metronome/hardware/PROTOTYPE.md
Me Here 33dc5ff5cb PM_K-1 Phase 1: bench prototype firmware + doc (Pico 2 + WM8960, transformer-isolated XLR)
Per the approved audio re-architecture (prototype-first): prove the click -> codec ->
transformer-isolated XLR chain on bought boards before any custom PCB, keeping the RP2350
firmware.

- pico-wm8960/code.py: CircuitPython bring-up for Pico 2 + SparkFun WM8960 breakout.
  Synthesizes the click (familiar piezo pitches) -> I2S -> WM8960 -> HP/speaker; line-in
  monitor hook; stereo/pan ready for polymeter spatialization. Uses the proven adafruit_wm8960
  driver (no hand-rolled register driver).
- hardware/PROTOTYPE.md: shopping list, wiring, and bench milestones M1-M5 (M4 = the no-buzz
  ground-loop test = acceptance gate).

Key findings baked in:
- Buzz was a ground loop; cure = transformer galvanic isolation, NOT +/-15 V (which was only
  studio headroom and is dropped).
- WM8960 needs MCLK (CircuitPython I2SOut doesn't emit it); the SparkFun breakout's onboard
  24 MHz oscillator supplies it -> resolves Risk R1 with zero extra parts.

Track-format conformance (node tests/run.mjs) stays green; DSL untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 09:15:26 -05:00

4.5 KiB
Raw Permalink Blame History

PM_K-1 — Phase-1 Bench Prototype

Prove the click → codec → transformer-isolated XLR chain (and the all-important no-buzz test) on bought boards before committing any custom PCB. Keeps the RP2350 firmware. This is Phase 1 of the approved plan (deep-honking-lemon). Firmware lives in pico-wm8960/code.py.

Why this shape (recap)

  • The brain (MCU + codec + Bluetooth) is a commodity → buy it.
  • The only genuinely-custom hardware is the Pro Out stage (line driver → output transformer → XLR) + the face → build only that, later.
  • The past "buzz" was a ground loop; the cure is galvanic isolation (a transformer), not ±15 V. ±15 V was only studio headroom and is gone.

Shopping list (~$4080)

Item Why ~$
Raspberry Pi Pico 2 (RP2350) Keeps the existing RP2350 firmware/toolchain 5
SparkFun WM8960 Audio Codec Breakout Stereo codec + HP amp + 1 W class-D speaker; has an onboard 24 MHz oscillator → supplies the WM8960 MCLK (resolves Risk R1), and the adafruit_wm8960 driver is tested against exactly this board 15
Output transformer The buzz-killer: galvanic isolation + balancing. Bench-start with a budget 1:1 600:600 Ω line transformer (Triad/Würth/Bourns); evaluate Jensen JT-11 / Lundahl for the keeper. Pick for full-level low-frequency handling — a punchy click is transient-rich and small cores saturate/dull the thump 1050
Male XLR chassis connector (Neutrik) + optional ¼" TRS Stadium-standard, locking, unambiguous output 5
Audio op-amp (OPA1612 etc.) + breadboard/protoboard, jumpers Low-rail line driver into the transformer primary 5
(later) Microchip BM83 dev board Bluetooth leg (A2DP sink+source) for M5 3040
Measurement: USB audio interface + REW (free), or a phone analyzer app Check output level + LF response (M3)

Wiring

Pico 2 ↔ WM8960 breakout (digital): match pico-wm8960/code.py.

Pico 2 WM8960 Note
GP0 BCLK bit clock
GP1 DACLRC (+ tie ADCLRC) word/LR clock — must be GP(bit_clock)+1
GP2 DACDAT Pico transmits the click
GP4 SDA Qwiic I²C
GP5 SCL Qwiic I²C
3V3 / GND 3V3 / GND power the breakout

Analog out (Pro Out, breadboard): WM8960 line/HP out → op-amp line driver (low rail) → transformer primary; transformer secondary → XLR pin 2 (hot) / pin 3 (cold) / pin 1 (shield, tied to chassis). Optionally also a ¼" TRS off the same secondary (tip/ring/sleeve). The transformer's secondary floats — that floating, isolated output is what cannot form a ground loop.

Firmware

  1. Flash CircuitPython (9.x+) onto the Pico 2.
  2. circup install adafruit_wm8960 (or copy adafruit_wm8960/ into CIRCUITPY/lib).
  3. Copy pico-wm8960/code.py to CIRCUITPY/code.py. It boots a steady 120 BPM click for M1.

Bench validation milestones

  • M1 — click out: the synthesized click plays cleanly via the WM8960 on headphones / speaker.
  • M2 — mix: your guitar on the line input is heard with the click (enable the codec's analog input→output bypass for ~0 ms monitor latency — see the M2 hook in code.py).
  • M3 — pro output: the transformer-isolated XLR drives a real console/interface at usable level, and the click keeps its punch — measure the low-frequency response through the transformer (this is where a too-small transformer shows up as a thin, gutless click).
  • M4 — the acid test (NO BUZZ): power the rig from a mains USB charger and connect the XLR to a mains-powered console/interface. Confirm no hum. A/B against a non-isolated output (tap before the transformer) to prove the transformer is what kills the loop. This is the acceptance gate for the whole approach.
  • M5 (later): add the BM83 — phone audio in (A2DP sink) mixes with the click; click out to a Bluetooth speaker (A2DP source).

Then → Phase 2 (only if M1M4 pass)

Design the Pro Out module PCB (op-amp → transformer → XLR) and optionally a custom RP2350 + WM8960 brain, using the existing SKiDL designs as reference. Not before the bench proves it.

Open risks to watch

  • Transformer LF/level (M3) — the "rock the house" punch lives or dies here.
  • WM8960 MCLK — relying on the SparkFun breakout's onboard 24 MHz osc; a bare WM8960 needs you to supply MCLK.
  • CircuitPython I²S/mixer throughput on the Pico 2 — if it can't keep up at 44.1 k, fall back to the C/Rust path.