Experimental thumb keyboard, suitable for a hand held device
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
I'm working on a new method for producing the labels. The existing system (mis)uses a spreadsheet, but I would like something better.
The new method uses a Python program with the Python Image Library (PIL) to create a bitmap image of the labels. The required layout will be defined in a separate file that the program will process. The resulting bitmap can then be
So far I've hit a couple of snags. The first one is that despite the resulting bitmap having a DPI setting to indicate what size it should be printed at, many programs that print bitmaps "helpfully" scale it to fit the page, even when I think I've turned off all the "scale to fit page" options. I've found that GIMP will print at the correct size as long as I don't print preview first.
I can't control what software will be used to print the bitmap, so I've added a couple of scales, one in centimetres and one in inches, so at least you can check if it's printed correctly.
The second snag is that fonts in PIL are not anti-aliased, reducing the print quality. Producing the bitmap at a higher resolution should work around this.
This is not finished yet but when it is I'll compare it with the old method to see if it's worth switching.
I've updated the base library at https://dboucher.org.uk/keyboard/Thumb_Keyboard.zip to the current Arduino and PlatformIO standards, so you can now install it in Arduino using the "Add .ZIP Library" option or in PlatformIO using:
platformio lib install https://dboucher.org.uk/keyboard/Thumb_Keyboard.zip
My next task is to do the same for the 23017 version of the library and move the key label and 3D printed part files into the "extras" directory of the base library to finish tidying things up.
EDIT: All done.
After I uploaded the last version, I realised that I had forgotten something in the event reporting: raw key numbers. These give the position of the key regardless of what that key is mapped to. For example, key 15 might be a "y" in an English layout or a "z" in a German one. As this can be useful in some applications I have added it to the library.
Keys are numbered left to right, top to bottom, with the top left key being zero. As usual, the downloads can be found at https://dboucher.org.uk/keyboard/.
As promised, I've updated the main download and you can get the new version here. This contains the Arduino libraries from the last update, the improved label spreadsheet and the new keyboard back panel as shown below:
This is the same as the previous version, just with new labels and the back panel. I also removed a row of holes from the bottom and sides of the perfboard as they were surplus to requirements.
The case back slides up and over the sides of the bezel and the end result is a nice tight fit.
This update has been delayed a little due to other commitments, but I've finally finished converting the keyboard scanning software into Arduino libraries. There are currently two versions: the base version is for use when connecting the keyboard via GPIO pins (download link) and there is a second version for connecting via an MCP23017 I/O expander chip (download link).
Both versions come with an example program which will appear in the Arduino IDE's examples menu when the library is installed. The base version has no dependencies but the 23017 version depends on both the base version and the Adafruit 23017 library, which you can install from the library manager.
My next task is to update the main download (the one with the software, labels and 3D models). Hopefully, that won't be delayed as much as this update!
There are currently two versions of the software in the download: one that connects to the keyboard directly via GPIO pins and targets an Arduino Uno, and one that connects via an MCP23017 I/O expander and targets an ESP8622 board. Both versions take the form of a single source code file.
To make things more flexible, I'm in the process of converting the software to a set of Arduino libraries. There will be one library for the hardware independent code and libraries for each interfacing method (direct GPIO, I/O expender, whatever else).
Once I have converted the code, the steps needed to use it will be as follows:
I've also finished tweaking the layout spreadsheet, at least for now, however I've not uploaded the new version yet. I'll add that update when I've finished the software changes.
Currently working on improving the labels.
Here is what I've found so far:
This is never going to be a mass produced product but I would like assembly to be as simple as possible, so I'm going to keep working on this until I have a good system.
I've improved the key label spreadsheet (LibreOffice) so that you can just enter what you want to appear on each label, run a couple of macros, and get a page of labels ready to print.
You set the number of rows and columns that you want, the colours that you want to use and what you would like to see for the unmodified key plus the two modifier states. Press the "Create Key Label" button and a macro will construct each label in the "Key Label" column. If you don't like how any of the have turned out, put what you would like to see in the "Override" column and press "Create Key Label" again and the value from the "Override" column will be used. Finally press "Create Label Page" and a page of labels, repeated as many times as will fit on the page, will be produced in the "Labels" sheet ready for printing.
There is more information in the "Instructions" sheet. I've updated the download and you can get the new version here.
As promised, I've uploaded the ESP8266 version here. You will need an MCP23071 I/O expander chip for this one (see previous log).
Although the version in the archive targets an Adafruit Huzzah ESP8266 board specifically, the target can easily be changed to another ESP8266 board or anything that has an I2C bus and a PlatformIO target.
As some point I'll convert the software to an Arduino library. As there are multiple ways to interface to the hardware (GPIO pins, I/O expander chip), I think I'll need to need to split the code across two libraries in the same way that the Adafruit TFT libraries work: a low level library that accesses the hardware and a high level one for the keyboard handling code that's independent of the hardware access method. This is something for later though.
My keyboard needs one GPIO pin for each row and column, so for a 10x4 layout that's 14 GPIOs. Most Arduino style boards can accommodate this, but it takes up most of the pins. Other types of board, such as ESP8266 and Raspberry PI, don't have nearly enough pins though. What to do? Use an IO expander chip of course! These types of chip provide a number of GPIO pins that the host accesses via a serial protocol, usually I2C or SPI. This means that the host only needs to support the relevant serial protocol which generally only requires 2-5 pins. You could also run other devices off the same serial bus without using any more pins.
Here I am using an MCP23017 IO Expander chip with a Teensy LC. The only other components needed are two 4.7KOhm resistors to pull up the signals on the I2C bus. I'll document this properly another time, but you can see from the picture above I'm only using a small number of pins on the Teensy, leaving most of them free for other things. Only minor changes are needed to the software, Adafruit produce a library for the 23017 which provides equivalents to the standard Arduino digitalRead()/digitalWrite().
The 23017 has 16 GPIOs, which means that I have two spare here which I could you to add more rows or columns. The chip also has three address pins which can be pulled high or low allowing for a up to eight chips on one I2C bus, giving a total of 128 GPIOs, more than enough for any thumb keyboard.
I'll release the software soon, including a version for ESP8266.
Create an account to leave a comment. Already have an account? Log In.
Okay, I'd missed that USB HID was a requirement. I don't think it's possible to get USB HID out of a 328 and it wasn't needed for what I was doing. If you need that then a PI Pico or a Teensy should work. I did port the keyboard code to the Pico at one point but that doesn't include USB HID. If you're interested, I can look for it and upload it somewhere. The Pico's SDK examples include a USB keyboard demo I believe.
EDIT: I've uploaded the Pico code, see my other reply below.
I mean the pico is selling for way less atm, so I might go for that one, and don’t worry I should have thought of that before I made a version with the nano. I might try seeing if I can get V-USB working, but assuming that doesn’t work, pico does seem like my best option, so I’d really appreciate seeing the port, but only if it doesn’t take too much time.
thanks again for all this, your logs are amazing enough on their own, and this level of support on top has been so helpful
Replying to this post as it's not possible to reply to a reply here (or I've missed something). Anyway, here is the Pico version of the keyboard code with a very quick thrown together demo: https://dboucher.org.uk/keyboard/pico_thumb_keyboard.zip
The demo has had very minimal testing, so beware. Basically, I ran it once and shorted pins on the Pico together in lieu of a keyboard.
hey it’s me again, I actually managed to get this working, do you know if the arduino nano every would work with this? I’ve only managed to get this working on the uno so far
Hello again and congratulations on getting it to work! Regarding the Nano, It should work fine as it's based on the same chip as the Uno (ATMega328).
Yeah I can confirm now that this one works
https://www.amazon.co.uk/dp/B092SW8T2J?ref=ppx_pop_mob_ap_share
Which is handy given the rise in price of teensy lcs and the size of the uno. (Also obviously misses out the circuitry on the mcp23017/esp8266)
My project is designed to fit underneath a blackberry priv keymat, which is designed to be backlit and have a trackpad. Theoretically the trackpad is going to be plug and play with a USB capacitive touch foil, but I’m going to try running the LEDs out of the spare GPIOs with a hard switch, so if I get that working on the prototype, I’ll provided the modified version of the software (your program runs beautifully, but I used two buttons for the space bar, so I’ve had to only check that once per frame, and I haven’t gotten to the LED circuitry yet, but I imagine I’ll need to do something to the extra pins in code)
I've been following along, but I'm not getting any output at all. Part of me is chalking it up to shorting the keyboard (so I'll check through later with a multimeter), but can I check which pins on the MCP23017 should be connected to which pins on an ESP8266? I'm using a D1 mini, so for now, my pins are hooked up:
3V3 to Vdd
GND to Vss
D8 to SDA
D7 to SCK
I'm using 4.7k ohm resistors on the data lines
Sorry, I can't find my original notes on this, but I've looked up a pinout on the D1 mini and that shows SCL on D1 and SDA on D2. I think you might have it connected to the SPI lines instead of the I2C lines.
yeah that sounds about right, thanks! Also, while I'm here, your logs have been a godsend for the project I'm on so thank you so much.
As for the device (my version of it), I'm not ruling out a short somewhere, so I'm going to wait until my super advanced debugging equipment arrives tomorrow (multimeter, pack of LEDs and a battery holder), because as it is, I've intentionally shorted two buttons together to fit under the space bar of the overlay I have, and the solder itself is not pretty, and I'm convinced I fried the first D1, and I only have 1 more in right now. I'll update back and let you know if that works though
Upon applying my super advanced debugging techniques, I can safely say that some idiot soldered the entire bottom row among other keys (the one with the intentional short on mind you) incorrectly. Will attempt round 2 when I have the energy and the additional parts
The printed bezel is an excellent solution! Exactly the kind of thing I was looking for but could not find anywhere else. As far as anti-aliasing goes, you might be able to get around that by using monochromatic bitmaps, which I think has its own file type.
Interesting device. Let me share this with our team at https://www.queensnycconcrete.com, I'll let you know if they liked it as well.
I'm working on something similar. Your key label system is really well done!
I'm thinking of using a specialized keyboard breakout like the ADP5588 instead of a generic GPIO breakout. Did you explore that option?
I'd not thought about the ADP5588, but it would be a good thing to add. Thanks for pointing it out.
I've had good luck with the TCA8418 so far. Seems like there's support for it in the Linux kernel too so it may be usable on the raspberry pi. These folks got it working: https://hackaday.io/project/5081-malti/log/17068-it-lives
See how this feels before thinking about using staggered rows. Staggered rows were introduced in typewriters originally so that the typebar mechanisms would be spaced at a regular interval. This is completely unnecessary with electronic keyboards, but still the tradition lives on.
I agree that staggered rows are not necessary here, but some people might want them as an aesthetic feature. If I add them it will be as an optional element of the design.
Staggered rows are not strictly aesthetic; they help the typist locate their fingers without looking at the keyboard, they do, however, use more space.
What You think abot this? http://klawiatura.wordpress.com/
Is possible add 2 rotor for sound/volume ,obj 3d manipulation etc. Second trouble are different size of keys.
Interesting article, thank you. The aim seems to be the same as mine, but with a different approach: instead of customising the keyboard, make one keyboard that works for any language. The problem with that approach is even if you make all the necessary character available, every language has a different preferred layout. English speakers want QWERTY, French AZERTY, German QWERTZ and so on.
Second answer: you can add whatever you like to the keyboard, rotors, LEDs, whatever, the design is meant to be flexible. As you say though, different sized keys would be difficult.
The problem is not the layout of the keys, this one can be changed programmatically, but their number.
Unfortunately, for example, the French have a lot of national characters and the Spanish characters are diacratic.On the website you have other layouts, eg adapted to laptops, which are wider in height.
In my opinion, give people a chance for a universal keyboard, and the software will do it themselves.
Rotors are usefull for input analog dataBecome a member to follow this project and never miss any updates
wouldn’t you believe it, I’m back! How did you solve the atmega328 not being able to be used as an HID device issue? I’m considering installing V-USB, but idk what’s gonna work or not