Monday 22 June 2020

Context-sensitive macro keypad

I've been doing quite a bit of 3D work recently for both 3D printing and VR software development.

The main software that I use for 3D work are OpenSCAD and Blender.

One annoyance I have is that the short cut keys each use for standard things such as scale, rotate, move, etc. are all different, which makes switching between applications more awkward than it need be.

So my latest electronics project is to create universal short cut keys - a physical keypad that has single button presses for those functions, but then translates them into the relevant keyboard/mouse presses dependent on which application has focus at the time.

The hardware
As we're still under lockdown due to COVID-19, I'm restricted to using only components and tools I have got at home, like with the USB Switch project.

The keypad itself is this mechanical key switch tester.



Unfortunately the eighth switch was lost some time ago. I'll leave the gap there as potential room for expansion in future though.

The controller is an Arduino Pro Micro. I thought about using a different microcontroller, however the real sticking point was my lack of a spare USB to serial adapter.

The Pro Micro helps keep the overall form factor nice and compact, whilst keeping the programming side of things straightforward.

I picked out some LEDs to backlight the keys as there was spacing for them, and the keycaps are translucent. I tried to find all different colours, but my inventory didn't allow for that, so there's a couple of duplications.

The rest of the hardware is just some diodes and resistors, a bit of perfboard and some scavenged wires.

The hardware is wired up like so:
Quite simply, there's two matrices, one for the switches, and one for the LEDs. Because of the missing key, one column in each only has three connections.


The case is just some plastic container that would otherwise have been trash. It wasn't a perfect fit so required some Dremel-based customisation.

The Firmware

The Arduino will stay set up as a USB to Serial device rather than as a keyboard because there needs to be bi-directional communication - the Arduino needs to also receive input from the application in order to control the lights.

This post was a useful resource when putting together the matrices.

The full source is available in the project on GitHub.

The Software
The software is a java desktop app that communicates with the Arduino using jSerialComm. It controls which keys are 'set' and indicates this with the LEDs.

The interfacing with the other applications comes from a thread that uses system calls to the 'xdotool' linux command, reading in the output of that command which is the name of the current window that has focus. There's room here to make the application multi-platform, by implementing a similar Windows command in something like AutoHotKey.

If the window matches the defined rule set, the relevant keys are highlighted and a thread monitors serial input. If that key is pressed, java built-in Robot class sends the relevant commands to the application.

As with the firmware, the source is available on GitHub. It's in a pretty simplistic state at the moment due to the one-week time limit I've placed on these lockdown projects, but there's room to expand and improve in future.