vbstudio.hu

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.

The Big Red Button™

The Big Red Button

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].

The Beetle board, featuring the ATmega32U4 chip, and an onboard Type-A USB connector, which is very good for soldering.

The Beetle board, featuring the ATmega32U4 chip, and an onboard Type-A USB connector, which is very good for soldering.

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

Wiring diagram of the Beetle board. BTN must be connected to an analog I/O pin (A#) for the Schmitt trigger to work. LED must be connected to a PWM compatible I/O pin (on the Leonardo these are: D3, D5, D6, D9 and D10). SW1 and SW2 inputs can go to any type of I/O pin.

Wiring diagram of the Beetle board. BTN must be connected to an analog I/O pin (A#) for the Schmitt trigger to work. LED must be connected to a PWM compatible I/O pin (on the Leonardo these are: D3, D5, D6, D9 and D10). SW1 and SW2 inputs can go to any type of I/O pin.

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.

My main reason to use the Beetle board is that it has the contacts for a big Type-A USB plug, which can easily be drilled and then soldered to the panel with some pin headers, just like the rest of the I/O pins.

My main reason to use the Beetle board is that it has the contacts for a big Type-A USB plug, which can easily be drilled and then soldered to the panel with some pin headers, just like the rest of the I/O pins.

The button and LED

Wiring diagram for the button and the embedded LED. Note how the button and the LED share a common ground, thus requiring only 3 cables to go to the panel.

Wiring diagram for the button and the embedded LED. Note how the button and the LED share a common ground, thus requiring only 3 cables to go to the panel.

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)

The program switches. The pull-up resistors guarantee that the signal will always be either ground or power.

The program switches. The pull-up resistors guarantee that the signal will always be either ground or power.

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.

The program switches on the bottom of the button. Two switches can have a total of 4 states. 0 means OFF (down) and 1 means ON (up).

The program switches on the bottom of the button. Two switches can have a total of 4 states. 0 means OFF (down) and 1 means ON (up).

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

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:

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.

Oooh, what does this button do?

Please, please! Do not push the button! You have no idea what it...

References

  1. Arduino Leonardo board - arduino.cc
  2. Human interface device - wikipedia.org
  3. "Beetle" USB ATMEGA32U4 Development Board for Arduino Leonardo - ebay.com
  4. Switch Bounce and How to Deal with It - by Jens Christoffersen
  5. HID implementation examples - by NicoHood on GitHub