A First Foray Into DIY Keyboards
Why Make a Keyboard
I recently graduated from CMU's School of Computer Science, and while I was walking the stage accepting my diploma
it occured to me, "I don't know how a computer works." Don't get me wrong, CMU's CS curriculum is top notch,
but, largely because of my own choices in classes (which I wouldn't change), I have a degree in theoretical math boxes.
Don't get me wrong, I am perfectly comfortable with low level programming, but once we get below an OS, I have
very little idea how electronics work. So, I decided to take the summer to learn about more about this.
Simultaneously, I attended Keycon 2025, the premier Keyboard convention.
There, Joe Scotto gave a talk on the process of hand-wiring
keyboards and I was immediately hooked. I've had a vague interest in mechanical keyboards for a while and I saw
and opportunity to learn a bit more about electronics by building my own, completely from scratch. However,
I have never soldered before, never done embedded programming, and have very little 3D modeling experience. What
could possibly go wrong?
The Idea
It seems like a classic first project is a 3x3 macropad, but honestly, that seems a bit boring to me. I don't think
I would ever use it, and, if I'm going to do a project I have no use for, I'd like it to be at least entertaining.
Enter the Keybyte, a keyboard where you type one byte at a time. More specifically, my idea was to have a keyboard
with 9 keys in a row. The first 8 correspond to the bits of the byte you want to type, and the last is an "enter"
key which confirms the byte you are pressing. For example, to type an "A", which is 65 in ascii, you would need to
type the second and eight key (corresponding to the least significant and second most significant bits) and then
press "enter."
It's kind of like if the Stenotype Machine was comically
inefficient.
The 3d Model
Of course, any good keyboard needs a case. Unfortunately, they don't sell cases for keyboards this brilliant,
so I would have to design it myself.
I hadn't done any 3D modeling since highschool, but it was shockingly easy to get back into. I used onshape as
my modeling software and had a decent prototype modeled and printed in only a couple of hours. Honestly, the hardest
part was finding the dimensions of the MX switches I was going to use.
The Microchip
The first thing I had to learn about for this project was microchips.
I debated going with an arduino or raspberry pi, but I didn't like the fact that they used microUSB instead of USB C.
I know I could solder on a USB C breakout board, but that seemed like a lot of work. After doing some research, I
settled on the Sparkfun Pro Micro with an Atmega32U4 processor. In retrospect, I should've gone with a board with
and RP2040 so I could use the Raspberry Pi Pico SDK,
but I'll keep that in mind for the future. Having picked out a microchip, I had to face my biggest concern
for this project. Soldering.
Learning to Solder
A common theme I saw reading blog posts and watching videos about DIY is "how easy it is to solder." In my
experience, that could not have been further from the truth. I had about a million "bugs" due to poor connections,
especially between the pins of the switches and my copper wire. But, after spending several hours soldering and
re-soldering, I was able to get it to work! It should be noted that like any skill, you improve over time and I
definitely noticed my solder joints had improved by the end of the day.
Writing the Software
Finally something I'm good at! To be honest, I really wanted to write the software for this project in C,
but given the Atmega32U4, I decided to just use Arduino and be a bit sad about it. Truthfully, either way the code
is super simple, it's not like I was going to write the USB stack from scratch... for now. The only difference is
whether I would be using Arduino's Keyboard library or TinyUSB.
Writing the software was super simple, at least, given my experience programming for the past decade. The
entire thing is basically just:
if (pressed(PIN_ENTER)) {
char byte = 0;
for i in PINS.length {
if (pressed(PINS[i])) {
byte |= 1 << i;
}
}
Keyboard.write(byte);
}
Results
And that's it! With a WPM of approximately 0, here is the keybyte: