A hot-key, shortcut, or macro keyboard built with an Arduino Pro Micro. This macro pad has as many features as it does mistakes during the design process. There are three popular boards with that microcontroller: Arduino Leonardo, Teensy 2.0, and Pro Micro (not to be confused with Pro Mini, which uses ATmega328). Arduino Leonardo is too big for our needs. Teensy 2.0 is quite expensive. Pro Micro can be had for about $4 in.
I’m a self-confessed keyboard nerd and got a hold of this keyboard for the keycaps off of a friend. Initially I’d thought they would be cherry compatible, but unfortunately, they are not. So rather than butchering a perfectly good keyboard, I wanted to make it USB compatible. Please bear with me, this is the first time I’ve done any projects interfacing with unknown hardware, or even with an Arduino.
Here’s the GitHub repository for the current code, and all the circuit diagrams I could find. There are a few issues with the layouts of each of those, however:
The ATmega32U4 was chosen for a few reasons:
These were collected online from various sources, the first of two contains more information, the second is more basic and easier to understand at a glance.
Note that the rows are organised differently in the two diagrams and there is some disagreement between the locations of “I” and “9”.
The keyboard has some integrated logic on board, but as a basic breakdown a few things happen (as if it was still in the main box):
There is one exception, which is the break key that is a directly wired switch, that avoids the logic designed to perform soft/hard resets of the BBC micro.
There is a more detailed explanation of the whole system and keyboard available here.
BBC Pin | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Function | Ground | Break | Clock | Row A | Row B | Row C | Col A | Col B | Col C | Col D | W | LED0 | CA2 | +5v | LED1 | LED2 |
Arduino Pin | GND | A3 | 9 | 6 | 7 | 8 | 5 | 4 | 3 | 2 | A1 | 16 | 10 | VCC | 14 | 15 |
Pin mappings for the BBC are from the top left to right, with the keyboard face up with the pins facing away.
So there are a few things we need to do here; generate a clock, listen for a keypress, scan the keyboard matrix, find out when we have the right combination of rol and col, and finally convert the (row, col) value to the correct character.
First thing’s first, supply the keyboard with ~5v from the VCC pin and generate a 1MHz clock on pin 9.
Put simply, this enables the fast PWM mode on pin 9 for a 1MHz signal, further details can be found in section 14.8.3 of the ATMega manual.
The LEDs on the main motherboard are already powered and need to be connected to ground to get to work. Setting the LED pins to output mode, and using the digitalWrite function to turn them on (LOW) and off (HIGH). Currently, the LEDs are mapped in the code to display keypress events and when the correct key has been found from scanning the rows and columns.
Early on, it became clear that the digital read mode on the Arduino would not be suitable as it uses a +5v signal for high, where the keyboard was returning +1.8-2.2v for high. So to compensate, an auto-adjusting sensor for each of the input pins using the analogue input.
Each input pin was set to an AnalogInput mode and checked every cycle. The low value was stored as it would drift. To ignore the drifting and nose on the pin, a threshold was added to ensure the readings for high were not false positives.
Once a keypress event is detected by a ‘high’ on CA2, KB EN is set to pause the scan high and start searching the matrix.This is done is by counting in binary across the logic chips e.g. 0 = 000, 1 = 001,… 4 = 100.
To encode this information, set the lines you want to count with to digitalWrite(high) and then check to see if W has gone high, indicating that you have found the correct row & col value.
Arduino has a great (but limited) keyboard library, that I’ve used here to turn the device into a USB keyboard.
It allows the device to send ASCII characters in the same way a keyboard would. It can be sent as a quoted character, ASCII binary, base 10 or hexadecimal.
The next step is to map out the keyboard matrix into numerical matrices with the ASCII characters for three states: lower case, upper case and shifted. Once we have the correct mappings for these, they are converted to the integer values in ASCII using this very helpful tool.
The negative numbers are not valid ASCII characters and are used to represent special cases:
In order to get the key mapping to work, it is necessary to not send the data about the state of the shift key. This is done as I found that assumptions are made about the key mapping (at least on Linux), so “Shift + 3” is the “£” key on a UK layout, however, on the BBC KB this is the “#” character, so sending “Shift + 3” would print the “£” character. Ranger boat ignition switch manual.
So send “#” and problem solved, right? Well, no. Even though the correct ASCII code for “#” would be sent, as the shift key would also be held, the assumption is that it should be remapped this to the shifted version on a UK keyboard which is “~”.
So in order to send the correct characters, I had to withhold the shift status and store it locally on the Arduino to modify the keypress.
After scouring over the circuit diagrams, I had assumed that the layout of the rows and columns would be in a logical order. However, after a long and frustrating time, it appears that the layout of the rows does not follow my assumed logical mapping. Spyrix keylogger for mac. After looking at it, this is clearly done to keep the trace layouts simple and efficient. (However, be wrong and just have some wires crossed.) The row order that works for me is :
Decimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Expected | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
Actual | 000 | 011 | 101 | 001 | 110 | 010 | 100 | 111 |
Currently, my ‘Shift’ and ‘Ctrl’ buttons are not working. Unfortunately, it looks like the whole row of keys is out of commission. I’ll get back to this where I have more time, the rest of the row should be a row of selector switches, but this isn’t included on this keyboard model.
There are quite a few keys on this keyboard that are not in use anymore:
The break key is an interesting one and is wired independently to the keyboard. It is intended to be used to warm or cold restart the machine. I’m currently thinking I should map this and the ‘Copy’ key to “Ctrl + c”.
Shift lock has been implemented, by storing the value on the Arduino and passing the appropriate shifted ASCII code. F0 has been mapped to F10.
Now why didn’t we think of this? While building a dactyl manuform — a semi-ergonomic split keyboard — [dapperrogue] had the life-changing epiphany that keyboards can be any shape or size, as long as there is room for wiring and a microcontroller inside. Free adobe software for mac. [dapperrogue]’s first foray into the world of fictional ordnance came in the form of an F-bomb — a round macro keeb made in the classic round explosive shape and covered with function keys. Building on the explosive feedback from that, [dapperrogue] built this bomb of a pineapple keeb, the only anti-personnel factor being the clickiness of the key switches.
This groovy grenade has 25 keys total, 24 of which are in a 4×6 grid around the body. The 25th key, the best one, is hiding under the lever and you bet it can only be actuated by pulling the pin first. We love the use of the lever because it makes us think of Morse code keyers, which might be what we would use that switch for.
Inside is an Arduino Pro Micro running QMK and some skillful wiring. The entirely 3D-printed enclosure is in two main pieces that are connected with M3 screws, plus the top. If you want to pack one of your own, the STLs and firmware are out on GitHub. Just don’t take it to the airport.
Be sure to check out the demos after the break — in the stock firmware, every key types out a different onomatopoeic boom-type sound. Are you more of a pacifist when it comes to macro pad design? That’s understandable. We have plenty of different builds to admire.