bluebuzz

Generated, routed

A small Bluetooth vibrator controller: RP2350A + Raspberry Pi Radio Module 2 (Wi-Fi, Bluetooth Classic + LE), USB-C charging with power path, two PWM motor channels, a tactile array of four DPS368 barometers on the back (arranged in a symmetric 4-point diamond, cast in elastomer), an MP34DT05TR-A digital PDM microphone on the front, and an IMU. 26 × 56.84 mm (squish_pcb.dxf with r = 10 mm lower tip offset inward by 2.0 mm; 64 front / 45 back footprints), 6-layer; USB-C on the bottom tip is the only connector, every other lead an SMT pad row on the back. (The earlier nRF52840 board is further down.)

Where it stands

The whole design is generated from scripts/circuit.py and design.yaml by the bike-tracker's pipeline (python3 build.py): schematic drawn and verified against the netlist, board placed from a table inside the 2.0 mm inward-offset r = 10 mm squish outline (26 × 56.84 mm; RM2 centered at the top dome, MP34DT05TR-A PDM microphone on the front upper-right shoulder, four DPS368 tactile sensors in a diamond pattern on the back alongside the 3.3 V LDO, sensor load switch, IMU, and dual motor drivers), routed by freerouting around a set of hand-laid pre-routes with scripted planes, keepouts and stitching, closed by the grid router, DRC'd, audited and exported for JLCPCB. See README.md for the pipeline and the decisions, and out/ for the latest renders, copper layers and the 3D view. Every component choice, with datasheet and schematic excerpts: docs/components/.

front 3D render
front (3D): 26 × 56.84 mm (−2 mm offset squish outline), RM2 at top dome, PDM mic on right shoulder
back 3D render
back (3D): 4-sensor diamond tactile array, LDO, IMU, motor drivers & pads
front 2D layout
front (2D layout): component placement (64 footprints)
back 2D layout
back (2D layout, mirrored): 45 footprints & silkscreen
squish_pcb.dxf outline superimposed on board
design/squish_pcb.dxf with a 2.0 mm inward offset (26.0 × 56.84 mm, solid emerald) compared against the un-offset r = 10 mm (30.0 × 60.84 mm) and parametric lower-tip tangent variants (r = 5, 6, 7, 10, 12, 14 mm)

Board viewer — schematic, copper, 3D

Built by pcbview from out/bluebuzz-rm2.kicad_pcb and out/bluebuzz-rm2.kicad_sch as they stand (cd rm2 && python3 build.py --only site). Full-window viewer · the nRF board's viewer.

The dot puts a layer on top at full opacity; the box says whether it is drawn at all.

1.0×

Keys: 1–9 pick a layer, s solo, a all, m mirror, 0 fit. Click a part for its pane; coordinates are pcbnew’s, in millimetres.

One generated sheet, drawn block by block by scripts/gen_schematic.py and verified against scripts/circuit.py net for net.

F = every part and its escapes (the QSPI lines to the flash are hand-laid), In1 = solid ground, In2 = signals (the QSPI lanes, PG_N down the left side), In3 = the VSYS pour, In4 = solid ground, B = the pad rows and the wiring between the front parts. The empty strip across the top is the RM2's RF keep-out.

Every part wears its LCSC model except the RM2, which has no public model and shows as its pads. Click a part for its LCSC number and pin nets.

The earlier board: nRF52840 module, JST connectors (top level)

The first revision used an EBYTE E73-2G4M08S1C (nRF52840) with its ceramic antenna at the bottom edge, JST connectors for the battery, motors, load cell and pressure sensor and Tag-Connect SWD pads: 34 × 44 mm, 4 layers, parts on both sides. It is routed, DRC-clean and exported (out/jlcpcb/). Built from the top-level scripts/ (python3 build.py).

Board viewer (schematic / copper / 3D) · renders and layers · README.md

nRF board front render
nRF board, front
nRF board back render
nRF board, back

What is on it

MCU + radioRP2350A (QFN-60) with W25Q32 QSPI flash, 12 MHz crystal, 3.3 µH core inductor; Raspberry Pi RM2 (CYW43439) on gSPI, antenna end at the top edge, the top 5 mm of the board copper-free on every layer
PowerUSB-C on the bottom edge (the only connector) → USBLC6 ESD → BQ24074 (500 mA charge, 1 A input, power path) → VSYS (an inner-layer pour) → TLV75533 3.3 V. TPS22918 switches the sensor rail. Cell on two pads (BAT).
MotorsTwo channels: AO3400A low-side FET from VSYS, B5819W flyback, 22 µF bulk each, gate resistor and pull-down at the gate. PWM on GPIO0/1. Three pads (MOT): VSYS M1 M2. 1 A per channel.
TouchFour Infineon DPS368 barometers on the back in a 2 × 2 grid (6 × 8 mm), to be cast in soft elastomer after Tenzer, Jentoft & Howe 2014 (vacuum-degassed so the rubber fills the ports; a load on the surface reads as pressure). SPI1 on GPIO10-12 with one chip select each (GPIO13-16), on the switched rail, 100n at every sensor.
MotionST LSM6DS3TR-C 6-axis IMU on I2C1 (GPIO6/7, 4.7k pull-ups), INT1/INT2 on GPIO17/18, on the always-on rail for wake-on-motion.
UI / debugSide button, status LED, charge LED, 1M/1M battery divider into ADC0, five pogo pads (SWD) on the back under the radio: SWDIO SWCLK RUN BOOT GND. Firmware: pico-sdk, BTstack A2DP sink, TinyUSB audio.

Working

  • Project registered on port 8048
  • rm2 circuit (95 parts, 65 nets) with every part's LCSC number checked against JLCPCB's parts search; schematic verified against the netlist
  • rm2 placed: every part on the front beside the pin it serves except the sensor array on the back, no courtyard overlaps, nothing in the RF keep-out
  • rm2 routing: freerouting plus hand-laid pre-routes for the nets it never closed (QSPI, VBAT, PG_N, PWM, USB, LX, WL_CS); last runs ended within a few open nets
  • nRF board: routed (516 track segments, 212 vias), 0 DRC errors, 0 unconnected, audit clean; gerbers, BOM and pick-and-place in out/jlcpcb/

Next up

  • Check the antenna keepout against EBYTE's own E73 keep-out drawing (not retrievable 2026-10-17)
  • Pick the motors and cell; confirm 1 A per channel and the 500 mA charge rate suit them
  • Decide the pressure sensor (analog ratiometric or I2C) and confirm the pinout of its cable
  • Firmware: tristate HX_SCK before gating the sensor rail; UICR as needed

Open questions

  • JST SH 5-way stock at LCSC was 99 pieces; swap to a 4-way (drop I2C) if it stays scarce?
  • Smaller still? The right edge is full of connectors (battery, 4-way motor, pressure, load cell fill 39 of 44 mm) and the width is module + IC column + connector depth; a top-entry JST PH for the motors would buy ~4 mm of height.

Blocked on

  • Nothing.

Log

rm2 variant: RP2350A + RM2, USB-C the only connector, pad rows for every other lead. Passives re-placed by the pin each serves, then everything moved to the front; the page's viewer now shows this board. Later the same day: load cell and pressure port dropped for a 2 × 2 DPS368 tactile array on the back, an LSM6DS3TR-C IMU added, USB-C moved to the bottom edge, all trace bends at 45°.
Pipeline copied from bike-tracker; circuit, parts, schematic, placement (34 × 44, double-sided), routing scripts and audit written for this board. Second motor channel added on a shared 4-way lead.
Project created and registered with the hub. Status page scaffolded.