Main Content

I built a dynamically assignable macro keyboard with an e-ink screen. What does that mean? Well, it is a device that pretends to be a regular keyboard, but the meaning of each button changes depending on which application you currently try to control.

What does it do?
As you can see from the pictures, it is a device with eight buttons, a large dial and a display and it is plugged into a PC via USB. There it registers as a regular keyboard and sends individual key events or sequences of keypresses if I push one of the buttons. So, it is a macro keyboard - a keyboard to send macros.

The special thing about it is that I can dynamically reassign keys and display the current key assignment on an e-ink screen. So, for example, by default the top four keys are assigned to media control keys: Play, pause and skip buttons. If I press them, the device sends the media buttons to the PC as if those buttons were pushed on a normal keyboard with multimedia keys. But if I open up Gimp1, the keys change their meaning to functions within Gimp, which I need regularly and for which I cannot remember the shortcuts: For example “cut size to the selected area”, “automatically cut the image size to the content” etc.

Those are actually not simple key strokes and these particular examples do not even have a direct shortcut. Instead, if I press the “cut to selection” button, the device sends a quick sequence of “Alt+B” to open the image menu, followed by “Z” to select the function from the menu2. At the same time, the device shows some icons next to the buttons to tell me, which assignment is currently active.

Keystrokes or sequences cannot only be assigned to those eight buttons, but also to the big knob at the bottom. This is designed as a so-called jog wheel, commonly used in video editing to precisely move to a specific frame while at the same time allowing to quickly skip larger periods with the same control element3. In Gimp, it controls the tool size (brush size, pen size, eraser size, you get the idea…) or the tool opacity (brush opacity, alright, you know). How can it control both? Well, it doubles as another button. You can press the wheel and trigger a ninth4 button, which can also be associated with keypresses. However, in this case it is not set to send a keystroke, but instead triggers a script to switch the function of turning the wheel.

I actually use this a lot to control additional things with Python or to switch functions of the buttons. The default layout has a button that triggers an MQTT message (in a Python script) to switch a lamp in my office. Of course the script also listens for state changes of the lamp, so the icon on the e-ink screen changes accordingly5.

Similarly, I use Python to control OBS6 via its websockets plugin. If OBS is running, the left set of buttons allows me to switch scenes (a broader moderation view, a close-up shot, sharing slides with the close-up as picture-in-picture frame and an empty “video mute” scene) and the right set of buttons controls elements (microphone mute, overlay screen of my phone, picture-in-picture of the slide scene etc.). This is actually the main reason why I designed this macro keyboard in the first place: I needed a bunch of shortcuts for OBS and could not find a set that was easy to find while talking into a camera and that at the same time did not interfere with common shortcuts. In this case, though, I am not even sending keypresses but activating scenes and changing visibility of components via the websockets plugin from Python. The advantage is that this also allows me to retrieve the current state from OBS and visualize it on the e-ink screen accordingly.”

Link to article