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

a keyboard you build is mostly a firmware project with switches attached

Building a 65% mechanical keyboard turned out to be the easy part; the QMK keymap took three weeks of fiddling to feel right.

A keyboard PCB and loose switches on a desk

I told myself this was a hardware project. Two evenings of soldering, a tidy little 65% board, done. The soldering was indeed two evenings. The firmware has been three weeks and counting, and that is where the actual project was hiding the whole time.

The hardware bit is genuinely pleasant. A hotswap PCB if you want to avoid the iron entirely, or a soldered one if you enjoy the ritual. I went soldered, because I like the smell of flux and I am beyond help. Sixty-eight switches, sixty-eight LEDs I will never use, a controller, a plate, a case. Seat the stabilisers properly, clip and lube them first, because going back in later means desoldering and you will not enjoy that.

A close-up of a keyboard circuit board

then you flash it and nothing is where you want it

The board ran QMK out of the box, which is the right answer for anything you intend to keep. The default keymap is fine for typing the word "test" and nothing else. The moment you try to do real work you discover that a 65% layout has nowhere near enough keys for the muscle memory you've spent twenty years building, and you have to earn the rest back with layers.

A keymap in QMK is just C, which sounds intimidating and isn't. It's a couple of arrays. The shape of it looks like this:

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE] = LAYOUT_65_ansi(
        KC_ESC,  KC_1, KC_2, /* ... */ KC_BSPC, KC_DEL,
        /* ... */
        KC_LCTL, KC_LGUI, KC_LALT, /* space */ MO(_FN), KC_RCTL
    ),
    [_FN] = LAYOUT_65_ansi(
        KC_GRV, KC_F1, KC_F2, /* ... */ _______, RGB_TOG,
        /* ... */
    ),
};

MO(_FN) is a momentary layer: hold it and the function row appears under the number keys. That one line is the difference between a cramped board and a usable one. Everything I lost by going small, the arrows, the F-keys, the home/end cluster, comes back as a layer under a key I hold with my thumb.

The fiddly part isn't writing the keymap. It's living with it. You set up a layout that looks sensible on paper, use it for two days, and discover your hands disagree violently about where the delete key should be. So you change it, reflash, and try again. I've recompiled this firmware more times than I care to count.

A few things I'd tell my three-weeks-ago self:

  • Put the layer-toggle keys somewhere your thumbs already rest. Reaching for a layer key defeats the point.
  • Tap-hold keys (tap for one thing, hold for another) are wonderful until the timing fights you. Tune TAPPING_TERM early or you'll blame the hardware.
  • Keep the keymap in version control. You will want to roll back a "clever" idea, and you will not remember what you changed.

was it worth it

Yes, but not for the reason I expected. The board is lovely and it does feel better than the slab it replaced. The real value was the firmware ending up exactly mine: my layers, my thumb keys, my one daft macro that types my work email address. Nobody sells that. You have to build it, and most of the building is done in a text editor, not with the iron.

The hardware was the excuse. The firmware was the project.