- 12
- Keys
- 2
- Rotary encoders
- 3
- PCB revisions
- 1 ms
- Scan rate
Flux exists because I kept reaching for the same fifteen shortcuts in Fusion 360 and my IDE, and because I had never designed a PCB before. A 12-key macropad is the ideal first board: small enough to fail cheaply, complex enough to be a real design — matrix wiring, addressable LEDs, an I2C display, USB routing.
The board
The PCB is a two-layer design in KiCad around a bare RP2040 rather than a Pi Pico module, mostly to force myself to deal with the hard parts: the 12 MHz crystal layout, the W25Q16 flash, USB differential pair routing, and the 3.3 V regulator. The 12 keys sit in a 4x3 matrix (4 rows, 3 columns, one diode per key), Kailh hot-swap sockets on the back, and SK6812 Mini-E LEDs shine through a cutout in each socket footprint. Two EC11 encoders and the SSD1306 OLED live on a raised top row.
Rev 1 had the hot-swap socket footprint mirrored — sockets mount on the bottom of the board, and I had drawn them from the top view. Rev 2 fixed that but put the USB shield ground on the wrong net. Rev 3 works. Three revisions at about $9 per batch of five boards was cheap tuition.
Matrix scanning and the OLED
Firmware is stock QMK with a custom keyboard definition. QMK handles debouncing and matrix scanning at a 1 ms rate; my code mostly lives in the OLED task, which renders the active layer, a WPM counter, and the current encoder mode:
bool oled_task_user(void) {
oled_write_P(PSTR("Layer: "), false);
switch (get_highest_layer(layer_state)) {
case _BASE: oled_write_ln_P(PSTR("BASE"), false); break;
case _CAD: oled_write_ln_P(PSTR("CAD"), false); break;
case _MEDIA: oled_write_ln_P(PSTR("MEDIA"), false); break;
}
return false;
}
The per-key RGB doubles as a layer indicator too — the CAD layer lights the view-control keys blue, which turned out to be more useful than the OLED for at-a-glance state.
What I’d do differently
Ghosting never showed up thanks to the diodes, but I initially scanned columns with a 10 µs settle delay that was too short for the long traces near the encoders, producing phantom presses on one column. Bumping the delay fixed it; routing the matrix more compactly would have been the real fix. Rev 4 will also add ESD protection on USB — the current board survives on luck.
Development timeline
- 2025-04
Schematic and layout
First KiCad board sent to JLCPCB after a week of datasheet reading.
- 2025-05
Rev 1 arrives
Booted, typed, and taught me two hard lessons about footprints.
- 2025-06
Rev 3 + case
Clean board, printed case with heat-set inserts, QMK merged into my fork.
- 2025-07
Daily driver
Living next to my keyboard running shortcut layers for CAD and the IDE.