Nerves-keyboard - Running a mechanical keyboard with Elixir

Underjord is a tiny, wholesome team doing Elixir consulting and contract work. If you like the writing you should really try the code. See our services for more information.

Chris Dosé was interviewed by us on Elixir Mix. When he spoke about his work on a Nerves-powered keyboard I knew this was a project I wanted to try out. So I dropped into their dev channel, acquired the hardware (thanks for the help) and have done some playing around with it.

So what is the draw of a Nerves keyboard? Well, you can program it in Elixir. That's a big one for me personally. It also means that compared to a lot of high-level languages driving hardware you have pretty strong performance characteristics, resilience and specifically with Nerves a lot of best practices for running embedded hardware. It makes managing firmware updates easier, it mitigates corruption on SD cards and lots more. As an Elixir developer the pure convenience of customizing the keyboard in my favored language is of course delightful.

This post should help you try it out if you have/get the required hardware. The project is currently using the Keybow keypad as a prototyping platform to figure out how things should work while they work on the details of a full keyboard and it is a neat little gadget, whatever you want to do with it.

Getting started

Requirements to try this:

  • A Keybow kit, with Pi Zero (Adafruit)
  • Micro USB Cable
  • Micro SD Card

To get up and running you should:

The installation guide might not tell you to go into assets and run npm install but I think you have to. I'm not going to tell you how to install Node and NPM because it varies. But you can probably find it around the Node site.

If you reach the point of having burned the firmware to your SD Card, congratulations. We are ready to play.

First firmware on the device

So plug the SD card with your pristine Xebow firmware into the Keybow contraption and plug the Keybow into your computer with the Micro USB cable. Startup can take a little bit but it should settle into cycling through rainbow colors after a bit. It should also produce numbers when you poke it (the default keymap is a numpad plus some extras).

Making changes

I don't need a single numpad and now I have two of them. Let's make this more useful. Open lib/xebow/keyboard.ex in your preferred editor.

Replace the default keymap with:

elixir lib/xebow/keyboard.ex
    @keymap [

And then:

shell /
export MIX_TARGET=keybow
mix firmware
mix firmware.gen.script
./ xebow.local

Sometimes the upload process can be finicky. You can always re-burn the firmware to the SD card instead using mix firmware.burn instead of the gen.script.

The navigator

So with the Keybow on its side, four wide. You'll have this fantastic navigation machine at your disposal. Top row are arrows, middle row is VIM navigation or GMail or wherever else the don't-move-your-fingers approach is used. Bottom row are the extremes of the first row.



So my plan for the keyboard just filled the entire keypad. But the xebow application supports layers, so you can do some interesting stuff there. I considered doing a chorded keyboard but I'm terrible at them and decided on this as something I might actually use. There are plenty of cool things you can do with Layers if you want.

The Future

The folks in #nerves-keyboard (on the Elixir Slack) are hard at work figuring out a real mechanical keyboard schematic that should be a very cool thing to own and play with. Most of the conversation in there right now is about PCB's, CAD and hardware layout. They are a welcoming bunch. So enjoy :)

If this post was good, or has problems that need fixing, let me know at or @lawik on Twitter. If you want more of my writing I have a non-tracking newsletter which tends to cover quality and sustainability in software.

Underjord is a 4 people team doing Elixir consulting and contract work. If you like the writing you should really try the code. See our services for more information.

Note: Or try the videos on the YouTube channel.