05/03/2019 at 19:11 •
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:
- Add the relevant hardware specific library to your project. Ideally, I would like this to automatically add the hardware independent one too, but if that's not achievable it will need to be manually added.
- Define the keyboard configuration in your code. This is the number of rows and columns, the pins to use for each row and column, and the key mappings and the timings for polling, debouncing and key repeat.
- Call the initialisation function, passing your configuration, to set everything up.
- Call functions to update the keyboard state and read key events as needed.
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.
04/18/2019 at 21:56 •
Currently working on improving the labels.
Here is what I've found so far:
- Printing on glossy paper - I've found that the print smudges very easily if I use glossy paper, even if I leave it to dry for a while. Maybe I'm using the wrong paper? It's marked for use with inkjet printers but you never know. Using sticky tape (Sellotape or other brand, you probably know what I mean) on the labels gets around the smudging problem but the overall effect doesn't look any better to me, so I've gone back to plain copier paper for now.
- Some of the smaller punctuation symbols like "." and "," didn't come out clearly, changing the colour and font has fixed this one.
- Centring each key label requires a bit of manual tweaking in the label spreadsheet with the "override" column. I'm not sure that is a better way to do this with LibreOffice Calc macros, so I might have to rethink my approach here and use something like PyFPDF to create the labels instead.
- The label border was sometimes visible when the label was fitted into the bezel, so I've replaced the border with crop marks at each corner of the label.
- The labels need to be cut very accurately. Having multiple copies of each label on a page has turned out to be very useful.
- The length of the overhangs at each end of the label needed to be tweaked slightly. The label was slightly too short which was making alignment tricky. I've adjusted this but I think it still needs a bit more fine tuning.
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.
04/11/2019 at 19:39 •
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.
04/04/2019 at 21:21 •
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.
03/30/2019 at 20:31 •
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.
03/27/2019 at 21:57 •
Seeing as this has brought some more attention to the project I thought it would be a good time to explain where I want to take this next. I'm fairly happy with the prototype that I've built and I don't think that there are any serious flaws that need to be addressed. There are some minor tweaks though:
- Change the colours for the alternative functions on the keyboard labels. Some characters like the full stop and comma are hard to distinguish and I think darker colours would improve the contrast and help here. I'm also going to try printing the labels on glossy photo paper to see if that helps.
- The bars that hold the keyboard labels in place need to be slightly thicker for a more secure fit. A very minor change.
- Change the software so that it uses the more generic terms "modifier 1" and "modifier 2" instead of "shift" and "symbol".
Those things are just tweaks though and don't really add anything new to the design, so here are the REAL improvements that I plan to make:
- Add a version of the software that works with an IO expander chip so that the keyboard can be used with devices that aren't so well endowed with GPIOs, such as ESP8266 and Raspberry PI. This is actually written and will probably be the subject of the next log.
- A proper event queue callback and functions to poll the keyboard state.
- Allow for character sets other than 7 bit ASCII.
- Turn the software into a library.
- Fully parametrise the key label spreadsheet, include cutting instructions on the sheet itself with a guide to check that it has been printed at the correct size and print each label strip multiple times to make best use of the paper and allow for cutting mistakes.
- Fully parametrise the OpenSCAD code for the bezel, and include options to properly secure the bezel to the circuit board, including a full wrap around case.
- Write proper assembly instructions.
And a few things that are more long term:
- Allow for offset rows on the bezel, so the rows are slightly staggered like you get on most keyboards.
- Add support to allow modifiers to be toggled on or off with a press instead of needing to be held. This would be useful for single handed operation.
- Add support for external control of modifiers through, for example, a three position switch. This could allow for more more than two modifiers.
- Build some sort of central configurator, where you entry your keyboard layout once and it produces all the design files and source code.
I think that should be enough for now.
03/26/2019 at 20:34 •
This is the last of these logs covering my first prototype and I'll be talking about the 3D printed front cover.
The most important function of the front cover is to hold the key labels, which are paper strips that go above each row of keys (see previous log). There are four rows of holes to accommodate the switches and above each row is another row of smaller holes to accommodate the labels. The label is slotted in from the back of the cover and a plastic bar (also 3D printed) holds it in place. Here is a picture of the back to help make things clearer. I've removed one of the bars that hold the labels in.
The parts were designed on OpenSCAD, which, for those of you that don't know it, is a tool that allows 3D models to be defined programmatically. The output is an STL file which can then be sliced and printed or incorporated into a larger part such as a complete case.
One of my aims with this project is to make the keyboard layout fully parametric. The current design allows the number of rows and columns to be changed but I would like to add more flexibility in future, such as allowing offset key rows or taller row labels.
The OpenSCAD files can be downloaded here. PLEASE NOTE: I have reorganised the downloads so that everything is in one archive. This one also contains the software and the key label spreadsheet covered in the previous logs.
03/21/2019 at 22:14 •
Unless you have a very good memory, it's useful for the keys on a keyboard to be labelled in some way. The usual way that this is done on a professionally produced keyboard is by printing or laser etching on to the keycap, but these methods are out of my reach and in any case, I'm not using keycaps, just the bare switches. What I have done is put the key marking just above the relevant key and this means that I can print a strip of markings for each row on a normal inkjet or laser printer.
I needed a good way to lay out these strips, so I tried a number of different graphics packages to see what worked best. I eventually found that the best graphic package for this was a spreadsheet.
Yes, that most abused piece of office productivity software is now a keyboard labelling tool in addition to being a database, project planner, form designer and all the other things that it gets used for.
Above is the spreadsheet in LibreOffice Calc. Each key is represented by a single cell and I'm using different colours to indicate the normal and modified key functions. The B and V columns are small overhangs to allow the strip to be positioned correctly in the 3D printed part. If you don't have access to a 3D printer, you could print these on to label paper and stick them directly on to the perfboard.
To get enough accuracy, I had to specify the cell sizes to be ten times their actual size and change the print setting to print at 10% size. When printed correctly, the strip should be 77mm long.
The spreadsheet is available for download. I also plan to do a more flexible version at some point where you enter the number of rows and columns and the marking for each key on one sheet and then run a macro which produces a second sheet which you print.
03/18/2019 at 22:52 •
I'm going to go over how I assembled the prototype starting with how everything is connected up on the perfboard. I've already covered some of this in the first "Keyboard Basics" log, so this is mainly a recap with some more details.
The perfboard is the standard single sided type with holes spaced at 2.54mm/0.1in. Each switch takes up three holes across and four down and the grid is 10x4, so this gives us 30x16 holes. However, I also want a two holes margin around the whole board which I'll eventually use to help hold the board in a case, so the total size is 34x20 holes.
The switches are also a common type sold as "6x6x4.5mm Panel PCB Momentary Tactile Push Button Switch 4 Pin DIP". These fit into the perfboard with the pins facing top and bottom as close as they will go leaving a two hole gap around each edge. It should look something like this. Ignore the blue tape and wires for now:
Then I flipped the board over and folded the left side (as we are looking at the back of the board) pins of each switch outward and the right side ones inward. I made sure that each switch is flush with the board when folding the pins. I used the 3D printed part (which I know I've not covered yet) to check the switches were correctly positioned.
Finally, I soldered the switches as per the picture below. An uninsulated copper wire carries each row connection across the board and the column connections are carried through the switches (as explained in the log I mentioned earlier). In the picture below, I've coloured the row connections blue and the columns ones yellow to make things easier to follow. The uncoloured pins are not connected to anything and are just holding the switch in place. The row and column connections have to be bridged over two pads, which is why the soldering is messy. Well, that and the fact that my soldering is messy anyway.
03/16/2019 at 14:41 •
As promised, I've put the keyboard scanning code covered in the last three logs online and you can download it from this page: https://dboucher.org.uk/keyboard.
Keyboard with Arduino UNO and paper pin insulator.
This version is set up for Arduino but it should work on anything Arduino compatible with enough GPIO pins. I've used it on a Teensy LC for example.
There is a README with more info in the download. I hope you find it useful.