kei40

Overview

A handwired 40% ortholinear keyboard (4x10, 39 keys), built from bare parts up rather than around a PCB. Every switch is wired directly to a Raspberry Pi Pico (RP2040) through a hand-soldered diode matrix — no pre-made hotswap board, no plug-and-play kit. Every row, every column, every joint was placed and soldered individually, which means every quirk in the final board is something I put there myself, for better or worse. The 40% layout strips the board down to just what a normal typing/coding session actually touches, moving numbers, symbols, and function keys onto held layers instead of dedicating physical rows to them. kei (軽) — light in weight; the idea was to build something reduced to its essential form, both physically (compact footprint) and in what it asks of the fingers (no reaching, no bulk).

Specifications

Layout: 4x10 ortholinear (39 keys) — straight rows and columns rather than the row-stagger of a traditional keyboard, so every key sits in a true grid and finger travel is consistent across the whole board. Plate: FR4 ortholinear plate, giving the switches a stable, slightly flexy mounting surface with a bit more give than a rigid aluminum plate. Switches: Feker Holy Panda, a linear-meets-tactile hybrid prized for a sharp, defined bump without being heavy — modded further by lubing the rails with Krytox 205g0 (a thicker grease for smoothing housing-on-stem friction) and the springs with Krytox 105g0 (a thinner oil, cutting spring ping and scratch).

Controller: Raspberry Pi Pico (RP2040), a dual-core microcontroller with a native USB bootloader, chosen over a dedicated keyboard MCU partly for cost and partly for how forgiving its flashing process is. Wiring: 22 AWG solid-core copper wire for the matrix runs — solid-core holds its bend and stays put during soldering, unlike stranded wire which tends to fray and shift. Diodes: 1N4148, one per switch, oriented to enforce correct signal direction through the matrix and prevent ghosting when multiple keys are pressed at once. Keycaps: blank white XDA profile — uniform height across every row (unlike sculpted profiles like Cherry or OEM), which suits an ortholinear layout since there's no row-specific curvature to account for.

Software requirements

A working QMK firmware environment and the QMK CLI tools installed on your machine — QMK (Quantum Mechanical Keyboard) is the open-source firmware framework that turns a plain microcontroller into an actual keyboard, handling matrix scanning, debouncing, layer logic, and USB HID reporting. Runs on Windows, macOS, and Linux. No account, no API key, no internet connection needed after the initial toolchain setup — everything happens locally through the QMK build toolchain and the Pico's built-in USB bootloader, so the entire flash cycle works completely offline.

Setup

With the QMK environment set up, navigate to the firmware directory and compile the keymap with qmk compile -kb handwired/kei40 -km default. This runs the keymap and matrix configuration through QMK's build system and produces a handwired_kei40_default.uf2 file — a self-contained firmware image ready to drop straight onto the controller, no separate flashing tool required since the RP2040's bootloader reads UF2 files natively.

First flash

Hold the BOOTSEL button on the Raspberry Pi Pico while plugging in the USB cable — this forces the RP2040 to boot into its ROM-level USB mass storage bootloader instead of running any existing firmware. The controller mounts as a drive named RPI-RP2, appearing just like a blank USB flash drive to your computer. Drag the compiled .uf2 file onto that drive, and it will automatically unmount and reboot straight into the new firmware the moment the copy finishes — no drivers, no vendor flashing utility, no additional software required beyond a file manager. From that point on, the board enumerates as a standard USB HID keyboard.

Usage / Layers

  • Base layer — standard alpha and modifier keys, arranged ortholinear across 4 rows of 10, covering everything a normal typing session needs without ever touching a layer key
  • Layer 1 (symbols) — held via MO(1), remapping the board to numbers and the symbol row, since a 40% board has no room to dedicate physical keys to them permanently
  • Layer 2 (function) — held via MO(2), surfacing F-keys and system-level controls like media and brightness
  • Both layers are momentary (MO), meaning they're only active while the trigger key is physically held down, releasing it snaps instantly back to base with zero latency or mode-switching, unlike a toggle layer that has to be explicitly turned back off

Configuration options

No runtime configuration menu — this is firmware, not an app, so every change is made by editing source and reflashing rather than adjusting a setting live. The keymap itself lives in keymaps/default/keymap.c, where each layer's key assignments are defined as a C array. Hardware-level settings — which GPIO pins the matrix rows and columns are wired to, which direction the diodes face, debounce timing — live in keyboard.json, the board-level definition QMK reads before it ever gets to the keymap. Any edit to either file requires a full recompile and reflash to take effect; there's no hot-reload or partial update path, since the firmware is a single monolithic image.

Troubleshooting

  • Drive doesn't show up in bootloader mode — make sure BOOTSEL is held before plugging in the USB cable, not after the connection is already established; also worth ruling out a power-only cable, since some USB-C/micro-USB cables carry power but have no data lines wired at all, which looks identical to a bootloader failure at first glance.
  • Compile errors — double check the QMK CLI is up to date (qmk setup can resync a stale toolchain) and that you're running the command from inside the qmk_firmware root directory, since relative paths in the build system assume that working directory.
  • Keys not registering after flash — on a handwired board, this almost always traces back to the physical matrix rather than the firmware: check diode orientation first (a reversed diode will silently kill signal in one direction), then inspect solder joints on the affected row/column intersection, since unlike a PCB where a bad connection is rare and isolated, a single cold joint on a handwired matrix will take out an entire row or column at once, not just one key.
  • Drive doesn't show up in bootloader mode — make sure BOOTSEL is held before plugging in the USB cable, not after the connection is already established; also worth ruling out a power-only cable, since some USB-C/micro-USB cables carry power but have no data lines wired at all, which looks identical to a bootloader failure at first glance. Compile errors — double check the QMK CLI is up to date (qmk setup can resync a stale toolchain) and that you're running the command from inside the qmk_firmware root directory, since relative paths in the build system assume that working directory. Keys not registering after flash — on a handwired board, this almost always traces back to the physical matrix rather than the firmware: check diode orientation first (a reversed diode will silently kill signal in one direction), then inspect solder joints on the affected row/column intersection, since unlike a PCB where a bad connection is rare and isolated, a single cold joint on a handwired matrix will take out an entire row or column at once, not just one key.

Installation