Ramblings of an aging IT geek
← Ramblings of an aging IT geek
hardware

building a keyboard, and then arguing with qmk

Building a 65% mechanical keyboard from a kit, the soldering, and the long evening spent learning QMK well enough to lay out my own keymap.

A soldering iron and electronics components on a workbench

I have spent the better part of a week building a keyboard, and I would do it again tomorrow. Not because the result is dramatically better than a decent off-the-shelf board, though it is nicer than I expected, but because the whole exercise scratches an itch that software rarely does anymore. You finish it. It exists. You can hold it.

The board is a 65% kit: a hotswap PCB, an aluminium case, a brass plate, and a bag of stabilisers that I have come to regard with deep suspicion. Switches are Gateron browns, which are tactile without being loud enough to annoy the rest of the house, which matters more than usual given none of us are going anywhere at the moment. Caps are a cheap PBT set in a muted grey, because I have no taste and wanted to spend the budget on the bits that matter.

the soldering, which is the easy part

Everyone is nervous about the soldering and almost nobody needs to be. This kit is hotswap for the switches, so the only thing I actually had to solder was the per-key LED strip I optimistically ordered, plus the reset header. That is maybe forty joints, and forty joints is a pleasant evening, not an ordeal.

A close-up of a keyboard PCB with soldered components

The trick, as with all soldering, is heat the joint and not the solder. Tip on the pad and the pin, count two, feed the solder into the joint not onto the iron, count one more, lift. If it looks like a shiny little volcano you've done it. If it looks like a grey ball balanced on a pin, you've made a cold joint and it will haunt you in three months when that key stops registering. I reflowed two that looked dubious and felt very professional about it.

The stabilisers are where the actual craft is. A badly clipped and lubed stabiliser is the difference between a spacebar that goes "thock" and one that goes "chk-rattle". I clipped the feet, lubed the housings with a smear of dielectric grease because it was what I had, and band-aid-modded the PCB contact points with tiny squares cut from a plaster. It is a deeply silly modification with a deeply silly name and it works perfectly.

the firmware is the real project

Here is the bit nobody warns you about. The hardware is an afternoon. The firmware is the rabbit hole.

The board runs QMK, which is the open-source keyboard firmware that most of this hobby is quietly built on. Out of the box it works fine with the default keymap. But the entire point of building your own board is that you do not want the default keymap, so you set up the toolchain, and then you spend an evening learning more about layers than you ever intended to.

A keymap in QMK is just C. You define your layout as an array of arrays, one per layer, and the firmware walks it. Here is a trimmed version of mine, with a function layer hung off a held key:

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE] = LAYOUT_65_ansi(
        KC_ESC,  KC_1, KC_2, KC_3, KC_4, KC_5, /* ... */ KC_BSPC, KC_DEL,
        KC_TAB,  KC_Q, KC_W, KC_E, KC_R, KC_T, /* ... */ KC_BSLS, KC_HOME,
        MO(_FN), KC_A, KC_S, KC_D, KC_F, KC_G, /* ... */ KC_ENT,
        KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, /* ... */ KC_RSFT, KC_UP, KC_END,
        KC_LCTL, KC_LGUI, KC_LALT, /* space */ KC_SPC, MO(_FN), KC_LEFT, KC_DOWN, KC_RGHT
    ),

    [_FN] = LAYOUT_65_ansi(
        KC_GRV,  KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, /* ... */ _______, RESET,
        _______, RGB_TOG, RGB_MOD, RGB_HUI, _______, _______, /* ... */ _______,
        _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, _______, /* ... */ _______,
        _______, _______, _______, _______, _______, _______, /* ... */ _______, KC_PGUP, _______,
        _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
    ),
};

MO(_FN) is "momentary": hold it and you are on the function layer, release and you drop back. I put it on caps lock, because caps lock is wasted real estate and I have never once intended to type in all caps. With the function layer held, the number row becomes F-keys, WASD-ish becomes media controls, and the arrow cluster grows a page-up and page-down. The base layer stays clean.

Flashing is make handwired/myboard:default:flash with the board in bootloader mode, which on this PCB means shorting the reset header or, once you've mapped it, just hitting the RESET keycode you wisely put on the function layer. The first flash is nerve-wracking. Every flash after that is a five-second nothing.

A close-up of a keyboard PCB with switches installed

was it worth it

A few things I'd tell anyone starting this:

  • Buy a switch puller and a keycap puller. They cost almost nothing and the alternative is a flathead screwdriver and regret.
  • Lube your stabilisers before you assemble anything. Doing it afterwards means taking it apart again.
  • Keep your QMK fork in git from the first commit. You will tweak the keymap constantly, and you will want the history.

The honest answer on value is that I now own a keyboard that cost more than a perfectly good one from a shop and took a week of evenings to produce. By any rational measure that is daft.

But I type on it all day, every day, and now it does exactly what I want, the layers are where my fingers expect them, and when something annoys me I edit some C and reflash it in five seconds. There is something quietly satisfying about a tool you have actually built rather than merely bought. I suspect I am about to own several more.