Seedbox v0.1 + firmware, generic kit/synth, ROOT/SCALE pages
Some checks failed
check / check (push) Has been cancelled

First commit of the repo. Contents beyond the v0.1 simulator and layout:

- Full Pico 2 W firmware (firmware/app, drivers, engine port, host test).
- BANK page and 404 mode A/B removed; learned pads play exactly what was learned.
- 404/MiniFreak renamed to KIT/SYNTH throughout (jacks, code, sim, docs,
  layout labels; wiring rebuilt).
- ROLL returns to page select after a re-roll; a freshly learned track turns on.
- LCD contrast 66.
- ROOT and SCALE pages: 21 scales, AUTO = the seed picks; global and sticky.

Intended music change: the scale table grew from 8 to 21 and AUTO picks from
all of them, so every seed's scale changed. Vectors regenerated with
npm run vectors, plus new key-override cases. Flash record is now version 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 20:39:36 +03:00
commit 2196633ed5
77 changed files with 52207 additions and 0 deletions

137
docs/concept.md Normal file
View File

@@ -0,0 +1,137 @@
# Concept
Seedbox grows a whole tune from one 32-bit number. The seed decides the groove, the key, the chords, the melody and the form. Two knobs push it around while it plays, and eleven buttons decide which parts you hear. It is a performance instrument: there is no step editing.
## Tracks, not lanes
Following Eric Lyon's reading of Aphex Twin ("Techno Counterpoint"), a tune is a set of looped tracks that the player brings in and out. Every track is rendered every bar; the buttons only decide what reaches MIDI. Muting never changes the pattern underneath, so a track comes back exactly where it would have been.
| # | Track | Goes to | What it is |
|---|---|---|---|
| 0 | KICK | kit | main kicks (accented, and the one) |
| 1 | KICK 2 | kit | the other kicks |
| 2 | SNARE | kit | backbeats and loud snares (vel ≥ 90) |
| 3 | GHOST | kit | quiet snares |
| 4 | HAT | kit | hat accents (vel ≥ 85) |
| 5 | HAT 16 | kit | the rest of the hats |
| 6 | PERC | kit | percussion, shares the melody's phase offset |
| 7 | BASS | synth | root and chord degrees, follows the kick |
| 8 | MEL A | synth | the motif, first half of a hocket split |
| 9 | MEL B | synth | the other half of the hocket |
| 10 | PAD | synth | a chord held for the bar |
The synth runs in poly mode on one channel, so bass, melody and pad share one voice pool.
## The genome
`genome(seed)` picks, once per seed:
- **steps**: 16 most of the time, sometimes 12, 14 or 20 (bar length = steps × 16th)
- **form**: AAAB, AABA, ABAB, AAAA, ABAC or ABAA over a 4-bar phrase
- **scale and root**: any of the 21 scales below, any root. The ROOT and SCALE pages override them; AUTO keeps the seed's pick.
- **progression**: one chord root per bar of the phrase (e.g. i–vi–iv–v)
- **frame**: where the main kick and snare live (below)
- **swing**: none, light, medium, heavy or triplet feel
- **arc**: flat, build (bars 1–2 thin out) or break (bar 3 strips back)
- **accent cycle**: off, or an accent every 3, 5 or 7 sixteenths running across the bar line
- **motif length** (3–5 notes), **hocket mask**, **bass degree**, **melody phase offset**, **layback** (snares sit a little late), densities, fill odds
### Frames
All four kit generators share the frame, so a seed has a recognisable skeleton whichever generator plays it.
| Frame | Kick | Snare |
|---|---|---|
| backbeat | 1 | 2 and 4 |
| half-time | 1 | 3 |
| four-floor | every beat (layered) | 2 and 4 |
| 3-3-2 | 1, 1a, 3, 3a | between |
| broken | 1 and 3+ | 2+ and 4 |
| displaced | off the one | 3 |
| over the bar | every 12 sixteenths, across bar lines | halfway between |
| free snare | 1 | a Euclidean snare instead |
## Scales
Bass, melody and pad follow the scale. Chords stack every other scale note, so the scale's size changes the harmony: 5 notes give open chords, whole tone gives augmented, octatonic gives diminished.
| # | Name | Steps |
|---|---|---|
| 0 | MAJOR | 0 2 4 5 7 9 11 |
| 1 | MINOR | 0 2 3 5 7 8 10 |
| 2 | DORIAN | 0 2 3 5 7 9 10 |
| 3 | MIXOLYDIAN | 0 2 4 5 7 9 10 |
| 4 | LYDIAN | 0 2 4 6 7 9 11 |
| 5 | PHRYGIAN | 0 1 3 5 7 8 10 |
| 6 | HARM MINOR | 0 2 3 5 7 8 11 |
| 7 | MINOR PENT | 0 3 5 7 10 |
| 8 | MAJOR PENT | 0 2 4 7 9 |
| 9 | PHRYG DOM | 0 1 4 5 7 8 10 |
| 10 | DBL HARM | 0 1 4 5 7 8 11 |
| 11 | HUNG MINOR | 0 2 3 6 7 8 11 |
| 12 | UKR DORIAN | 0 2 3 6 7 9 10 |
| 13 | LYD DOM | 0 2 4 6 7 9 10 |
| 14 | HIRAJOSHI | 0 2 3 7 8 |
| 15 | IN SEN | 0 1 5 7 10 |
| 16 | IWATO | 0 1 5 6 10 |
| 17 | PROMETHEUS | 0 2 4 6 9 10 |
| 18 | WHOLE TONE | 0 2 4 6 8 10 |
| 19 | OCTATONIC | 0 1 3 4 6 7 9 10 |
| 20 | LOCRIAN | 0 1 3 5 6 8 10 |
## Generators
Selected on the GEN page. They only change the kit; the synth tracks are the same for all of them.
- **EUCLID**: Euclidean rhythms. Kick E(k,n) with a rotation that keeps the one, hats and perc often on their own cycle length (polymeter).
- **SKELETON**: the frame, plus a few kick moves and hat patterns. The most "drummer-like".
- **SUBDIV**: recursive subdivision of each beat. Clusters and rolls, calmer than it used to be.
- **AUTOMATA**: a 1-D cellular automaton decides the hits inside the frame.
- **AMENIZER**: the four bars of the Amen break, velocities included, with its own humanising and chopping (below).
## Sections
The form says which bars are A, B or C. B and C are transformations of A rather than new patterns, so the phrase hangs together. The transforms: kick answer, hat doubling, thin the first half, perc shift, ghost pickups, snare drag, drop the one, half-time switch.
## ENERGY
Pattern density. Kicks, snares, ghosts, perc and the melody thicken with it. Hats move only a quarter as much, so energy doesn't just mean "busier hats".
## DRIFT
One knob, several layers that fade in at different points. At 0 the loop is locked.
| Range | What comes in |
|---|---|
| 0–42 | phrase variations, from never to every phrase |
| 20–127 | microtiming: hats drag, snares rush, kick and bass move together |
| 40–127 | swing wobbles from bar to bar |
| 55–127 | accents slip, velocities loosen |
| 80–127 | whole parts slide a 16th early or late for a bar |
| 105–127 | now and then a beat is squeezed onto a triplet grid |
## AMENIZER
- The Amen break as a 4-bar table of step, drum, velocity and main/secondary.
- **Humanised**: each hit moves ±6 in velocity. A hit that quickly follows the same drum plays at 80%. The ride level drifts per bar.
- **Feel**: kicks ±4 ticks, main snares 10 ticks late (±5), ghosts ±10, ride 4 ticks early (±6).
- **Drift chops it per beat**, like a jungle edit. A beat can be swapped for:
- the same beat from another bar
- any beat
- a repeat
- a half-beat stutter
- a ratchet
- The chop chance rises with DRIFT. Beat 1 stays intact below DRIFT 88.
- The generic drift layers come in later and softer.
- Swing, transforms, arc and accent shaping are off.
- Bar 4 of the break is its own fill.
## Fills
There's no FILL button. Bar 4 of a phrase fills on its own now and then (roll, stutter or drop-out with pickup); how often depends on the seed. The engine still takes a fill flag, so a manual fill can come back later without touching the music.
## Determinism
The engine uses integers only, a seeded xorshift32 and a hash, so a given seed, generator, ENERGY, DRIFT and bar always give the same events. That is what lets the Pico firmware be tested against the simulator: see [the firmware plan](../firmware/README.md) and `test/`.
Timing is 840 ticks per quarter note (210 per 16th; 840 divides by 2, 3, 4, 5 and 7 for tuplets). MIDI clock goes out every 35 ticks (24 PPQN).

63
docs/controls.md Normal file
View File

@@ -0,0 +1,63 @@
# Controls
```
┌──────────────────────────────────────────────────────────────┐
│ [ 5110 screen ] (ENERGY) [KICK][KICK2][SNR] RUN/STOP
│ (DRIFT) [HAT ][HAT16][PRC][GHST]
│ (ENC) [ SEED ] [BASS][MEL A][MLB][PAD ]
└──────────────────────────────────────────────────────────────┘
back wall: USB · MIDI IN · OUT KIT · OUT SYNTH
```
To-scale layout and drill list: [hardware/panel.md](hardware/panel.md).
## Buttons and knobs
| Control | Does |
|---|---|
| **SEED** | A new random seed. The old one goes into the history (last 16). |
| **RUN** toggle | Start / stop. Stop sends note-offs, All Sound Off (CC 120) on the learned kit channels, and CC 120 and 123 on the synth channel. |
| **ENERGY** | Density. See [concept](concept.md#energy). |
| **DRIFT** | How loose and changeable. See [concept](concept.md#drift). |
| **Track button**, tap | Track on / off. |
| **Track button**, hold (> 250 ms) | Flips the track only while held: a quick drop-out or punch-in. |
| **Encoder**, turn | Choose the page. |
| **Encoder**, push | Edit the page (the value line inverts). Turn to change, push again to leave. |
Option (bench setting in the simulator): track changes wait for the next bar line.
## Screen
The Nokia 5110 has 84 × 48 pixels:
- **Top line**: the page name.
- **Second line**: its value, inverted while you edit it.
- **Below**: a 4 × 3 map that mirrors the buttons. The top-right cell is RUN: filled while playing.
- filled = on
- outline = off
- flash = hit
- dot = a kit track not learned yet
- blinking = a change waiting for the bar line
## Pages
| Page | Edit with the encoder | Push |
|---|---|---|
| **SEED** | scroll back through the last 16 seeds (`-1`, `-2` …; `*` = re-rolled) | load the shown seed |
| **GEN** | EUCLID, SKELETON, SUBDIV, AUTOMATA, AMENIZER | done |
| **ROOT** | AUTO, C … B. AUTO shows the seed's pick | done |
| **SCALE** | AUTO, then the 21 scales (see [Concept](concept.md#scales)). AUTO shows the seed's pick | done |
| **BPM** | tempo | done |
| **SLOT** | 8 slots for seed + salts + generator (not root or scale) | push = load, long push = save |
| **ROLL** | KIT or LINE | push re-rolls just that half (a new drum part over the same tune, or the other way round), then goes back to page select |
| **LEARN** | — | push, press a kit track button, hit the pad on the sampler or drum machine. Push again to cancel. |
## Simulator keys
| Key | Does |
|---|---|
| 1 … 0, - | track buttons KICK … PAD |
| Space | SEED |
| ← → | encoder turn |
| Enter / Shift+Enter | encoder push / long push |
| R | run / stop |

47
docs/decisions.md Normal file
View File

@@ -0,0 +1,47 @@
# Design decisions
Short record of why things are the way they are, so they don't get undone by accident.
## Music
- **Tracks are only on or off.**
- There's no auto mode. Bringing parts in and out is the performance (Lyon, "Techno Counterpoint").
- Every track is rendered every bar, so muting doesn't change the pattern.
- **No break lane.** Chopping breaks is the M8's job. Seedbox makes rhythm and melody. AMENIZER is a generator that plays a break pattern on the kit, not a sample player.
- **Energy moves hats only a quarter as much as the rest.** Before that, energy mostly meant busier hats.
- **Rhythmic frames per seed.** Before frames, most seeds put the kick on 1 and the snare on 3.
- **Sections are transforms of A**, not new patterns. The phrase hangs together.
- **Drift is continuous overlapping layers**, not steps. Wide knob spans used to do little. Drift adds displacement and weirdness at the top end.
- **AMENIZER keeps its own feel.** Its humanising and chops are tuned so that DRIFT past halfway isn't too extreme. The generic layers come in later and at half strength.
- **ROOT and SCALE are global and sticky (2026-10-11).** They survive SEED, ROLL and slot loads, so a seed can be fitted to an existing idea. AUTO lets the seed pick from all 21 scales, which changed every seed's sound (vectors regenerated). Slots don't store the key.
- **Integer-only engine** with a seeded RNG. This makes it deterministic and portable, and testable by golden vectors.
## MIDI
- **Kit pads are learned, not configured.** The bank/pad/mode tables were dropped. BANK was dropped too (2026-10-11): it only made sense for the SP-404MKII's bank layout, and the kit side should work with any sampler or drum machine. Re-learn to change kit.
- **STOP sends CC 120 on the kit channels** because some samplers (the SP-404MKII) ignore All Notes Off. SPP isn't sent.
- **The synth is in poly mode on one channel.** Bass, melody and pad share it.
- **MIDI OUT follows the 3.3 V spec (CA-033)**: 10 Ω on TX, 33 Ω on 3.3 V. An earlier draft had them swapped; the independent review caught it.
- **Generic kit and synth (2026-10-11).** Jacks, screens and docs say KIT and SYNTH, not 404 and MiniFreak. Those two are the test rig, nothing more.
## Hardware
- **6N137 for MIDI IN**, because that's the part on hand. It's pin-compatible with the 6N138 here except pin 7, which is the enable input and must be high: a link ties it to pin 8, and the 4.7 kΩ pin 7 resistor is gone. C1 (supply bypass) is required and sits right beside the chip. Never fit a 6N138 with that link in place: on a 6N138, pin 7 is the transistor base.
- **3.5 mm TRS MIDI jacks (Type A)** instead of 5-pin DIN: the DIN jacks didn't fit the box. Type A TRS gear takes a plain stereo cable; DIN gear gets a Type A adapter.
- **The Pico's USB end is at the stripboard edge** (its first pin row is strip A), so the box is powered and flashed through a slot in the back wall, with no extension cable.
- **11 momentary track buttons in a diode matrix**, with the state shown on the LCD map. Latching or lit buttons weren't available locally, and LEDs would need more pins.
- **No FILL button.** Dropped after trying the panel; fills still happen on their own in bar 4. The RUN toggle took the free corner of the grid (row 1 / column 4, outside the matrix), and GHOST moved into FILL's matrix slot (row 2 / column 4).
- **Nokia 5110** instead of a 0.91" OLED, which was too small to read.
- **Landscape panel** in an enclosure of about 80 × 150 mm.
- **One stripboard** in a plastic box, Pico socketed, everything else panel mounted. No standoffs, screws or USB extension.
- **GP0/GP4 links run under the Pico between its headers.** That keeps them from crossing header pins; it's the reason for the col-13 cut length.
- **Pad names P1–P35**, not W…, to avoid clashing with strip W.
## Process
- **The stripboard was reviewed by blind agents** with no access to the design reasoning, as well as by `check-layout.js`.
- First review (30-row DIN board): 6 issues, all fixed, then clean.
- Second review (USB at the edge, TRS jacks): no electrical faults, 12 doc and mechanical findings, all fixed. The biggest was a link note that named the ground strip instead of strip Y. The rest: USB slot height, SEED above R4, and the panel tool defaulting to portrait.
- R4 now lies flat along strip X across a cut at X23, so a normal ¼ W part fits under SEED.
- The re-check came back clean.
- **The firmware port happens in Claude Code** (this repo), against the golden vectors.

39
docs/hardware/README.md Normal file
View File

@@ -0,0 +1,39 @@
# Hardware
| File | What |
|---|---|
| [bom.csv](bom.csv) | parts list with status (have / check / buy / optional); interactive version: `tools/bom.html` |
| [pinout.md](pinout.md) | every Pico pin used, and why |
| [wiring.md](wiring.md) | stripboard, cuts, links, off-board wires, panel wiring, build order |
| [panel.md](panel.md) | panel layout and drill list |
| [board-parts.csv](board-parts.csv), [wire-list.csv](wire-list.csv), [drill-list.csv](drill-list.csv), [cuts.txt](cuts.txt) | the tables, exported from the tools |
| [svg/](svg/) | the drawings, exported from the tools |
The source of truth for the stripboard is [`hardware/layout.js`](../../hardware/layout.js). Everything in this folder that describes the board is generated from it. After changing it:
```sh
node hardware/check-layout.js # geometry, footprints, circuit rules
node tools/build-wiring.js # rebuilds tools/wiring.html
```
To refresh the SVGs and CSVs, open `tools/wiring.html` and `tools/panel.html` in a browser and save from there (or script it with jsdom, as the first export did).
## Build constraints this design assumes
- One stripboard carries the Pico (socketed in two female headers) and the MIDI circuits.
- Everything else is panel mounted and wired with hookup wire, in 5 colours.
- No standoffs, screws or USB extension. The board is held with foam tape or hot glue, and its USB port lines up with a slot in the box wall.
- The Nokia 5110 module sits on top of the box. Its wires go through a hole under the header.
- The enclosure is plastic, about 80 × 150 × 40 mm, laid out landscape.
- The MIDI jacks are 3.5 mm TRS, Type A.
- The Pico's USB end sits at the board edge. Its USB port powers the box and flashes the firmware through a slot in the back wall.
## Verified, and not
- **Checked**:
- `check-layout.js` covers the netlist against the pin map and the MIDI 3.3 V circuit, plus shorts, cuts and footprints.
- Two blind reviews by agents with no access to the design reasoning. Every finding was fixed; see [decisions](../decisions.md#process).
- **Not checkable from here**:
- Lug order on your TRS jacks: find tip, ring and sleeve with the meter and a plug inserted.
- RP2350 pin functions: confirm against the Pico 2 W datasheet when writing the firmware.
- Nokia BL polarity: the wiring doc says how to test it.

View File

@@ -0,0 +1,20 @@
part,value,holes,note
"Pico 2W","2 × 20-pin female header","A13–T13 and A20–T20 (pins 1–20 down the left, 40–21 down the right)","USB end flush with the top edge of the board, past strip A"
"U1","6N137","U5–X5, U8–X8","6N137 in a DIP-8 socket. Notch toward strip U, pin 1 at hole U5. Pin 7 (enable) is tied to pin 8 by the U10–V10 link."
"R1","220 Ω","V2 – Y2","MIDI IN current limit. 3-hole span: stand it upright, or use a small ⅛ W part flat. If learning ever misses notes, use 150 Ω."
"D1","1N4148","V4 – W4","Band (cathode) on V4, the opto LED anode side. Stands upright (1-hole span)."
"R2","1 kΩ","W10 – AB10","Opto output pull-up to 3.3 V"
"C1","100 nF","U11 – X11","6N137 supply bypass, right beside the chip: U11 is its 5 V (pin 8) strip, X11 its GND (pin 5) strip. Required. Fit it after the beep test."
"R4","10 Ω","X21 – X25","MIDI OUT KIT, TX line (RC). Lies flat along strip X, across the cut at X23 (4-hole span, ¼ W fits). SEED hangs right above it."
"R5","33 Ω ½ W","V19 – AB19","MIDI OUT KIT, 3.3 V line (RA). ½ W: a mono plug in the jack shorts it to ground."
"R6","10 Ω","U28 – Y28","MIDI OUT SYNTH, TX line (RC)"
"R7","33 Ω ½ W","V30 – AB30","MIDI OUT SYNTH, 3.3 V line (RA). ½ W, same reason as R5."
"Link","wire","A34 – Z34","5 V (VBUS) to the 5 V strip"
"Link","wire","E32 – AB32","3V3 to the 3V3 strip"
"Link","wire","R33 – AA33","GND to the GND strip"
"Link","wire","U13 – Z13","opto VCC to 5 V"
"Link","wire","U10 – V10","opto enable (pin 7) to VCC (pin 8): the 6N137 output only works with pin 7 high"
"Link","wire","X12 – AA12","opto GND to GND"
"Link","wire","W9 – B9","opto out to GP1 (MIDI RX), strip B"
"Link","wire","A15 – X15","GP0 (TX KIT) to strip X (R4), straight down under the Pico between its headers"
"Link","wire","F14 – Y14","GP4 (TX SYNTH) to strip Y (R6), straight down under the Pico between its headers"
1 part value holes note
2 Pico 2W 2 × 20-pin female header A13–T13 and A20–T20 (pins 1–20 down the left, 40–21 down the right) USB end flush with the top edge of the board, past strip A
3 U1 6N137 U5–X5, U8–X8 6N137 in a DIP-8 socket. Notch toward strip U, pin 1 at hole U5. Pin 7 (enable) is tied to pin 8 by the U10–V10 link.
4 R1 220 Ω V2 – Y2 MIDI IN current limit. 3-hole span: stand it upright, or use a small ⅛ W part flat. If learning ever misses notes, use 150 Ω.
5 D1 1N4148 V4 – W4 Band (cathode) on V4, the opto LED anode side. Stands upright (1-hole span).
6 R2 1 kΩ W10 – AB10 Opto output pull-up to 3.3 V
7 C1 100 nF U11 – X11 6N137 supply bypass, right beside the chip: U11 is its 5 V (pin 8) strip, X11 its GND (pin 5) strip. Required. Fit it after the beep test.
8 R4 10 Ω X21 – X25 MIDI OUT KIT, TX line (RC). Lies flat along strip X, across the cut at X23 (4-hole span, ¼ W fits). SEED hangs right above it.
9 R5 33 Ω ½ W V19 – AB19 MIDI OUT KIT, 3.3 V line (RA). ½ W: a mono plug in the jack shorts it to ground.
10 R6 10 Ω U28 – Y28 MIDI OUT SYNTH, TX line (RC)
11 R7 33 Ω ½ W V30 – AB30 MIDI OUT SYNTH, 3.3 V line (RA). ½ W, same reason as R5.
12 Link wire A34 – Z34 5 V (VBUS) to the 5 V strip
13 Link wire E32 – AB32 3V3 to the 3V3 strip
14 Link wire R33 – AA33 GND to the GND strip
15 Link wire U13 – Z13 opto VCC to 5 V
16 Link wire U10 – V10 opto enable (pin 7) to VCC (pin 8): the 6N137 output only works with pin 7 high
17 Link wire X12 – AA12 opto GND to GND
18 Link wire W9 – B9 opto out to GP1 (MIDI RX), strip B
19 Link wire A15 – X15 GP0 (TX KIT) to strip X (R4), straight down under the Pico between its headers
20 Link wire F14 – Y14 GP4 (TX SYNTH) to strip Y (R6), straight down under the Pico between its headers

26
docs/hardware/bom.csv Normal file
View File

@@ -0,0 +1,26 @@
group,id,part,spec,qty,status,notes
"Core","pico","Raspberry Pi Pico 2W","RP2350, micro-USB","1","have","The whole engine runs on it with lots of headroom."
"Core","lcd","Nokia 5110 LCD module","PCD8544, 84×48, SPI","1","have","The module you used with Arduino."
"Core","box","Enclosure","","1","have","About 80 × 150 × 40 mm. Panel layout: tools/panel.html."
"Controls","enc","Rotary encoder with push","KY-040 module or bare EC11","1","have","Power it from 3V3."
"Controls","pots","Potentiometer, linear","B10K (anything 5k–50k linear works)","2","have","Energy and Drift."
"Controls","knobs","Knobs","to fit the pot and encoder shafts","3","check","Shaft types differ (D, knurled, 6 mm). Match them."
"Controls","btn","Momentary push button, panel mount","~12 mm, non-latching","11","check","7 kit + 4 line tracks."
"Controls","seedbtn","Momentary push button, large","16–22 mm, non-latching","1","check","SEED. Any big momentary works."
"Controls","tog","Toggle switch, SPDT","","1","have","RUN / STOP. Your old bypass switch."
"Controls","dio","1N4148 diode","or 1N4448 / 1N914 / any small-signal diode","12","buy","11 for the button matrix + 1 for MIDI IN. 1N4448 works too. Every button needs one: a missing diode gives phantom presses with three buttons held."
"MIDI","trs","3.5 mm stereo (TRS) jack, panel mount","3 lugs: tip, ring, sleeve. Not mono.","3","check","IN, OUT KIT, OUT SYNTH. MIDI TRS Type A. 6 mm hole each."
"MIDI","adapt","TRS-to-DIN MIDI adapter, Type A","female DIN, 3.5 mm plug","1","buy","For a DIN synth or sampler (e.g. MiniFreak). Must say Type A (Type B swaps tip and ring). Type A TRS gear (e.g. SP-404MKII) takes a plain stereo 3.5 mm cable."
"MIDI","opto","6N137 optocoupler","DIP-8 (6N138 also works: then drop the pin 7 link)","1","have","MIDI IN. You have three; one is used."
"MIDI","sock","DIP-8 IC socket","","1","buy","So the opto can be swapped."
"MIDI","r330","Resistor 330 Ω","220–470 Ω","1","check","LCD backlight (LED pin) to 3.3 V, inline at the module."
"MIDI","r220","Resistor 220 Ω","150–220 Ω","1","have","MIDI IN, in series with the opto LED. The 6N137 wants a bit more LED current: use 150 Ω if learning misses notes."
"MIDI","r1k","Resistor 1 kΩ","470 Ω–2.2 kΩ is fine","2","have","Opto output pull-up, NPN base."
"MIDI","r33","Resistor 33 Ω, ½ W","27–47 Ω is fine","2","buy","MIDI OUT ring (pin 4) line, per the MIDI 3.3 V spec. ½ W because a mono plug in an OUT jack shorts it straight to ground (0.33 W); a ¼ W one would cook."
"MIDI","r10","Resistor 10 Ω","10–22 Ω is fine","2","check","MIDI OUT tip (pin 5) line, from TX. Don't replace with a wire: it protects the pin."
"MIDI","cap","Ceramic capacitor 100 nF","anything 47–220 nF","3","check","C1 on the board (6N137 supply bypass, required). Optional: one per pot, soldered at the pot from wiper to the left lug, if the readings jitter."
"Screen extras","blt","NPN or PNP transistor","2N3904 / BC547 (NPN) or 2N3906 / BC557 (PNP)","1","opt","Only for a dimmable backlight. NPN if your BL lights when grounded, PNP if it lights from 3.3 V. Otherwise hard-wire it."
"Power and assembly","perf","Stripboard","at least 34 × 28 holes (about 86 × 71 mm)","1","check","Pico socketed at the top edge, so its USB port meets a slot in the back wall."
"Power and assembly","hdr","Female header strip, 1 × 20","2.54 mm","2","check","Socket the Pico instead of soldering it in."
"Power and assembly","mhdr","Male header strip, 1 × 20","2.54 mm","2","check","Soldered to the Pico so it plugs into the female headers. Skip if yours is a Pico 2 WH (headers fitted)."
"Power and assembly","tape","Double-sided foam tape or hot glue","","—","check","Holds the stripboard and the screen without screws."
1 group id part spec qty status notes
2 Core pico Raspberry Pi Pico 2W RP2350, micro-USB 1 have The whole engine runs on it with lots of headroom.
3 Core lcd Nokia 5110 LCD module PCD8544, 84×48, SPI 1 have The module you used with Arduino.
4 Core box Enclosure 1 have About 80 × 150 × 40 mm. Panel layout: tools/panel.html.
5 Controls enc Rotary encoder with push KY-040 module or bare EC11 1 have Power it from 3V3.
6 Controls pots Potentiometer, linear B10K (anything 5k–50k linear works) 2 have Energy and Drift.
7 Controls knobs Knobs to fit the pot and encoder shafts 3 check Shaft types differ (D, knurled, 6 mm). Match them.
8 Controls btn Momentary push button, panel mount ~12 mm, non-latching 11 check 7 kit + 4 line tracks.
9 Controls seedbtn Momentary push button, large 16–22 mm, non-latching 1 check SEED. Any big momentary works.
10 Controls tog Toggle switch, SPDT 1 have RUN / STOP. Your old bypass switch.
11 Controls dio 1N4148 diode or 1N4448 / 1N914 / any small-signal diode 12 buy 11 for the button matrix + 1 for MIDI IN. 1N4448 works too. Every button needs one: a missing diode gives phantom presses with three buttons held.
12 MIDI trs 3.5 mm stereo (TRS) jack, panel mount 3 lugs: tip, ring, sleeve. Not mono. 3 check IN, OUT KIT, OUT SYNTH. MIDI TRS Type A. 6 mm hole each.
13 MIDI adapt TRS-to-DIN MIDI adapter, Type A female DIN, 3.5 mm plug 1 buy For a DIN synth or sampler (e.g. MiniFreak). Must say Type A (Type B swaps tip and ring). Type A TRS gear (e.g. SP-404MKII) takes a plain stereo 3.5 mm cable.
14 MIDI opto 6N137 optocoupler DIP-8 (6N138 also works: then drop the pin 7 link) 1 have MIDI IN. You have three; one is used.
15 MIDI sock DIP-8 IC socket 1 buy So the opto can be swapped.
16 MIDI r330 Resistor 330 Ω 220–470 Ω 1 check LCD backlight (LED pin) to 3.3 V, inline at the module.
17 MIDI r220 Resistor 220 Ω 150–220 Ω 1 have MIDI IN, in series with the opto LED. The 6N137 wants a bit more LED current: use 150 Ω if learning misses notes.
18 MIDI r1k Resistor 1 kΩ 470 Ω–2.2 kΩ is fine 2 have Opto output pull-up, NPN base.
19 MIDI r33 Resistor 33 Ω, ½ W 27–47 Ω is fine 2 buy MIDI OUT ring (pin 4) line, per the MIDI 3.3 V spec. ½ W because a mono plug in an OUT jack shorts it straight to ground (0.33 W); a ¼ W one would cook.
20 MIDI r10 Resistor 10 Ω 10–22 Ω is fine 2 check MIDI OUT tip (pin 5) line, from TX. Don't replace with a wire: it protects the pin.
21 MIDI cap Ceramic capacitor 100 nF anything 47–220 nF 3 check C1 on the board (6N137 supply bypass, required). Optional: one per pot, soldered at the pot from wiper to the left lug, if the readings jitter.
22 Screen extras blt NPN or PNP transistor 2N3904 / BC547 (NPN) or 2N3906 / BC557 (PNP) 1 opt Only for a dimmable backlight. NPN if your BL lights when grounded, PNP if it lights from 3.3 V. Otherwise hard-wire it.
23 Power and assembly perf Stripboard at least 34 × 28 holes (about 86 × 71 mm) 1 check Pico socketed at the top edge, so its USB port meets a slot in the back wall.
24 Power and assembly hdr Female header strip, 1 × 20 2.54 mm 2 check Socket the Pico instead of soldering it in.
25 Power and assembly mhdr Male header strip, 1 × 20 2.54 mm 2 check Soldered to the Pico so it plugs into the female headers. Skip if yours is a Pico 2 WH (headers fitted).
26 Power and assembly tape Double-sided foam tape or hot glue — check Holds the stripboard and the screen without screws.

5
docs/hardware/cuts.txt Normal file
View File

@@ -0,0 +1,5 @@
Hole 6 on strips U to Y (5 cuts)
Hole 14 on strips U to X (4 cuts)
Hole 16 on strips A to T (20 cuts)
Hole 23 on strip X (1 cut)
Hole 25 on strips U to W (3 cuts)

View File

@@ -0,0 +1,22 @@
where,part,x_mm,y_mm,hole
"Lid","Screen wire hole (under the header)","11","28","Ø 8"
"Lid","Encoder","15.5","61.5","Ø 7"
"Lid","KICK","83.5","20","Ø 12"
"Lid","KICK 2","101.2","20","Ø 12"
"Lid","SNARE","118.8","20","Ø 12"
"Lid","RUN toggle","136.5","20","Ø 6"
"Lid","HAT","83.5","40","Ø 12"
"Lid","HAT 16","101.2","40","Ø 12"
"Lid","PERC","118.8","40","Ø 12"
"Lid","GHOST","136.5","40","Ø 12"
"Lid","BASS","83.5","60","Ø 12"
"Lid","MEL A","101.2","60","Ø 12"
"Lid","MEL B","118.8","60","Ø 12"
"Lid","PAD","136.5","60","Ø 12"
"Lid","ENERGY pot","63","17.3","Ø 7"
"Lid","DRIFT pot","63","40","Ø 7"
"Lid","SEED","63","62.7","Ø 16"
"Back wall","Jack MIDI IN","105","20 down","Ø 6"
"Back wall","Jack OUT · KIT","121","20 down","Ø 6"
"Back wall","Jack OUT · SYNTH","137","20 down","Ø 6"
"Back wall","USB slot (Pico port)","44","16 up from inside floor","12 × 8 slot"
1 where part x_mm y_mm hole
2 Lid Screen wire hole (under the header) 11 28 Ø 8
3 Lid Encoder 15.5 61.5 Ø 7
4 Lid KICK 83.5 20 Ø 12
5 Lid KICK 2 101.2 20 Ø 12
6 Lid SNARE 118.8 20 Ø 12
7 Lid RUN toggle 136.5 20 Ø 6
8 Lid HAT 83.5 40 Ø 12
9 Lid HAT 16 101.2 40 Ø 12
10 Lid PERC 118.8 40 Ø 12
11 Lid GHOST 136.5 40 Ø 12
12 Lid BASS 83.5 60 Ø 12
13 Lid MEL A 101.2 60 Ø 12
14 Lid MEL B 118.8 60 Ø 12
15 Lid PAD 136.5 60 Ø 12
16 Lid ENERGY pot 63 17.3 Ø 7
17 Lid DRIFT pot 63 40 Ø 7
18 Lid SEED 63 62.7 Ø 16
19 Back wall Jack MIDI IN 105 20 down Ø 6
20 Back wall Jack OUT · KIT 121 20 down Ø 6
21 Back wall Jack OUT · SYNTH 137 20 down Ø 6
22 Back wall USB slot (Pico port) 44 16 up from inside floor 12 × 8 slot

46
docs/hardware/panel.md Normal file
View File

@@ -0,0 +1,46 @@
# Panel
Landscape layout for a plastic enclosure of about 80 × 150 × 40 mm. The interactive tool (`tools/panel.html`) takes your box size and hole diameters and redraws this, with a fit check.
![Panel layout, landscape](svg/panel-landscape.svg)
- **Left zone**: the screen (on top of the lid), with the encoder and RUN under it.
- **Middle zone**: ENERGY, DRIFT and SEED.
- **Right zone**: the 4 × 3 block, in the same order as the screen map: 11 track buttons, with the RUN toggle in the top-right corner. Check at test fit that the toggle's body clears the OUT SYNTH jack behind it on the back wall.
- **Back wall**: the USB slot for the Pico, and three 3.5 mm MIDI jacks (IN, OUT KIT, OUT SYNTH).
## Inside the box
- **Stripboard**: it lies on the floor with its top edge (strip A) against the back wall.
- **USB**: the Pico's micro-USB socket ends up about 41 mm from the board's left edge and about 16 mm above the *inside* floor. That stack is foam tape ~1, board 1.6, female header 8.5, the Pico's header spacer 2.5, Pico 1, half the socket ~1.4. Measure your own before cutting the slot.
- **Slot size**: cut it big enough for the plug's moulding (about 12 × 8 mm), not just the metal tip. The plug has to reach the socket through the wall's thickness.
- **Fit**: the board is 71 mm front to back, which fits the box's inside depth with a little to spare. Pot and button bodies hang down from the lid above it.
- **Under SEED**: R4 (lying flat) and pads P3/P4 sit right under SEED. Keep those two wires low and check how deep your SEED button reaches before closing the box.
## Drill list
Coordinates are from the lid's top-left corner, in mm, for the default sizes in the tool. Wall holes use x as drawn, which matches the lid view; heights are from the inside floor. Re-run the tool with your measured parts before drilling.
| Where | Part | x mm | y mm | Hole |
|---|---|---|---|---|
| Lid | Screen wire hole (under the header) | 11 | 28 | Ø 8 |
| Lid | Encoder | 15.5 | 61.5 | Ø 7 |
| Lid | KICK | 83.5 | 20 | Ø 12 |
| Lid | KICK 2 | 101.2 | 20 | Ø 12 |
| Lid | SNARE | 118.8 | 20 | Ø 12 |
| Lid | RUN toggle | 136.5 | 20 | Ø 6 |
| Lid | HAT | 83.5 | 40 | Ø 12 |
| Lid | HAT 16 | 101.2 | 40 | Ø 12 |
| Lid | PERC | 118.8 | 40 | Ø 12 |
| Lid | GHOST | 136.5 | 40 | Ø 12 |
| Lid | BASS | 83.5 | 60 | Ø 12 |
| Lid | MEL A | 101.2 | 60 | Ø 12 |
| Lid | MEL B | 118.8 | 60 | Ø 12 |
| Lid | PAD | 136.5 | 60 | Ø 12 |
| Lid | ENERGY pot | 63 | 17.3 | Ø 7 |
| Lid | DRIFT pot | 63 | 40 | Ø 7 |
| Lid | SEED | 63 | 62.7 | Ø 16 |
| Back wall | Jack MIDI IN | 105 | 20 down | Ø 6 |
| Back wall | Jack OUT · KIT | 121 | 20 down | Ø 6 |
| Back wall | Jack OUT · SYNTH | 137 | 20 down | Ø 6 |
| Back wall | USB slot (Pico port) | 44 | 16 up from inside floor | 12 × 8 slot |

44
docs/hardware/pinout.md Normal file
View File

@@ -0,0 +1,44 @@
# Pinout (Pico 2 W)
| Pico pin | GPIO | Function | Goes to | Notes |
|---|---|---|---|---|
| 1 | GP0 | UART0 TX | OUT KIT tip, via 10 Ω | drive strength 8–12 mA |
| 2 | GP1 | UART0 RX | 6N137 output (pin 6), 1 kΩ pull-up to 3.3 V | MIDI IN |
| 4 | GP2 | matrix row 1 | KICK, KICK 2, SNARE (col 4 empty) | input, pull-up |
| 5 | GP3 | matrix row 2 | HAT, HAT 16, PERC, GHOST | input, pull-up |
| 6 | GP4 | UART1 TX | OUT SYNTH tip, via 10 Ω | drive strength 8–12 mA |
| 7 | GP5 | matrix row 3 | BASS, MEL A, MEL B, PAD | input, pull-up |
| 9 | GP6 | matrix column 1 | KICK, HAT, BASS | driven low one at a time, else Hi-Z |
| 10 | GP7 | matrix column 2 | KICK 2, HAT 16, MEL A | 〃 |
| 11 | GP8 | matrix column 3 | SNARE, PERC, MEL B | 〃 |
| 12 | GP9 | matrix column 4 | GHOST, PAD | 〃 |
| 14 | GP10 | encoder A (SIA) | encoder | pull-up |
| 15 | GP11 | encoder B (SIB) | encoder | pull-up |
| 16 | GP12 | encoder push (SW) | encoder | pull-up |
| 17 | GP13 | SEED | button to ground | pull-up |
| 19 | GP14 | RUN | toggle to ground | pull-up |
| 22 | GP17 | SPI0 CSn | LCD SCE (pin 3) | can be tied to GND instead |
| 24 | GP18 | SPI0 SCK | LCD SCLK (pin 7) | |
| 25 | GP19 | SPI0 TX | LCD DN / MOSI (pin 6) | |
| 26 | GP20 | GPIO | LCD D/C (pin 5) | |
| 27 | GP21 | GPIO | LCD RST (pin 4) | |
| 31 | GP26 | ADC0 | ENERGY pot wiper | |
| 32 | GP27 | ADC1 | DRIFT pot wiper | |
| 33 | AGND | | pots, left lugs | |
| 36 | 3V3 | | 3V3 strip (AB): LCD, encoder, pots, MIDI OUT rings via 33 Ω, opto pull-up | |
| 40 | VBUS | | 5 V strip (Z): 6N137 VCC and enable only | powered from the Pico's USB |
| 23 | GND | | GND strip (AA) | all Pico GND pins are common |
Free: GP15, GP16, GP22, GP28 (ADC2), and GP17 if SCE is tied to ground. The LCD backlight runs straight from 3.3 V through 330 Ω; GP22 could dim it later through a transistor.
## Firmware notes for these pins
- **Pull-ups, not pull-downs.** RP2350 erratum E9 makes the internal pull-downs unreliable on inputs, so every input here is active-low with a pull-up.
- **Drive strength.** GP0 and GP4 drive the MIDI current loops directly, about 6–8 mA. That's above the RP2350's default 4 mA drive, so set them to 8 or 12 mA with `gpio_set_drive_strength()`.
- **Matrix.**
- Drive one column low at a time and leave the others Hi-Z, then read the three rows. On the idle columns, disable the input buffer (`gpio_set_input_enabled(pin, false)`) or enable the pull-up, so erratum E9 leakage can't hold them at a middle level.
- The diode bands point to the column.
- A short settle (a few µs) after switching columns helps.
- Debounce in software.
- **UART.** Both UARTs run at 31 250 baud, 8N1. MIDI IN is only used to learn pads, so it can be polled.
- **Nokia 5110.** It runs at 3.3 V on SPI up to 4 MHz.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="enc" viewBox="0 0 300 80" role="img" aria-label="Encoder module pins" xmlns="http://www.w3.org/2000/svg" style="background:#F6F7F9"><rect x="72" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="78" y1="26" x2="78" y2="52" stroke="#D7263D" stroke-width="4" stroke-linecap="round"></line><text x="78" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" fill="#18202A">VCC</text><text x="78" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">AB4</text><rect x="108" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="114" y1="26" x2="114" y2="52" stroke="#1E1E1E" stroke-width="4" stroke-linecap="round"></line><text x="114" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" fill="#18202A">GND</text><text x="114" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">AA4</text><rect x="144" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="150" y1="26" x2="150" y2="52" stroke="#2E9E5B" stroke-width="4" stroke-linecap="round"></line><text x="150" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" fill="#18202A">SW</text><text x="150" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">P2</text><rect x="180" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="186" y1="26" x2="186" y2="52" stroke="#2E9E5B" stroke-width="4" stroke-linecap="round"></line><text x="186" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" fill="#18202A">SIB</text><text x="186" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">O2</text><rect x="216" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="222" y1="26" x2="222" y2="52" stroke="#2E9E5B" stroke-width="4" stroke-linecap="round"></line><text x="222" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" fill="#18202A">SIA</text><text x="222" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">N2</text></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="lcd" viewBox="0 0 300 92" role="img" aria-label="LCD header pins" xmlns="http://www.w3.org/2000/svg" style="background:#F6F7F9"><rect x="30.25" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="36.25" y1="26" x2="36.25" y2="52" stroke="#D7263D" stroke-width="4" stroke-linecap="round"></line><text x="36.25" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">1 VCC</text><text x="36.25" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">AB23</text><rect x="62.75" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="68.75" y1="26" x2="68.75" y2="52" stroke="#1E1E1E" stroke-width="4" stroke-linecap="round"></line><text x="68.75" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">2 GND</text><text x="68.75" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">AA23</text><rect x="95.25" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="101.25" y1="26" x2="101.25" y2="52" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="101.25" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">3 SCE</text><text x="101.25" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">S27</text><rect x="127.75" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="133.75" y1="26" x2="133.75" y2="52" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="133.75" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">4 RST</text><text x="133.75" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">N27</text><rect x="160.25" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="166.25" y1="26" x2="166.25" y2="52" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="166.25" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">5 D/C</text><text x="166.25" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">O27</text><rect x="192.75" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="198.75" y1="26" x2="198.75" y2="52" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="198.75" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">6 DN</text><text x="198.75" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">P27</text><rect x="225.25" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="231.25" y1="26" x2="231.25" y2="52" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="231.25" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">7 SCLK</text><text x="231.25" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">Q27</text><rect x="257.75" y="14" width="12" height="12" fill="#111" stroke="#D4AF37" stroke-width="1.5"></rect><line x1="263.75" y1="26" x2="263.75" y2="52" stroke="#D7263D" stroke-width="4" stroke-linecap="round"></line><text x="263.75" y="10" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="8" fill="#18202A">8 LED</text><text x="263.75" y="68" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" font-weight="700" fill="#18202A">AB22</text></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="misc" viewBox="0 0 300 150" role="img" aria-label="Pots, SEED and RUN wiring" xmlns="http://www.w3.org/2000/svg" style="background:#F6F7F9"><circle cx="45" cy="42" r="20" fill="#2C3238"></circle><text x="45" y="14" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" fill="#18202A">ENERGY</text><rect x="30.5" y="62" width="5" height="12" fill="#C9CFD5"></rect><line x1="33" y1="74" x2="33" y2="96" stroke="#1E1E1E" stroke-width="4" stroke-linecap="round"></line><text x="33" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">H27</text><rect x="42.5" y="62" width="5" height="12" fill="#C9CFD5"></rect><line x1="45" y1="74" x2="45" y2="96" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="45" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">J27</text><rect x="54.5" y="62" width="5" height="12" fill="#C9CFD5"></rect><line x1="57" y1="74" x2="57" y2="96" stroke="#D7263D" stroke-width="4" stroke-linecap="round"></line><text x="57" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">AB25</text><circle cx="115" cy="42" r="20" fill="#2C3238"></circle><text x="115" y="14" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" fill="#18202A">DRIFT</text><rect x="100.5" y="62" width="5" height="12" fill="#C9CFD5"></rect><line x1="103" y1="74" x2="103" y2="96" stroke="#1E1E1E" stroke-width="4" stroke-linecap="round"></line><text x="103" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">H27</text><rect x="112.5" y="62" width="5" height="12" fill="#C9CFD5"></rect><line x1="115" y1="74" x2="115" y2="96" stroke="#2F6FDB" stroke-width="4" stroke-linecap="round"></line><text x="115" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">I27</text><rect x="124.5" y="62" width="5" height="12" fill="#C9CFD5"></rect><line x1="127" y1="74" x2="127" y2="96" stroke="#D7263D" stroke-width="4" stroke-linecap="round"></line><text x="127" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">AB25</text><circle cx="190" cy="42" r="16" fill="#2C3238"></circle><text x="190" y="14" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" fill="#18202A">SEED</text><line x1="183" y1="58" x2="183" y2="96" stroke="#D9A600" stroke-width="4" stroke-linecap="round"></line><text x="183" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">Q2</text><line x1="197" y1="58" x2="197" y2="96" stroke="#1E1E1E" stroke-width="4" stroke-linecap="round"></line><text x="197" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">AA6</text><rect x="240" y="30" width="34" height="24" rx="3" fill="#2C3238"></rect><text x="257" y="14" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="10" fill="#18202A">RUN</text><rect x="243.5" y="54" width="5" height="10" fill="#C9CFD5"></rect><rect x="254.5" y="54" width="5" height="10" fill="#C9CFD5"></rect><line x1="257" y1="64" x2="257" y2="96" stroke="#D9A600" stroke-width="4" stroke-linecap="round"></line><text x="257" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">S2</text><rect x="265.5" y="54" width="5" height="10" fill="#C9CFD5"></rect><line x1="268" y1="64" x2="268" y2="96" stroke="#1E1E1E" stroke-width="4" stroke-linecap="round"></line><text x="268" y="108" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" font-weight="700" fill="#18202A">AA6</text><text x="150" y="138" text-anchor="middle" font-family="'Martian Mono', ui-monospace, Menlo, Consolas, monospace" font-size="9" fill="#566271">lugs facing down, seen from the front</text></svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 70 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 98 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,36 @@
pad,board_hole,colour,pico_pin_or_signal,goes_to
"P1","Y1","blue","via R1 to opto","MIDI IN jack · ring (pin 4)"
"P2","W1","blue","opto cathode","MIDI IN jack · tip (pin 5)"
"P3","X26","blue","via R4 (10 Ω) from GP0","OUT KIT jack · tip (pin 5)"
"P4","V22","red","via R5 (33 Ω) from 3V3","OUT KIT jack · ring (pin 4)"
"P5","AA22","black","GND strip","OUT KIT jack · sleeve (pin 2)"
"P6","U31","blue","via R6 (10 Ω) from GP4","OUT SYNTH jack · tip (pin 5)"
"P7","V31","red","via R7 (33 Ω) from 3V3","OUT SYNTH jack · ring (pin 4)"
"P8","AA31","black","GND strip","OUT SYNTH jack · sleeve (pin 2)"
"P9","N27","blue","GP21","LCD · RST (pin 4)"
"P10","S27","blue","GP17","LCD · SCE (pin 3)"
"P11","O27","blue","GP20","LCD · D/C (pin 5)"
"P12","P27","blue","GP19","LCD · DN/MOSI (pin 6)"
"P13","Q27","blue","GP18","LCD · SCLK (pin 7)"
"P14","AB23","red","3V3 strip","LCD · VCC (pin 1)"
"P15","AA23","black","GND strip","LCD · GND (pin 2)"
"P16","AB22","red","3V3 strip","LCD · LED (pin 8) through 330 Ω"
"P17","N2","green","GP10","Encoder · SIA"
"P18","O2","green","GP11","Encoder · SIB"
"P19","P2","green","GP12","Encoder · SW"
"P20","AB4","red","3V3 strip","Encoder · VCC"
"P21","AA4","black","GND strip","Encoder · GND"
"P22","J27","blue","GP26","ENERGY pot · middle lug"
"P23","I27","blue","GP27","DRIFT pot · middle lug"
"P24","AB25","red","3V3 strip","Pots · right lugs (chain both)"
"P25","H27","black","AGND","Pots · left lugs (chain both)"
"P26","Q2","yellow","GP13","SEED · one lug"
"P27","S2","yellow","GP14","RUN toggle · middle lug"
"P28","AA6","black","GND strip","Panel ground bus · SEED other lug, RUN one outer lug"
"P29","D2","yellow","GP2","Matrix row 1 (KICK, KICK 2, SNARE)"
"P30","E2","yellow","GP3","Matrix row 2 (HAT, HAT 16, PERC, GHOST)"
"P31","G2","yellow","GP5","Matrix row 3 (BASS, MEL A, MEL B, PAD)"
"P32","I2","green","GP6","Matrix column 1 (KICK, HAT, BASS)"
"P33","J2","green","GP7","Matrix column 2 (KICK 2, HAT 16, MEL A)"
"P34","K2","green","GP8","Matrix column 3 (SNARE, PERC, MEL B)"
"P35","L2","green","GP9","Matrix column 4 (GHOST, PAD)"
1 pad board_hole colour pico_pin_or_signal goes_to
2 P1 Y1 blue via R1 to opto MIDI IN jack · ring (pin 4)
3 P2 W1 blue opto cathode MIDI IN jack · tip (pin 5)
4 P3 X26 blue via R4 (10 Ω) from GP0 OUT KIT jack · tip (pin 5)
5 P4 V22 red via R5 (33 Ω) from 3V3 OUT KIT jack · ring (pin 4)
6 P5 AA22 black GND strip OUT KIT jack · sleeve (pin 2)
7 P6 U31 blue via R6 (10 Ω) from GP4 OUT SYNTH jack · tip (pin 5)
8 P7 V31 red via R7 (33 Ω) from 3V3 OUT SYNTH jack · ring (pin 4)
9 P8 AA31 black GND strip OUT SYNTH jack · sleeve (pin 2)
10 P9 N27 blue GP21 LCD · RST (pin 4)
11 P10 S27 blue GP17 LCD · SCE (pin 3)
12 P11 O27 blue GP20 LCD · D/C (pin 5)
13 P12 P27 blue GP19 LCD · DN/MOSI (pin 6)
14 P13 Q27 blue GP18 LCD · SCLK (pin 7)
15 P14 AB23 red 3V3 strip LCD · VCC (pin 1)
16 P15 AA23 black GND strip LCD · GND (pin 2)
17 P16 AB22 red 3V3 strip LCD · LED (pin 8) through 330 Ω
18 P17 N2 green GP10 Encoder · SIA
19 P18 O2 green GP11 Encoder · SIB
20 P19 P2 green GP12 Encoder · SW
21 P20 AB4 red 3V3 strip Encoder · VCC
22 P21 AA4 black GND strip Encoder · GND
23 P22 J27 blue GP26 ENERGY pot · middle lug
24 P23 I27 blue GP27 DRIFT pot · middle lug
25 P24 AB25 red 3V3 strip Pots · right lugs (chain both)
26 P25 H27 black AGND Pots · left lugs (chain both)
27 P26 Q2 yellow GP13 SEED · one lug
28 P27 S2 yellow GP14 RUN toggle · middle lug
29 P28 AA6 black GND strip Panel ground bus · SEED other lug, RUN one outer lug
30 P29 D2 yellow GP2 Matrix row 1 (KICK, KICK 2, SNARE)
31 P30 E2 yellow GP3 Matrix row 2 (HAT, HAT 16, PERC, GHOST)
32 P31 G2 yellow GP5 Matrix row 3 (BASS, MEL A, MEL B, PAD)
33 P32 I2 green GP6 Matrix column 1 (KICK, HAT, BASS)
34 P33 J2 green GP7 Matrix column 2 (KICK 2, HAT 16, MEL A)
35 P34 K2 green GP8 Matrix column 3 (SNARE, PERC, MEL B)
36 P35 L2 green GP9 Matrix column 4 (GHOST, PAD)

239
docs/hardware/wiring.md Normal file
View File

@@ -0,0 +1,239 @@
# Wiring
One stripboard carries the Pico and the MIDI circuits. Everything on the panel (screen, encoder, pots, buttons, jacks) connects to it with hookup wire.
**Board positions** are strip letter + hole number. For example V4 is strip V, hole 4, counted from the left with the parts facing you. Strips run left to right: A at the top (the USB edge), then Z, AA, AB at the bottom.
The interactive version, with the same drawings, is `tools/wiring.html`. Generated from [`hardware/layout.js`](../../hardware/layout.js).
## Wire map: panel to board
Every panel wire and the board hole it lands in: strip letter, then hole number counted from the opto end.
![Wire map](svg/wire-map.svg)
| Part | Lug | Wire | Board hole |
|---|---|---|---|
| Buttons | Row 1 · KICK, KICK 2, SNARE | yellow | **D2** |
| | Row 2 · HAT, HAT 16, PERC, GHOST | yellow | **E2** |
| | Row 3 · BASS, MEL A, MEL B, PAD | yellow | **G2** |
| | Col 1 · KICK, HAT, BASS (diode band side) | green | **I2** |
| | Col 2 · KICK 2, HAT 16, MEL A | green | **J2** |
| | Col 3 · SNARE, PERC, MEL B | green | **K2** |
| | Col 4 · GHOST, PAD | green | **L2** |
| SEED | one lug | yellow | **Q2** |
| RUN toggle | middle lug (it sits in the button grid, row 1 / col 4) | yellow | **S2** |
| SEED + RUN | ground: SEED other lug, RUN one outer lug | black | **AA6** |
| Encoder | VCC (3.3 V, never 5 V) | red | **AB4** |
| | GND | black | **AA4** |
| | SW | green | **P2** |
| | SIB | green | **O2** |
| | SIA | green | **N2** |
| ENERGY pot | middle lug | blue | **J27** |
| DRIFT pot | middle lug | blue | **I27** |
| Pots | right lugs, both (3.3 V) | red | **AB25** |
| | left lugs, both (AGND) | black | **H27** |
| LCD | 1 · VCC (3.3 V) | red | **AB23** |
| | 2 · GND | black | **AA23** |
| | 3 · SCE | blue | **S27** |
| | 4 · RST | blue | **N27** |
| | 5 · D/C | blue | **O27** |
| | 6 · DN (MOSI) | blue | **P27** |
| | 7 · SCLK | blue | **Q27** |
| | 8 · LED, through a 330 Ω resistor (if dark, move to any AA hole) | red | **AB22** |
| MIDI IN jack | tip | blue | **W1** |
| | ring | blue | **Y1** |
| OUT KIT jack | tip | blue | **X26** |
| | ring | red | **V22** |
| | sleeve | black | **AA22** |
| OUT SYNTH jack | tip | blue | **U31** |
| | ring | red | **V31** |
| | sleeve | black | **AA31** |
## Wire colours
| Colour | Role |
|---|---|
| Red | 3.3 V and the MIDI OUT ring lugs |
| Black | ground |
| Yellow | button rows, SEED, RUN |
| Green | button columns, encoder |
| Blue | screen, pots, MIDI signals |
| Grey | short links on the board |
If your spools are other colours, keep the roles and rename them. Red and black for power and ground matter most.
## Board · parts side
![Stripboard, parts side](svg/stripboard-parts-side.svg)
- **Size**: 34 holes × 28 strips, about 86 × 71 mm.
- **Pico**: sits in two 20-pin female headers with pins 1 and 40 on strip A. Its USB end is flush with the top edge of the board, and the micro-USB socket reaches just past it.
- **Mounting**: lay the board on the box floor with that edge against the back wall, behind the USB slot. The socket is about 41 mm from the board's left edge.
- **Pads**: the numbered dots P1 … P35 are where off-board wires solder.
## Board · copper side, for cutting
![Stripboard, copper side](svg/stripboard-copper-side.svg)
This view is flipped: hole 1 is on the right.
How to cut:
- Use a 3–4 mm drill bit turned by hand, or a spot-face cutter.
- Check each cut with the meter's continuity beeper.
- Hole 6 on strips U to Y (5 cuts)
- Hole 14 on strips U to X (4 cuts)
- Hole 16 on strips A to T (20 cuts)
- Hole 23 on strip X (1 cut)
- Hole 25 on strips U to W (3 cuts)
### Power strips along the bottom
- **Z**: 5 V from the Pico's VBUS. Only the opto uses it.
- **AA**: ground.
- **AB**: 3.3 V from the Pico's 3V3 pin.
Every red wire to the panel starts on AB. Every black wire starts on AA, except the pots, which use the AGND strip.
## Board parts and links
| Part | Value | Holes | Note |
|---|---|---|---|
| Pico 2W | 2 × 20-pin female header | A13–T13 and A20–T20 (pins 1–20 down the left, 40–21 down the right) | USB end flush with the top edge of the board, past strip A |
| U1 | 6N137 | U5–X5, U8–X8 | 6N137 in a DIP-8 socket. Notch toward strip U, pin 1 at hole U5. Pin 7 (enable) is tied to pin 8 by the U10–V10 link. |
| R1 | 220 Ω | V2 – Y2 | MIDI IN current limit. 3-hole span: stand it upright, or use a small ⅛ W part flat. If learning ever misses notes, use 150 Ω. |
| D1 | 1N4148 | V4 – W4 | Band (cathode) on V4, the opto LED anode side. Stands upright (1-hole span). |
| R2 | 1 kΩ | W10 – AB10 | Opto output pull-up to 3.3 V |
| C1 | 100 nF | U11 – X11 | 6N137 supply bypass, right beside the chip: U11 is its 5 V (pin 8) strip, X11 its GND (pin 5) strip. Required. Fit it after the beep test. |
| R4 | 10 Ω | X21 – X25 | MIDI OUT KIT, TX line (RC). Lies flat along strip X, across the cut at X23 (4-hole span, ¼ W fits). SEED hangs right above it. |
| R5 | 33 Ω ½ W | V19 – AB19 | MIDI OUT KIT, 3.3 V line (RA). ½ W: a mono plug in the jack shorts it to ground. |
| R6 | 10 Ω | U28 – Y28 | MIDI OUT SYNTH, TX line (RC) |
| R7 | 33 Ω ½ W | V30 – AB30 | MIDI OUT SYNTH, 3.3 V line (RA). ½ W, same reason as R5. |
| Link | wire | A34 – Z34 | 5 V (VBUS) to the 5 V strip |
| Link | wire | E32 – AB32 | 3V3 to the 3V3 strip |
| Link | wire | R33 – AA33 | GND to the GND strip |
| Link | wire | U13 – Z13 | opto VCC to 5 V |
| Link | wire | U10 – V10 | opto enable (pin 7) to VCC (pin 8): the 6N137 output only works with pin 7 high |
| Link | wire | X12 – AA12 | opto GND to GND |
| Link | wire | W9 – B9 | opto out to GP1 (MIDI RX), strip B |
| Link | wire | A15 – X15 | GP0 (TX KIT) to strip X (R4), straight down under the Pico between its headers |
| Link | wire | F14 – Y14 | GP4 (TX SYNTH) to strip Y (R6), straight down under the Pico between its headers |
## Off-board wires
| Pad | Board hole | Colour | Pico pin / signal | Goes to |
|---|---|---|---|---|
| P1 | Y1 | blue | via R1 to opto | MIDI IN jack · ring (pin 4) |
| P2 | W1 | blue | opto cathode | MIDI IN jack · tip (pin 5) |
| P3 | X26 | blue | via R4 (10 Ω) from GP0 | OUT KIT jack · tip (pin 5) |
| P4 | V22 | red | via R5 (33 Ω) from 3V3 | OUT KIT jack · ring (pin 4) |
| P5 | AA22 | black | GND strip | OUT KIT jack · sleeve (pin 2) |
| P6 | U31 | blue | via R6 (10 Ω) from GP4 | OUT SYNTH jack · tip (pin 5) |
| P7 | V31 | red | via R7 (33 Ω) from 3V3 | OUT SYNTH jack · ring (pin 4) |
| P8 | AA31 | black | GND strip | OUT SYNTH jack · sleeve (pin 2) |
| P9 | N27 | blue | GP21 | LCD · RST (pin 4) |
| P10 | S27 | blue | GP17 | LCD · SCE (pin 3) |
| P11 | O27 | blue | GP20 | LCD · D/C (pin 5) |
| P12 | P27 | blue | GP19 | LCD · DN/MOSI (pin 6) |
| P13 | Q27 | blue | GP18 | LCD · SCLK (pin 7) |
| P14 | AB23 | red | 3V3 strip | LCD · VCC (pin 1) |
| P15 | AA23 | black | GND strip | LCD · GND (pin 2) |
| P16 | AB22 | red | 3V3 strip | LCD · LED (pin 8) through 330 Ω |
| P17 | N2 | green | GP10 | Encoder · SIA |
| P18 | O2 | green | GP11 | Encoder · SIB |
| P19 | P2 | green | GP12 | Encoder · SW |
| P20 | AB4 | red | 3V3 strip | Encoder · VCC |
| P21 | AA4 | black | GND strip | Encoder · GND |
| P22 | J27 | blue | GP26 | ENERGY pot · middle lug |
| P23 | I27 | blue | GP27 | DRIFT pot · middle lug |
| P24 | AB25 | red | 3V3 strip | Pots · right lugs (chain both) |
| P25 | H27 | black | AGND | Pots · left lugs (chain both) |
| P26 | Q2 | yellow | GP13 | SEED · one lug |
| P27 | S2 | yellow | GP14 | RUN toggle · middle lug |
| P28 | AA6 | black | GND strip | Panel ground bus · SEED other lug, RUN one outer lug |
| P29 | D2 | yellow | GP2 | Matrix row 1 (KICK, KICK 2, SNARE) |
| P30 | E2 | yellow | GP3 | Matrix row 2 (HAT, HAT 16, PERC, GHOST) |
| P31 | G2 | yellow | GP5 | Matrix row 3 (BASS, MEL A, MEL B, PAD) |
| P32 | I2 | green | GP6 | Matrix column 1 (KICK, HAT, BASS) |
| P33 | J2 | green | GP7 | Matrix column 2 (KICK 2, HAT 16, MEL A) |
| P34 | K2 | green | GP8 | Matrix column 3 (SNARE, PERC, MEL B) |
| P35 | L2 | green | GP9 | Matrix column 4 (GHOST, PAD) |
## Panel wiring
### Button matrix, seen from the back
![Button matrix](svg/button-matrix.svg)
Each button:
- One lug goes to its row wire (yellow), daisy-chained along the row.
- The other lug goes through a diode to its column wire (green), daisy-chained down the column.
- The diode's band points to the column. Solder the diodes straight onto the button lugs and sleeve them. 1N4148, 1N4448 or any small-signal diode works.
11 track buttons, each with its own diode, plus D1 on the board: 12 diodes. GHOST is wired at row 2 / column 4. The RUN toggle sits in the grid's row 1 / column 4 spot but isn't part of the matrix, so row 1's wire stops at SNARE and column 4 starts at GHOST.
Drawn from behind the panel, the side you solder on: KICK is top-right, RUN top-left.
### MIDI jacks: 3.5 mm TRS, Type A
![TRS jacks](svg/midi-jacks-trs.svg)
| Jack | Tip (pin 5) | Ring (pin 4) | Sleeve (pin 2) |
|---|---|---|---|
| MIDI IN | P2 | P1 | stays empty |
| OUT KIT | P3 | P4 | P5 |
| OUT SYNTH | P6 | P7 | P8 |
- **Jack type**: use stereo (TRS) jacks; mono ones have no ring.
- **Lug order**: it differs between jack models. Find the tip, ring and sleeve lugs with the meter and a plug inserted.
- **Cables**: Type A is the MIDI standard, so a plain stereo 3.5 mm cable goes straight to another Type A device (e.g. SP-404MKII). A DIN device (e.g. MiniFreak) needs a TRS-to-DIN adapter that says **Type A**. A Type B one swaps tip and ring and gives silence; nothing breaks.
### Nokia 5110 module
![LCD pins](svg/lcd-pins.svg)
- Pin order as printed on your module: 1 VCC, 2 GND, 3 SCE, 4 RST, 5 D/C, 6 DN (MOSI), 7 SCLK, 8 LED.
- **LED** (backlight): wire it through a 330 Ω resistor to AB22 (3.3 V), with the resistor inline at the module end, sleeved. If it stays dark, move that wire to any free hole on strip AA (ground). GP22 (L27) stays free; it's only needed for dimming later, through a transistor.
- **SCE** can go straight to ground instead of S27 if it's the only thing on the SPI bus. That frees GP17.
### Encoder module
![Encoder pins](svg/encoder-pins.svg)
Pin order as printed on your module: VCC, GND, SW, SIB, SIA. Power it from 3.3 V (AB4), never 5 V: its pull-up resistors would put 5 V on the Pico's pins. If clockwise steps the wrong way, swap SIA and SIB (or flip it in firmware).
### Pots, SEED, RUN
![Pots, SEED and RUN](svg/pots-seed-run.svg)
- **Pots**, lugs facing down, shaft toward you:
- left lug to AGND (P25)
- middle lug to its pin
- right lug to 3.3 V (P24)
- Chain the left lugs together and the right lugs together.
- If the readings jitter, solder a 100 nF capacitor at each pot, from wiper to left lug.
- **SEED**: one lug to P26, the other to the ground bus (P28).
- **RUN**: middle lug to P27, one outer lug to the ground bus. If RUN and STOP come out swapped, use the other outer lug.
## Build order and checks
### Board
1. Cut the board to 34 × 28 holes. For the top edge, cut through the row of holes above strip A, then sand it back to about 1.3 mm from the strip A holes, stopping before the strip A copper. That puts the Pico's edge flush with the board. Unsanded, the Pico sits about 1 mm back, which still works if the wall slot lets the plug's moulding through.
Make the track cuts and beep each one out.
2. Solder the two Pico headers and the DIP-8 socket (notch toward strip U). Then the resistors and the diode (band on V4).
- Keep everything low, because the SEED button hangs right above R4. R4 lies flat along strip X, across the cut at X23.
- R1's 3-hole span is tight for a ¼ W body, so stand R1 upright or use a small ⅛ W part.
- Leave C1 for step 4.
3. Solder the grey links with insulated wire. The two long ones (GP0 and GP4) run straight down under the Pico, between its two headers, so fit them before the Pico goes in.
4. Before fitting C1, with the Pico and the 6N137 out, check that AB to AA does not beep and Z to AA does not beep. Then fit C1. It can chirp briefly on the beeper once it's in.
### First power
1. Plug in the Pico only and power it from USB. Measure AB to AA: about 3.3 V. Z to AA: about 5 V.
2. Unplug, then insert the 6N137 (notch toward strip U, pin 1 at hole U5).
3. Wire the panel. Before closing the box, check that no bare lugs touch each other.
4. Flash the firmware. Set GP0 and GP4 to 8–12 mA drive (see [pinout](pinout.md)).

50
docs/midi-setup.md Normal file
View File

@@ -0,0 +1,50 @@
# MIDI setup
```
Seedbox OUT KIT ──▶ sampler / drum machine MIDI IN
Seedbox OUT SYNTH ──▶ poly synth MIDI IN
sampler MIDI OUT ──▶ Seedbox IN (only needed to learn pads)
```
All three Seedbox jacks are 3.5 mm TRS, Type A (tip = pin 5, ring = pin 4, sleeve = pin 2).
| Other end | Cable |
|---|---|
| 3.5 mm TRS, Type A (e.g. SP-404MKII) | plain stereo 3.5 mm cable |
| 5-pin DIN (e.g. MiniFreak) | TRS-to-DIN adapter marked Type A |
| 3.5 mm TRS, Type B | Type A ↔ B converter |
A Type B adapter on a Type A jack swaps tip and ring: you get no MIDI, but nothing is damaged.
Both OUTs carry MIDI clock (start, 24 PPQN clock, stop) when clock is enabled. Song Position Pointer is not sent.
## Kit (sampler or drum machine)
Pads are learned, not typed in, so any sampler or drum machine that sends a note-on per pad works. Seedbox plays exactly the channel and note it learned. To use another bank or kit, re-learn the pads there.
### Learn a pad
1. Connect the sampler's MIDI OUT to Seedbox IN. In the simulator, choose it as the input port.
2. LEARN page, push the encoder: the screen says PICK TRACK.
3. Press a kit track button (KICK … PERC): HIT PAD.
4. Hit the pad. Seedbox stores its channel and note.
Kit tracks that aren't learned stay silent and show a dot on the screen map.
STOP sends All Sound Off (CC 120) on every learned kit channel. Some samplers ignore All Notes Off (the SP-404MKII does), but they do obey CC 120.
## Synth
- Poly mode, so bass, melody and pad can overlap.
- Set its MIDI channel to match Seedbox's synth channel (bench setting, default 1).
- An octave offset is available on the bench.
- STOP sends CC 120 and CC 123.
## Hardware notes
- The MIDI OUTs follow the MIDI 1.0 3.3 V electrical spec (CA-033):
- TX goes through 10 Ω to the tip (pin 5).
- 3.3 V goes through 33 Ω to the ring (pin 4).
- The sleeve (pin 2) is ground.
- MIDI IN uses a 6N137 optocoupler powered from 5 V, with its enable pin tied high and its output pulled up to 3.3 V.
- Details are in [hardware/wiring.md](hardware/wiring.md).

View File

@@ -0,0 +1,95 @@
# Scale and root selection
2026-10-11. Status: draft for review.
## Goal
Let Gee lock the line (bass, melody, pad) to a chosen root and scale, so Seedbox can play along with an existing musical idea. The seed still makes everything else.
## Decisions
| Question | Answer |
|---|---|
| Scope | Global and sticky. SEED, ROLL and loading a slot don't change it. Slots don't store it. |
| Pages | Two: ROOT and SCALE, each with AUTO. |
| AUTO | The seed picks from all 21 scales and 12 roots. Every existing seed changes scale (an intended music change). |
| Old data | None kept. It's a prototype, so the flash record starts fresh. |
## Scales
The menu order is also the table index.
| # | Screen name | Steps |
|---|---|---|
| 0 | MAJOR | 0 2 4 5 7 9 11 |
| 1 | MINOR | 0 2 3 5 7 8 10 |
| 2 | DORIAN | 0 2 3 5 7 9 10 |
| 3 | MIXOLYDIAN | 0 2 4 5 7 9 10 |
| 4 | LYDIAN | 0 2 4 6 7 9 11 |
| 5 | PHRYGIAN | 0 1 3 5 7 8 10 |
| 6 | HARM MINOR | 0 2 3 5 7 8 11 |
| 7 | MINOR PENT | 0 3 5 7 10 |
| 8 | MAJOR PENT | 0 2 4 7 9 |
| 9 | PHRYG DOM | 0 1 4 5 7 8 10 |
| 10 | DBL HARM | 0 1 4 5 7 8 11 |
| 11 | HUNG MINOR | 0 2 3 6 7 8 11 |
| 12 | UKR DORIAN | 0 2 3 6 7 9 10 |
| 13 | LYD DOM | 0 2 4 6 7 9 10 |
| 14 | HIRAJOSHI | 0 2 3 7 8 |
| 15 | IN SEN | 0 1 5 7 10 |
| 16 | IWATO | 0 1 5 6 10 |
| 17 | PROMETHEUS | 0 2 4 6 9 10 |
| 18 | WHOLE TONE | 0 2 4 6 8 10 |
| 19 | OCTATONIC | 0 1 3 4 6 7 9 10 |
| 20 | LOCRIAN | 0 1 3 5 6 8 10 |
Scales have 5 to 8 notes. Chords stay "every other scale note" (0, 2, 4 from the chord degree), so:
- 5-note scales give open chords;
- the 6-note whole tone gives augmented chords;
- the 8-note octatonic gives diminished chords.
## Engine (`sim/engine.js`, then `firmware/engine/engine.c`)
- `SCALES` and `SCALE_NAMES` become the 21-entry table above. In C, `SCALES[21][8]` and `SCALE_LEN[21]`.
- `genome()`: `g.scale = r.below(21)`. It's still one draw, so every later draw in the genome is unchanged.
- The params get `scale` (-1 = AUTO, 0..20) and `root` (-1 = AUTO, 0..11). `renderBar` overrides `g.scale` and `g.root` when they're ≥ 0, right after `genome()`, the same way AMENIZER overrides `steps`. In C this is `sb_params.scale` and `sb_params.root`.
- `describe()` and the simulator's "Key" fact show the effective scale and root.
- Integer-only and deterministic, as before.
## Vectors
- Run `npm run vectors` (an intended music change; the commit message says so).
- Add cases to `test/cases.js` with a fixed scale and root, so the C port is tested on overrides. Cover at least:
- a 5-note scale;
- the 8-note OCTATONIC;
- a root that isn't C;
- AUTO.
## Panel (firmware `app/main.c`, simulator `app.js`)
- Pages: SEED · GEN · ROOT · SCALE · BPM · SLOT · ROLL · LEARN.
- ROOT turns through AUTO, C, C#, …, B. SCALE turns through AUTO, MAJOR, …, LOCRIAN. Edit them like GEN: push, turn, push.
- Screen when set: label `ROOT` / `SCALE`, value `D` / `HIRAJOSHI`.
- Screen on AUTO: label `ROOT AUTO` / `SCALE AUTO`, value is what the seed picked.
- A change is heard from the next rendered bar, the same as GEN.
## Storage
- `live_t` gains `scale` and `root`, saved in flash. The record version goes to 2. Old records are ignored and defaults load.
- The leftovers from BANK go: the `unused` record field and `pad_t.spare`.
- Defaults: both AUTO.
- The simulator keeps them in localStorage next to `gen`.
## Docs
- `docs/controls.md`: add ROOT and SCALE to the pages table.
- `docs/concept.md`: the scale list.
- `docs/decisions.md`: add one line on global sticky key, AUTO over all 21.
## Testing
1. `npm test` passes with the new vectors.
2. `cd firmware/test && make test` passes.
3. Bench checks:
- set ROOT D and SCALE HIRAJOSHI, and check the MiniFreak notes stay in D Hirajoshi across several SEEDs;
- check that AUTO shows the seed's own pick.