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>
4.5 KiB
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 (~$40–80)
| 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 | 10–50 |
| 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 | 30–40 |
| 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
- Flash CircuitPython (9.x+) onto the Pico 2.
circup install adafruit_wm8960(or copyadafruit_wm8960/intoCIRCUITPY/lib).- Copy
pico-wm8960/code.pytoCIRCUITPY/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 M1–M4 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.