Skip to content

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.md for 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.md instead. 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.)

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:

  1. The Sweep order is delayed (out of stock, shipping holdup, customs, etc.) and
  2. 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.


Everything below is in addition to the PCB-version BOM in keyboard.md.

ItemQtySourceApprox Cost
Adafruit KB2040 (RP2040, USB-C, Pro Micro form factor)1Adafruit PID 5302, DigiKey 1528-5302-ND$8.95
Kailh Choc v1 switches (linear or tactile, your call)31 + sparesKeebio, SplitKB, Little Keyboards$25–$40 (~$0.80 ea)
MBK keycaps (blank or labeled)29× 1U + 1× 1.75U + 1× 1.5UKeebio, SplitKB$25–$60
1N4148 through-hole diodes (DO-35 axial)31 + sparesDigiKey, Mouser, Amazon$3 for 100
Adafruit LIS3DH breakout (ADA-2809)1Adafruit PID 2809, DigiKey 1528-1561-ND$5.95
30 AWG silicone-coated wire, multiple colors~10 ft totalAdafruit PID 1880 set, Amazon$10
Solid-core 22 AWG hookup wire (matrix backbone)~2 ftHardware store, Amazon$5
Hot-glue gun + sticks1Any$10
Cardboard or 3mm scrap plywood (mounting plate)1 sheetAround the house$0
USB-C → USB-A cable (for flashing + Pi connection)1Anywhere$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

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:

  1. 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.

  2. 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):

RowY (top of cutout)Function (left side, 4 keys)Numpad (right side, 4 keys)
15QUOTE / CONS / NIL / FN @ X = 5, 23, 41, 59· / 1 / 2 / · @ X = 78, 96, 114, 132
223INFO / CAR / APPLY / SYSGHI(4) / JKL(5) / MNO(6) / :
341LINK / BACK / CDR / ATOMPQRS(7) / TUV(8) / WXYZ(9) / +
459EVAL(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.

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:

  1. Bend the diode’s cathode lead (the end with the black band) into a small hook.
  2. Hook the cathode onto switch pin 2 (the one on the right when the switch logo faces you). Solder.
  3. Trim the anode (other end) to ~6mm of straight lead pointing out the back of the plate.
  4. 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.

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 7
ROW 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 # ENT

Note: 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:

  1. 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.
  2. 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).
  3. 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 labelWire ToFunction
D0Row 0 lineMatrix row input
D1Row 1 lineMatrix row input
D2Row 2 lineMatrix row input
D3Row 3 lineMatrix row input (same pin as silkscreen “MOSI” — wire to D3 only)
D7Col 0 lineMatrix column output
D8Col 1 lineMatrix column output
D9Col 2 lineMatrix column output
A3Col 3 lineMatrix column output
A2Col 4 lineMatrix column output
A1Col 5 lineMatrix column output
A0Col 6 lineMatrix column output
D10Col 7 lineMatrix column output
3V3LIS3DH VDDSensor power
GNDLIS3DH GND, all matrix grounds (none in this layout)Common ground
D4 (silk: SDA)LIS3DH SDAI²C0 SDA
D5 (silk: SCL)LIS3DH SCLI²C0 SCL
D6LIS3DH INT1Reserved 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 PinConnect To (KB2040 silkscreen)
VIN3V3
GNDGND
SCLD5 (silk: SCL)
SDAD4 (silk: SDA)
SDO/SA0GND (selects I²C address 0x18)
CS3V3 (forces I²C mode, not SPI)
INTD6

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.


Detailed firmware steps belong in a separate document; here’s the bring-up loop.

  1. Set up QMK. Follow QMK’s RP2040 setup guide. Confirm qmk doctor passes.
  2. Create a new keyboard under keyboards/handwired/kn86:
    • info.json: matrix size 4×8, layout per ADR-0022
    • config.h: pin assignments per ADR-0024 §3
    • keymap.c: 31-key keymap from ADR-0022
  3. Build: qmk compile -kb handwired/kn86 -km default
  4. Flash: hold BOOT on the KB2040, press RESET, release BOOT. Drag the .uf2 to the BOOTSEL volume that appears.
  5. 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.
  6. Add LIS3DH driver: pull the QMK accel_lis3dh community module. Add a debug print of accelerometer X/Y/Z values to the QMK console. Tilt the prototype operator-right; X should go positive.

SymptomLikely CauseFix
Whole row of keys deadBad row wireMultimeter the row line end-to-end
Whole column of keys deadBad column wire or wrong KB2040 pinRecheck pin map; multimeter column
One key deadDiode reversed or cold jointInspect diode orientation (band toward switch)
Two keys press as oneDiode missing or shortedCheck diode placement
All keys register on every pressDiode cathodes wired wrong directionReverse all diodes (pain — be careful upfront)
KB2040 doesn’t enumerateUSB cable is power-onlyUse a known-good data cable
LIS3DH not detected on I²CSA0 floating, or SDA/SCL swappedVerify SA0 to GND, address scan via QMK console

  • ✅ 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)
  • ❌ 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).


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.


StageEstimated timeHard part
Stage 1 (plate)30–60 minMarking precise 18mm pitch
Stage 2 (switches + diodes)90 minDiode orientation discipline
Stage 3 (matrix wiring)3–4 hoursPatience, color discipline, continuity-as-you-go
Stage 4 (KB2040 + LIS3DH)90 minPin map verification
QMK setup + first flash60–90 minRP2040 toolchain on macOS specifically
Keymap validation30 minFirst-flash debugging
LIS3DH bring-up60 minI²C pull-up sanity, address detection
Total8–11 hoursSpread over 2–3 evenings

If you’ve never built a hand-wired keyboard before, add 50% buffer. The first one always takes longer.


Primary keyboard path (use this first):

  • keyboard.mdPRIMARY 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