I have a friend, Josh. Josh is a literal superhero. He’s a boring, minivan-driving programmer by day, paramedic and firefighter by night. That’s already a much more plausible superhero premise than Batman (a billionaire who spends his time fighting street-level crime? Really, Bruce? Is that the best use of your time and billions?).
Josh showed me some notes he had taken while he was paramedicking his paramedic things. I say “showed”, it was more “asked me if I could make out what the hell the notes said”.
I could not.
The conversation then went like this:
- Why don't you type on a computer?
- A computer is generally hard to set up in the field, and you need to keep eye contact with the patient, so handwriting is more convenient.
- Why not have a special keyboard?
- I don't think that's very con
- It can be wireless, and one-handed!
- Yeah but still, how am
- It can have five keys, one for each finger, and you can chord combinations to type!
- That sounds slow and
- JOSH THIS IS HAPPENING STOP FIGHTING IT
After his outpour of encouragement, I was motivated to create a solution, no matter how hard. I had a rough idea in my mind, but it was going to be tough oh who am I kidding, it’s five buttons connected to a microcontroller, it would take two minutes.
It took four hours. Close enough.
As I said, the hardware is simple enough: Just a microcontroller and five keyboard switches wired to five of its input pins. Since this build needed to be Bluetooth-enabled, my microcontroller of choice here was the ESP32. It’s a bit of a power hog because it implements all the required protocols (both WiFi and Bluetooth) in software, but for such a small project it would be good enough.
The ESP32 is going to be on and running continuously, and not sleeping between keystrokes, because I’m too lazy to figure out how to make the ESP32 keep the Bluetooth connection open while sleeping. That means the battery (a 1S 250mAh LiPo) is only good for 2-3 hours, but that’s 2-3 hours more than anyone will ever use this for, so it’s more than enough.
For the case, I designed a very simple square prism with five holes where the switches should be. In retrospect, I should have measured the distance between my fingers rather than the distance between the switches, because now the case feels a bit small, but that lack of smarts is why I am poor and writing a blog post on a Monday morning.
Getting the ESP32 to emulate a Bluetooth keyboard took less than a minute, as there is an excellent library for that. All I had to do was call an initialization function and then send keystrokes whenever I wanted to, and that was it.
Then, the only thing that was left was the meat of the project: How can we use five switches to type the entire alphabet, plus some keys like space, backspace, etc? Obviously, if we only press one switch at a time, we can only type up to five letters, but what if we press multiple switches at once, to produce one character? Then we can type up to 25 = 31 characters (actually 32, but pressing nothing is a no-op), which is more than however many letters the English language has nowadays, including the accents and umlauts.
With that decided, we there are two issues to solve:
- How do we know which switches were pressed? The microcontroller is fast enough to read the switches every microsecond, and it’s impossible for a human to activate all switches at exactly the same time.
- How do we decide which character each switch combination will produce?
Pressing multiple keys together
To figure out which switches were pressed for a key, we’ll need to somehow wait until all the switches that the user intends to press have been pressed, and only then generate the character. This is different from normal keyboards, which generate a character as soon as you press the switch, and can keep generating it (on repeat) for as long as the switch is pressed.
We can achieve this by starting to keep track of presses when one switch is pressed, and waiting until that switch is released. We can also wait until the last switch is released, in practice there’s no difference between the two approaches. While we’re keeping track of key presses, we can store the most switches were pressed at one time (and which ones they were), and output the character for that combination when they’re all released. We could also keep track of which switches have been pressed until they are all released, but that would be less “natural”, since the switches could be pressed out-of-sequence and still work.
As you can see, there are many ways to peel this particular cat, and the particular method chosen doesn’t matter too much, as they all produce similar (and satisfactory) results. Now that that’s done, we can move on to the next (and bigger) problem.
The character map
Deciding which key presses would correspond to which characters was the hardest part, but also the most creative. Since this is a brand-new keyboard layout, I would not be beholden to the mistakes of the past. No more jamming typewriters for me, no more bigrams, I would have free rein to perform extensive research and decide what the optimal correspondence would be for my layout.
I decided that that was too much work, and that I’d just fall back to the good old etaoin shrdlu. I found the character frequencies in the English language, and made sure that each of the five most frequently used characters (the spacebar, “e”, “t”, etc) had its own key. After that, the next most frequent characters got a double press (the thumb plus one of the four others). Then came double presses between the other keys, then triple presses, etc.
The final layout can be seen here, though it’s not very straightforward because the keys are read in a binary pattern. In essence, each key is a single bit, with the full press being a 5-bit number, so the thumb key corresponds to 1, the index key to 2, all keys together to 31, and so on.
As you can see, the entire source code is barely 100 lines long.
Shortly after uploading the code to the keyboard, I paired it with my mobile and started typing. It actually felt quite nice to type in, because my hand was in a perfectly natural position with a pleasingly hefty object in it, so I spent quite a bit of time typing.
It’s pretty slow to type in, as each character needs multiple presses, so the slow speed is largely due to my unfamiliarity with the keyboard. I’m sure there’s lots of room for improvement as I get used to it, which I won’t, because I have no use for it at all, and it was just a fun experiment for me.
After popular demand, here’s a video of me struggling to type with it:
If anyone wants it, you can own an ORIGINAL STAVROS PROJECT if you pay for shipping (I’ll even sign it with my chicken scrawl) because it’s gathering dust in a drawer right now. Also, I may be too lazy to even ship it by the time you read this, so don’t get too excited, but if you can make it easy for me and come by my house I’ll definitely give it to you. Or you can make your entirely own keyyyyyyyys keyboard, which is way more rewarding in that you don’t have to deal with me!
You can find the code here:
Let me know what you think by tweeting or tooting at me, or emailing me directly!