A Big Red Button Acting as a Keyboard Using Arduino
The Big Red Button is technically a keyboard with a single button. What that button is, is up to the implementation. It can be an actual keyboard key, a combination of keys, or even a sequence of keys like a macro. It can also have multiple functions for the same button with single click, double click and long press.
It is based on an Arduino Leonardo [1] board. Unlike the Uno, Nano and Mini boards which all use the ATmega328P chip, this one runs on the ATmega32U4, which features a built-in USB controller. This enables the programming of different Human Interface Devices (HID) [2], such as a keyboard.
The actual board I use is a non-official version called the Beetle [3], which is the tiniest of all the versions I have seen so far. This is an important factor, as the official Leonardo board comes only on a big bulky board, which won't fit into the box. Don't worry, the actual chip is the same on all boards, official or not. These boards can be bought on eBay [3].
My previous version of the Big Red Button featured the control board of an actual keyboard. But this came with several limitations. There are many advantages of using an Arduino Leonardo over an actual keyboard:
- Easy to make more, as you don't just throw out a keyboard every week (I hope).
- No limit to what buttons can be mapped.
- You can simulate multiple buttons pressed at once, or in a sequence.
- A single button can have a maximum of 4 different actions with single click, double click, long press, and double click long press.
- Can be reprogrammed at any time for different behavior.
- Serial port mode can be added for more control over the button via custom software running on the host OS (like making a quiz show with a button for each contestant)
The code
I made the code open source and available on GitHub. Feel free to use it for anything. Detailed instructions on how to install it are provided in the repository.
What are HID usage pages
If you wish to replace keys in the code, it is important to understand what the usage pages mean for a HID device. Most keyboard buttons are defined under "Keyboard/Keypad" Page (a.k.a. page 0x07), but special keys like System Sleep and Volume Up/Down/Mute are defined in "Generic Desktop" Page (0x01). Different pages need separate HID descriptors, and the events are handled entirely separately. It is like having two keyboards in one package. There are a lot more pages, but you most likely won't need the rest. These two are already implemented and ready to use in the code.
This document helped me a lot in understanding usage pages and figuring out key codes. Look for chapter 4 and 10:
Electronic schematics
I don't intend to go into too much detail here, besides, the circuits are rather simple anyway, so I'll just provide a few points for you to get started.
Arduino
Including a reset button is important for reprogramming the chip. You can skip this if your board already features one.
The Beetle board already has an onboard USB connector that you can use to connect to a PC, but since it is going to be inside the box, there are two things you can do:
- Get any kind of USB cable with a Type-A plug on one end, cut off the plug on the other end, and then solder the cables to the Arduino board's USB contacts.
- Or drill the USB contacts and use some pin headers to connect it to your PCB board, just like the rest of the I/O pins. (see picture below).
Either way, be extra careful about which wire goes where, otherwise you might end up frying the board if the 5 Volts go to the wrong place.
The button and LED
The code can read the keyboard LED statuses, so I connected the LED inside the button to the Scroll Lock LED. I have never seen any application that uses that key, so turning it on and off for our own purpose should come without consequences.
For the button I am using a Schmitt trigger with a 100nF capacitor to entirely eliminate any signal bouncing [4] that would make it register multiple presses for a single one. The button needs to be connected to an analog input on the Arduino for the software part of the Schmitt trigger to work.
To minimize current load on the Arduino's pins I am using a general purpose PNP transistor to drive the LED. This type of transistor also lets the LED share a common ground with the button, reducing the number of cables going to the button to 3.
Program switches (optional)
Switch 1 and Switch 2 are for setting button behavior from 4 preset programs. This enables to switch between multiple use cases without reprogramming the Arduino. You can skip this if you only need one function at a time.
In the provided code these are the behaviors for each program switch state: (with 0 being down and 1 being up)
- 00: Button is the Enter key
- 01: Button is the Space key
- 10:
- Single click: F13 is pressed
- Double click: F14 is pressed
- Long press: F15 is pressed
- Double click with long press: F16 is pressed
- 11:
- Single click: ⊞ Left Win + L is pressed (lock workstation)
- Long press: Sleep is pressed
- Single click: ⊞ Left Win + L is pressed (lock workstation)
Actually, if you can get a 4-state sliding switch, that might be even better. I just couldn't find any that can be mounted with screws.
Sourcing the materials
Here are the main components I used:
- Arduino Leonardo "Beetle" board [3]
- Big Red Button
- Multipurpose box: G366 (82 x 80 x 55 mm) by Gainta Industries Ltd. (datasheet)
The rest of the components can be bought from any local electronic component store. The total component price for one button had costed me about €16 at the time. This includes shipping.
Windows app for playing sound effects with the button
The best thing about the function keys F13 through F24 is that I haven't seen any app that use them, and they are completely ignored by DirectInput, making the button invisible to games. The benefit to this is that you can use the button during a gaming party, with an app running in the background that will intercept the button press, and the game won't get confused and add the Big Red Button (technically the keyboard) as an extra player. This happened to me once or twice with the previous prototype which utilized the Pause key.
My app Vasparittya (Iron-sling, don't look for logic in the name) is such an app that can play sound effects on key presses.
Gallery
This is my implementation, using the provided code and circuits.