KN-86 Keyboard — Hand-Wired Prototype Build Guide (Sweep-Delayed Fallback)
🛑 Skip this guide if the Sweep PCB arrives in time.
Section titled “🛑 Skip this guide if the Sweep PCB arrives in time.”The primary keyboard path is the Ferris Sweep Soldered kit from holykeebs — see
docs/device/hardware/keyboard.mdfor the canonical build. Per ADR-0031, the KN-86 v0.1 keyboard is a stock 34-key Ferris Sweep (David Barr design), not a custom hand-wired board. This guide is a FALLBACK ONLY.Use it only if the Sweep order is delayed and you need to start firmware/accelerometer bring-up before the PCB lands. If the Sweep PCB is in your hand (or arriving within your bring-up window), stop reading here and follow
keyboard.mdinstead. The hand-wired path below is throwaway-wiring effort that the Sweep makes unnecessary; do not invest in it on the primary timeline.
⚠️ Update 2026-06-06: ADR-0031 adopts the Ferris Sweep (David Barr design, holykeebs Soldered kit) as the v0.1 keyboard, superseding the custom 31-key PCB path this guide originally assumed. This guide is no longer the v0.1 build path. It survives recast (per ADR-0031 §F5) as a parallel bring-up substrate: a breadboard/hand-wired KB2040 + LIS3DH rig you build only if the Sweep PCB is delayed, so firmware and accelerometer work isn’t blocked on the order. It is also a teaching artifact for QMK/RP2040/LIS3DH integration and a record of design history. The hand-wired technique content is preserved intact below — none of it is deleted.
Purpose (fallback path): If — and only if — the Ferris Sweep order is delayed past the point where it would block firmware work, build a working hand-wired 31-key prototype to validate the keymap, QMK build chain, USB-HID-to-Pi enumeration path, and the LIS3DH accelerometer pipeline (ADR-0023) in parallel. The firmware you write here ports forward to the Sweep largely unchanged — same KB2040 (the Sweep uses two of them), same QMK toolchain, same accelerometer driver — but note the keymap retargets from a 31-key unified matrix to the Sweep’s 34-key LAYOUT_split_3x5_2(...) per ADR-0031 §3.1.
Time estimate: 6–10 hours of hands-on work, spread over 2–3 evenings. Cost estimate: ~$80–$120 in parts (one-shot, mostly reusable). Skill level: intermediate soldering. If you’ve built a Corne or Ferris Sweep, this is a notch easier — fewer keys, no split. (And if you’ve already built a Sweep, you don’t need this guide at all.)
When to Use This Guide (and When Not To)
Section titled “When to Use This Guide (and When Not To)”Primary path — use this instead, whenever possible: the Ferris Sweep Soldered kit from holykeebs, documented in docs/device/hardware/keyboard.md. Stock PCB, hot-swap sockets, two KB2040s, TRRS bridge, QMK split-keyboard firmware. Order it, build the bezel, flash QMK. No hand-wiring.
Fallback trigger — use this guide only if BOTH are true:
- The Sweep order is delayed (out of stock, shipping holdup, customs, etc.) and
- Waiting for it would block firmware / QMK / accelerometer bring-up that you need to start now.
If the Sweep is in hand or arriving within your bring-up window, skip this guide entirely — the hand-wired matrix below is throwaway effort the Sweep eliminates.
When the trigger holds, a hand-wired prototype unblocks the following in parallel:
- Get QMK building and flashing for the RP2040 / KB2040 target on real silicon
- Validate the keymap semantics (the 31-key legend from ADR-0022; note the Sweep retargets this to a 34-key split per ADR-0031 §3.1)
- Bring up the LIS3DH accelerometer (ADR-0023) on the same MCU
- Validate USB-HID enumeration on the Pi Zero 2 W via the internal USB hub
- Find keymap-ergonomic problems before the real keyboard arrives
Most of what you build here is reusable when the Sweep lands: the KB2040 transfers (the Sweep master half can host it), the accelerometer breakout transfers, and all the firmware/driver work ports forward. Only the matrix wiring and the cardboard plate are throwaway.
BOM (Prototype-Specific)
Section titled “BOM (Prototype-Specific)”Everything below is in addition to the PCB-version BOM in keyboard.md.
| Item | Qty | Source | Approx Cost |
|---|---|---|---|
| Adafruit KB2040 (RP2040, USB-C, Pro Micro form factor) | 1 | Adafruit PID 5302, DigiKey 1528-5302-ND | $8.95 |
| Kailh Choc v1 switches (linear or tactile, your call) | 31 + spares | Keebio, SplitKB, Little Keyboards | $25–$40 (~$0.80 ea) |
| MBK keycaps (blank or labeled) | 29× 1U + 1× 1.75U + 1× 1.5U | Keebio, SplitKB | $25–$60 |
| 1N4148 through-hole diodes (DO-35 axial) | 31 + spares | DigiKey, Mouser, Amazon | $3 for 100 |
| Adafruit LIS3DH breakout (ADA-2809) | 1 | Adafruit PID 2809, DigiKey 1528-1561-ND | $5.95 |
| 30 AWG silicone-coated wire, multiple colors | ~10 ft total | Adafruit PID 1880 set, Amazon | $10 |
| Solid-core 22 AWG hookup wire (matrix backbone) | ~2 ft | Hardware store, Amazon | $5 |
| Hot-glue gun + sticks | 1 | Any | $10 |
| Cardboard or 3mm scrap plywood (mounting plate) | 1 sheet | Around the house | $0 |
| USB-C → USB-A cable (for flashing + Pi connection) | 1 | Anywhere | $5 |
Total: ~$80–$120
You probably already own the wire, glue gun, cable, and plate material. If so, the real out-of-pocket is closer to $50–$70.
- Soldering iron (60W or temperature-controlled, ~330°C tip)
- Lead-free or 60/40 solder (0.6mm or 0.8mm)
- Wire cutters / strippers
- Tweezers
- Multimeter (continuity beep is the most-used function for matrix debugging)
- Hot air rework station — nice to have, not required
Build Plan (4 Stages)
Section titled “Build Plan (4 Stages)”Stage 1 — The Plate (30 min)
Section titled “Stage 1 — The Plate (30 min)”The “plate” is just a flat piece of material that holds the 31 switches in place while you solder. It’s not the production keyplate; it’s a soldering jig.
Two paths:
-
Cardboard / corrugated plastic (fastest): mark a 4×8 grid at 18mm pitch on a flat sheet. Cut 14mm × 14mm holes for each switch position. Choc v1 switches snap into a 14mm × 14mm cutout. ~30 min with a hobby knife.
-
3D-printed plate (cleaner): if you have a 3D printer, model a 150mm × 95mm plate with 14mm × 14mm cutouts at 18mm pitch matching
keyboard-layout-diagram.txt. PLA in 1.5mm thickness is plenty rigid. ~60 min print time.
Layout reference (for cutout positions, all in mm from top-left):
| Row | Y (top of cutout) | Function (left side, 4 keys) | Numpad (right side, 4 keys) |
|---|---|---|---|
| 1 | 5 | QUOTE / CONS / NIL / FN @ X = 5, 23, 41, 59 | · / 1 / 2 / · @ X = 78, 96, 114, 132 |
| 2 | 23 | INFO / CAR / APPLY / SYS | GHI(4) / JKL(5) / MNO(6) / : |
| 3 | 41 | LINK / BACK / CDR / ATOM | PQRS(7) / TUV(8) / WXYZ(9) / + |
| 4 | 59 | EVAL(1.75u) / EQ / TERM(1.5u) | * / 0 / # / ENT |
The 1.75u and 1.5u key cutouts on Row 4 left are wider — center them on the same column-1 / column-3 positions, but the cutout itself is 25.5mm (1.5u) or 29.75mm (1.75u) wide.
Shortcut: if the plate work intimidates, skip it entirely and hot-glue the switches directly to a flat piece of cardboard at 18mm pitch. It looks bad but works fine for firmware bring-up.
Stage 2 — Switches and Diodes (90 min)
Section titled “Stage 2 — Switches and Diodes (90 min)”Snap all 31 switches into the plate. Choc v1 switches have side clips that grip a 14mm × 14mm cutout. Push down firmly until both sides click. They should not wiggle when seated.
Solder a 1N4148 diode to each switch. For each switch:
- Bend the diode’s cathode lead (the end with the black band) into a small hook.
- Hook the cathode onto switch pin 2 (the one on the right when the switch logo faces you). Solder.
- Trim the anode (other end) to ~6mm of straight lead pointing out the back of the plate.
- Mark the orientation: black band always on the switch side, anode pointing away from the switch. Get this wrong and that key won’t work — and matrix-ghost detection will be confusing.
After 31 switches: you have a plate with a forest of 31 bent diodes pointing up from the back. Inspect for cold solder joints. Wiggle each diode — if any flexes the joint, reflow it.
Stage 3 — Matrix Wiring (3–4 hours)
Section titled “Stage 3 — Matrix Wiring (3–4 hours)”This is the slow part. Be patient. Test continuity as you go — finding a bad joint after wiring 31 keys is much harder than catching it at key 7.
Matrix layout: 4 rows × 8 columns. Per keyboard-electrical-spec.txt:
COL: 0 1 2 3 4 5 6 7ROW 0: QUOTE CONS NIL FN · 1 2 ·ROW 1: INFO CAR APPLY SYS GHI(4) JKL(5) MNO(6) :ROW 2: LINK BACK CDR ATOM PQRS(7) TUV(8) WXYZ(9) +ROW 3: EVAL EQ TERM (none) * 0 # ENTNote: Row 3 column 3 has no key (the wider EVAL/EQ/TERM keys take 3 column positions on the left side, leaving column 3 empty).
Wiring approach:
- Rows first. Strip a long piece of 22AWG solid-core hookup wire. Bend it into a serpentine that runs through all 8 column positions in one row, with a small bare loop at each switch position. Solder each diode’s anode (free end) to the row wire. Repeat for all 4 rows. Use a different wire color per row — it makes debugging immensely faster.
- Columns second. With 30AWG silicone wire (more flexible — easier to route), connect switch pin 1 of each switch in a column. Different color per column if you can manage it (or at least one stripe pattern to distinguish columns from rows).
- Trim and test continuity with your multimeter:
- Each row line: continuous from end to end.
- Each column line: continuous from end to end.
- Each row should NOT have continuity to any other row (until pressed).
- Each row-to-column intersection: open until you press the corresponding key, then closed (through the diode).
Pro tip: Take a photo of your matrix at every 4-key milestone. If you find a problem 20 keys in, you can compare against the photo to spot which connection went wrong.
Stage 4 — KB2040 Wiring + Accelerometer (90 min)
Section titled “Stage 4 — KB2040 Wiring + Accelerometer (90 min)”KB2040 power and matrix wiring:
Per ADR-0024 §3 canonical as-built pin map. Wire to the KB2040’s silkscreen labels — these are printed on the board itself, so you don’t have to translate to GP-numbers while soldering:
| KB2040 silkscreen label | Wire To | Function |
|---|---|---|
| D0 | Row 0 line | Matrix row input |
| D1 | Row 1 line | Matrix row input |
| D2 | Row 2 line | Matrix row input |
| D3 | Row 3 line | Matrix row input (same pin as silkscreen “MOSI” — wire to D3 only) |
| D7 | Col 0 line | Matrix column output |
| D8 | Col 1 line | Matrix column output |
| D9 | Col 2 line | Matrix column output |
| A3 | Col 3 line | Matrix column output |
| A2 | Col 4 line | Matrix column output |
| A1 | Col 5 line | Matrix column output |
| A0 | Col 6 line | Matrix column output |
| D10 | Col 7 line | Matrix column output |
| 3V3 | LIS3DH VDD | Sensor power |
| GND | LIS3DH GND, all matrix grounds (none in this layout) | Common ground |
| D4 (silk: SDA) | LIS3DH SDA | I²C0 SDA |
| D5 (silk: SCL) | LIS3DH SCL | I²C0 SCL |
| D6 | LIS3DH INT1 | Reserved interrupt |
(For QMK config.h, these silkscreen labels map to RP2040 pins as: D0=GP0, D1=GP1, D2=GP2, D3=GP3, D4=GP4, D5=GP5, D6=GP6, D7=GP7, D8=GP8, D9=GP9, D10=GP10, A0=GP26, A1=GP27, A2=GP28, A3=GP29.)
LIS3DH breakout wiring:
The Adafruit ADA-2809 breakout exposes pins via 0.1” headers. Solder the included male header (or use stranded wire directly). Then wire:
| LIS3DH Breakout Pin | Connect To (KB2040 silkscreen) |
|---|---|
| VIN | 3V3 |
| GND | GND |
| SCL | D5 (silk: SCL) |
| SDA | D4 (silk: SDA) |
| SDO/SA0 | GND (selects I²C address 0x18) |
| CS | 3V3 (forces I²C mode, not SPI) |
| INT | D6 |
The breakout has built-in 10kΩ pull-ups on SDA/SCL — you do not need to add external pull-ups for the prototype.
Mount the LIS3DH in the same orientation as the production PCB: sensor’s native +X axis pointing toward operator-right (the numpad side). Hot-glue the breakout to the bottom of the plate near the KB2040, with the chip’s pin-1 dot oriented to match. Doesn’t have to be exact — bring-up validates that tilting operator-right reads positive X.
KB2040 mounting: hot-glue it to the bottom of the plate too. USB-C connector should face the bottom edge of the plate so you can plug in a cable without disturbing the matrix.
Firmware (QMK)
Section titled “Firmware (QMK)”Detailed firmware steps belong in a separate document; here’s the bring-up loop.
- Set up QMK. Follow QMK’s RP2040 setup guide. Confirm
qmk doctorpasses. - Create a new keyboard under
keyboards/handwired/kn86:info.json: matrix size 4×8, layout per ADR-0022config.h: pin assignments per ADR-0024 §3keymap.c: 31-key keymap from ADR-0022
- Build:
qmk compile -kb handwired/kn86 -km default - Flash: hold BOOT on the KB2040, press RESET, release BOOT. Drag the .uf2 to the BOOTSEL volume that appears.
- Test: open a text editor on your laptop. Press each of the 31 keys. Verify the right character/scancode arrives. If any key doesn’t register or registers as the wrong character, debug with the QMK console (
qmk console) and trace the matrix with your multimeter. - Add LIS3DH driver: pull the QMK
accel_lis3dhcommunity module. Add a debug print of accelerometer X/Y/Z values to the QMK console. Tilt the prototype operator-right; X should go positive.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely Cause | Fix |
|---|---|---|
| Whole row of keys dead | Bad row wire | Multimeter the row line end-to-end |
| Whole column of keys dead | Bad column wire or wrong KB2040 pin | Recheck pin map; multimeter column |
| One key dead | Diode reversed or cold joint | Inspect diode orientation (band toward switch) |
| Two keys press as one | Diode missing or shorted | Check diode placement |
| All keys register on every press | Diode cathodes wired wrong direction | Reverse all diodes (pain — be careful upfront) |
| KB2040 doesn’t enumerate | USB cable is power-only | Use a known-good data cable |
| LIS3DH not detected on I²C | SA0 floating, or SDA/SCL swapped | Verify SA0 to GND, address scan via QMK console |
What This Prototype Validates
Section titled “What This Prototype Validates”- ✅ QMK builds and flashes for KB2040 / RP2040 target
- ✅ 31-key matrix layout is correct in ADR-0022
- ✅ Keymap behavior under realistic typing
- ✅ USB HID enumeration on the Pi Zero 2 W
- ✅ LIS3DH I²C bring-up + axis convention sanity check
- ✅ Internal USB hub IC integration (when the Pi-side hardware is ready)
What This Prototype Does NOT Validate
Section titled “What This Prototype Does NOT Validate”- ❌ PCB-level signal integrity (no traces yet)
- ❌ Mechanical fit in the Pelican 1170 case
- ❌ Hot-swap socket compatibility (you’ve direct-soldered the switches)
- ❌ Production manufacturability
- ❌ Long-term reliability of the matrix wiring (hand-wired matrices loosen over time)
When the Ferris Sweep arrives (the primary keyboard — see keyboard.md), you transfer the LIS3DH and a KB2040 to the Sweep’s master half, reflash QMK against the keyboards/ferris/sweep tree, and you’re done with the hand-wired rig. The accelerometer driver and the QMK toolchain carry over unchanged; the keymap retargets from this 31-key unified matrix to the Sweep’s 34-key LAYOUT_split_3x5_2(...) per ADR-0031 §3.1 (the logical Lisp-primitive / Nokia-digit semantics are preserved; the physical layout changes).
Reusing the Prototype for Bench Tests
Section titled “Reusing the Prototype for Bench Tests”After the Ferris Sweep takes over as the primary keyboard, the hand-wired prototype is still useful:
- QMK firmware regression bench — keep it wired and powered to test keymap-semantics revisions before flashing the Sweep
- Accelerometer experimentation rig — easier to tilt and shake a cardboard plate than a fully assembled KN-86
- Pi-side software development target — any USB HID keyboard that emits the right scancodes is good enough for nOSh dispatch testing
Don’t throw it out when the Sweep lands.
Time Budget Realistic Estimate
Section titled “Time Budget Realistic Estimate”| Stage | Estimated time | Hard part |
|---|---|---|
| Stage 1 (plate) | 30–60 min | Marking precise 18mm pitch |
| Stage 2 (switches + diodes) | 90 min | Diode orientation discipline |
| Stage 3 (matrix wiring) | 3–4 hours | Patience, color discipline, continuity-as-you-go |
| Stage 4 (KB2040 + LIS3DH) | 90 min | Pin map verification |
| QMK setup + first flash | 60–90 min | RP2040 toolchain on macOS specifically |
| Keymap validation | 30 min | First-flash debugging |
| LIS3DH bring-up | 60 min | I²C pull-up sanity, address detection |
| Total | 8–11 hours | Spread over 2–3 evenings |
If you’ve never built a hand-wired keyboard before, add 50% buffer. The first one always takes longer.
Reference Documents
Section titled “Reference Documents”Primary keyboard path (use this first):
keyboard.md— PRIMARY keyboard subsystem spec (Ferris Sweep). Start here; this guide is a fallback only.- ADR-0031 — Ferris Sweep adoption (34-key split), supersedes the custom 31-key path; §3.1 carries the canonical keymap manifest.
Hand-wired fallback context:
- ADR-0018 — Custom mech-keeb build pattern (PCB path superseded by ADR-0031; commodity-parts framing preserved)
- ADR-0022 — Legend manifest (left-half Lisp primitives preserved; right-half superseded by ADR-0031 §3.1)
- ADR-0023 — LIS3DH integration
- ADR-0024 — KB2040 controller (pin map amended by ADR-0031 §3 + ADR-0032 §3 for split topology)
keyboard-layout-diagram.txt— Physical layout (legacy 31-key reference)keyboard-electrical-spec.txt— Pin map + matrix detail (superseded by ADR-0031; design history)keyboard-keycap-legend.txt— Keycap labels and shifts