For my computer engineering senior design project, I decided to make a keyboard, and now that I am graduated and have some time, I figure I'd share.
So for starters, I decided to go with 16x6 hand wired matrix (the 17th "column" was transposed into empty spots in other rows columns so there's a bit of funky wiring there"
While the hand-wired matrix is pretty standard fare for do-it-yourself-keyboards, I feel this project brings a number of new and interesting features to the table, including:
- 8MHz operation at 3.3V for reduced power consumption and better logic compatibility with the bluetooth module
- USB or battery powered with 1N5817 Diodes to prevent current flowing in the wrong direction
- Seamless switching between USB and Bluetooth via interrupts
- 74HC4514 and 74HC251 logic ICs for reduced IO pin usage (8 pins to control up to a 16x8 matrix)
Running the Teensy at 3.3V AND with battery power was a bit tricky as I had to separate VBUS and VCC, and then run VBUS through the onboard regulator of the Bluetooth module, and then run the 3.3v from the Bluetooth module back into the teensy's VCC. This was the only way i could think of to have USB and battery power, AND also run the teensy at 3.3V because I needed diodes on the battery and on the USB VBUS connection so I could switch between these sources without worrying about current flowing the wrong way.
Also, I made use of the USB connection transition interrupt to switch between communicating via bluetooth or USB whenever the USB cable is plugged or unplugged.
Anothing thing to expound upon was using some basic logic ICs to reduce IO pin usage for controlling the switch matrix. The big pin-saver was the 74HC4514 4 to 16 decoder which I used to drive all 16 columns using just 4 IO pins. I'm definitely going to be using this chip in future keyboard projects because it is easy to use and saves a ton of IO pins. I also used a 74HC251 3 to 8 mux for selecting which row I wanted to poll. This one did not result in as big of savings because I used 4 IO pins (three select lines, and mux output) to poll 6 rows. I decided to use it anyway because this allowed me to use 8 IO pins to scan which meant i could do all matrix-related stuff using a single IO port on the teensy.
All-in-all this was a really fun project, but there is still room for improvement. While the Adafruit EZ-key is a pretty nice bluetooth module to work with, I find that there were a few things that were really annoying to deal with. The first thing has to do with getting keyboard status indicator information. There's no way manually requesting that information and when the EZ-key does send status indicators it does so in the form of a relatively long ASCII string that needs to be parsed. Also, the EZ-key has no good way of putting the module to sleep, as using the reset pin takes about 3 seconds for the EZ-key to come back online. I've ordered a RN42HID which I am pretty sure is more configurable, so we will see how things go from there.
Anyway, I've uploaded my code as well as some sparse documentation to github:
https://github.com/Tranquilite0/hybrid-keyboard