Page content

For the past year and a bit, I have been designing and builging my own keyboard. The current iteration, the proto3, is my daily driver, and I like it enough that I bring it with me when I travel. It supports several input modes, that are in different states of completion:

  • QWERTY: This is the closest layout to a traditional desktop keyboard. The next post will summarize how I fit a fairly standard QWERTY keyboard into just 42 keys, while still being able to type nearly everything I could on a regular keyboard.
  • Steno: This is a strict chord keyboard (multiple keys are pressed together and released) built around 23 keys (plus two extra in my design). On the proto3, this uses the top two rows, and the thumb keys. The lower finger row is treated entirely as the number bar, except that it isn’t in the right place, and ends up not being particularly useful. Instead, I use what are affectioniately known as “thumber” keys–the keys to the outside of the traditional vowel keys. My theory, Phoenix, does not require the number bar, so this works out. I have started incorporating number shifts into my shortcuts I use for programming language constructs.
  • Local Steno: Intended as the same use as the above steno mode, but instead of sending the raw strokes over a special protocol on an CDC/ACM USB endpoint, the dictionary lookups and translations are done locally on the keyboard. This is incomplete. The dictionary lookup is implemented, but I need to work through all of the rules for stitching text together, while supporting an undo stroke.
  • Taipo: The last layout, and the subject of this post.

Taipo, is a slightly chorded keyboard. When I first looked at Taipo, it just looked like another variant of something like Artsey, but with use of two thumb keys making for less state, and no holding down of keys.

However, reading further, it becomes clear that there is one thing that sets Taipo apart: it is intended to be used with two hands.

One of the big disadvantages of chord-based letter-typing keyboards (as opposed to Steno, which each chord can write anywhere from a syllable to an entire phrase) is that all of the fingers generally have to be lifted entirely between characters. With a traditional layout, such as QWERTY, it is possible to press the next key before releasing the previous one. This is called rollover, and is important to be able to type at any reasonable pace. With the chord keyboard, since there are fewer keys, and sometimes more than one pressed at a time, there is much less opportunity to roll over to the next key.

How Taipo handles this is to make the two halves of the keyboard entirely symmetric. The presses are exactly the same between the two sides (unlike Artsey, which changes a few navigation things), and the intention is to alternate between the hands for every stroke.

Learning Taipo

To learn taipo, I started by making my own drills. I started with a small number of letters, and used a little bit of python to pull words out of a wordlist that only used those letters.

At first, the alternating was rather alien. I had to say “left, right, left, right” out loud while I was typing in order to keep track of which hand I was supposed to use. I repeated each exercise, starting with the other hand so that I would begin to get used to this alternating.

It didn’t take too long to be able to do all of the 8 single-key letters (plus space), and I was going at about 10 WPM. As I started to introduce the rest of the letters, the focus became more on the actual fingering, as the hand alternating had started to become automatic. I finished the alphabet, and was able to pass at about 10 WPM on monkeytype.

But, learning was going real slowly. I had a lot of hesitation when typing, and the single letters that were in different positions than they are in QWERTY or steno (only the letter A, on the left hand is in the same place as QWERTY), were frequently coming out with the wrong key.

So, I created a new account with typing.com. I took their placement test, which decided I had learned all of the letters, but I was slow with uppercase letters (which are the same as the letters, but with a thumb key pressed at the same time). After getting through the uppercase letters, I started realizing that my speed wasn’t improving, and the same hesitations were there.

So, I went back to the beginning, and went through all of the typing.com lessons. There were a few I had to just do in QWERTY mode, because they required holding down a key with one hand and typing with the other. This doesn’t really make any sense with Taipo, anyway, so I just wanted to get past it. After completing all of those lessons, I was up to about 15 WPM, and felt a lot less hesitation.

Next was to try keybr.com which is supposed to be good at focusin on problem keys. I set the initial speed fairly low, 15 WPM, and let it take me through everything, and managed to get my speed up to about 20 WPM. I have found that as long as “Unlock a key only when previous keys are also above the target speed), it seems to work to bump the speed up by about 5 WPM. Less than that, and it doesn’t lock the keys to hone the focus. As of this writing, I am currently working through the keys at 35 WPM.

Implementing Taipo

Because my keyboards run my own firmware, I needed to implement Taipo myself. The implementation is fairly straightforward and contained in one file. There are a few quirks about how I went about this:

  • The one shot modifier keys currently don’t send anything until the key being modified is sent. I’ve not ever run the author’s implementation, so I don’t know how that is handled.
  • I haven’t implemented function keys yet. This is not too difficult, and basically done as a number prefix.

I would like to change the modifiers so that the send the “down” event when they are pressed. But including a “null” key that doesn’t do anything, but will release any pressed modifiers, I should be able to do things like “press the Windows key”, or “press Control, and click”. Once this, and the function keys, are implemented, I believe this layout could be a complete replacement for QWERTY. In fact, in some ways it is a bit easier, since it can be used entirly with one hand, if needed, it is useful for driving applications that are heavily mouse based.

One other quirk I had to add was for the shifted letter keys. I originally just send a single HID event containing the character, with the modifier pressed together. For some reason, though, this bothers typing.com, and I had to send the modifier separately, with a long enough delay to cause it to always end up as a separate HID event. I will probably remove this (or make it a feature), because it is kind of silly for anything else that doesn’t care if the shift is pressed separately.


Overall, I do like the layout. But, I have roughly 45 years of experience with QWERTY, and getting close to that speed will take a while, if I ever get there. But, with Steno, I don’t really need to get up to full speed, as the Taipo is more for typing things that are less English oriented (although I may write up a post about writing code in Steno). My main goal is to get comfortable enough with Taipo (as well as Steno) that I don’t feel like I’m spending a lot of thought effort on the typing itself. At some point, I will need to decide that Taipo is at a point where I can go “cold turkey” with QWERTY (at least for a bit, I don’t want to forget how to be fast there). As part of this, I’m revising my 30 key keyboard, which only has two rows, and doesn’t do a practical QWERTY mode. This keyboard is fine for Steno and Taipo.