The humble Arduino can do a lot of things, but did you know it can emulate a USB keyboard? You can combine those difficult to remember long keyboard shortcuts into a single custom shortcut key, with this simple circuit. Here's the end result:

Never used an Arduino before? Check out our getting started guide first.

What You Need

Arduino Shortcut Parts

Here's what you need to make this project:

  • 1 x Arduino Pro Micro.
  • Momentary buttons or keyboard buttons.
  • 10K ohm resistors.
  • Assorted hookup wires.
  • 1 x 220 ohm resistors.
  • 1 x 5mm (0.197 inches) LED.
  • 1 x 5mm LED holder.

You will need a very specific Arduino for this project. I'm using a Pro Micro, as they are so small and cheap, you need an Arduino that has USB-Serial built in to the processor (Atmega32u4). It is possible to built this project with other Arduinos, such as an UNO or Nano, however it requires a lot of hard work to re-flash the bios and fiddling about to get things to work. Clones of other Arduino models do not usually work at all, but a Pro Micro clone is also fine.

You will need one momentary button, one 10K ohm resistor, and appropriate hookup wire for each button you want to use. I'm using Cherry MX mechanical keyboard switches for the actual shortcut buttons, although any switch will do, providing it is momentary and not latching.

You may need a few other items depending on how you build this. If you want to prototype it, you will need a solderless breadboard. It's worth spending the money on a good one -- they can sometimes be very unreliable. If you want to box this up, you will want to purchase some stripboard.

Build Plan

Here's how this will work. The Arduino will be programmed to act like a USB keyboard -- as far as your computer is concerned, it is. Several buttons connected to the Arduino will send key commands to your computer. You will only press one button, but your computer will think you have pressed Alt > F4, for example.

Selecting a Switch

Arduino Cherry MX

There are several variations of MX series switches. This website provides an excellent introduction, however they essentially come down to noise and pressure. Some models require more force to press, and some models make a mechanical "click" sound when pressed. I have used Cherry MX Browns, which do not make a noise when pressed. They are all the same dimensions, so choose any model you like (or mix and match) without worry.

You'll also need to purchase some key caps, of course, and there's a world of custom designs out there to choose from -- we purchased from KeyboardCo in the U.K.

The Case

I've 3D printed this case, and you can download the .STL files from Thingiverse. Don't worry if you do not own a 3D printer, you can still build this. Many websites provide 3D printing services, such as 3D Hubs or Shapeways. Alternatively, this is a very simple case, you could make your own out of plasticard, perspex, wood, or even cardboard. If you want to be really thrifty, Cherry MX sell a switch tester/sampler set on Amazon (UK). You will need 4 M5 x 35mm bolts and 4 M5 nuts. You can of course substitute these for a suitable alternative you have.

If you are making your own case, there's one important detail you need to know: Cherry MX switches are a push-fit into their mounting holes. They require a 14 x 14mm (0.551 inch) square mounting hole, with the plate being no thicker than 1.5mm (0.059 inch). Stray too far from these dimensions, and your switches may no longer mount correctly.

Shortcut Case

The 3D printed case is in two parts, the top and the bottom. Push the Cherry MX switches into the square holes:

Shortcut Cherry MX Mount

Make sure you mount the switches the correct way round. The top has the words "CHERRY" on, and the bottom has a little notch. Insert a 3mm LED into this little slot:

Shortcut Cherry MX LED

You may find that the LEDs look best mounted "upside down". This was the case for the keycaps I used, and it does not impact the switches at all.

You should now have nine switches with 9 LEDS. There is no need to glue any of these parts in. The solder will hold the LEDs, and friction will hold the switches.

Shortcut Cherry MX All

Next, screw in the LED mount (leave the LED removed for now). You will finish assembling the case later on, once the circuit is built.

The Circuit

This circuit is built on stripboard. This is excellent for building semi-permanent circuits, without the cost of a print circuit board (PCB). It is simply a piece of fiberglass with copper tracks running parallel in one direction. These tracks can be soldered to, as well as cut. Cutting a track can be done with a special tool or a small drill bit.

Not too confident at soldering? Have a look at these simple projects first.

Here's the stripboard layout (excludes trailing leads):

Arduino Shortcut Stripboard

Make sure you cut the traces under the resistors and the Arduino. As it can be very difficult to read a stripboard circuit, here's a breadboard version:

Arduino Shortcut Breadboard

It is a tight fit to squeeze all the components into such a small space. Cut the corners of your stripboard as follows:

Shortcut Stripboard

This should fit neatly into the bottom of the case:

Shortcut Stripboard in Box

Make sure the tracks are running vertically.

Connect the anode (long leg, positive) of the LED to the 200 ohm resistor and then to +5 V. Connect the Cathode (short leg, negative) to ground. Cover the legs with heat shrink sleeving and then push into the LED holder. There is no need for any glue, however your LED holder may not be a push-fit, so you may need to adapt these instructions.

Shortcut Status LED

You may wish to use a bi-color LED here instead -- this will allow you to setup two or more banks of switches, with a different colored status LED for each bank.

Now it's time to solder all the LEDs for the keycaps. These are used solely to make the keys glow, so you can skip them if you would like to, and they don't have to be connected to a digital pin, only power. Connect all the anodes together, and all the cathodes together. Learn from my mistake -- it's much easier to do this before wiring the switches! Connect the anodes to +5 V though a 220 ohm resistor, and the cathodes to ground. These LEDs are wired in parallel. Here's the circuit just for these LEDS:

Shortcut Button LEDs Circuit

Use a small piece of heat shrink tubing to cover the connection between the LEDs and the Arduino:

Shortcut LED Heatshrink

Power up the Arduino to test all the LEDs work. You do not need to upload any code. If any LEDs aren't working, go and double check your wiring.

Shortcut LED Testing

Now wire up the switches. These must be connected through a 10k resistor, otherwise the Arduino will die. This is called a dead short -- +5 V goes directly into ground, and all that remains of your Arduino will be a puff of smoke (trust me, I killed one already so you don't have to). Here's the circuit for one switch:

Arduino Shortcut Circuit

This circuit is the same for all nine switches. Connect the switches to digital pins two through ten, each with their own 10K resistor to ground. Be careful soldering Cherry MX switches, they can be a little fragile, I had several pins break on me. You may want to solder these directly to some more stripboard, however trailing leads are still suitable.

That's it for the wiring. You may wish to mount a USB type B female socket, however the tiny pins on them can often be quite difficult to solder to. If you do not wish to do this, do not worry. The Micro USB connector on the Arduino neatly fits the hole in the chassis. If you are a bit confused about the different USB types, make sure you understand the differences.

Finally, double check your circuit is correct. A short can easily destroy an Arduino, and it can be easy to do using stripboard.

The Code

Now test the circuit is correct. It's a good idea to do this before proceeding, so you can fix any issues now whilst you can. Upload this test code (don't forget to select the correct board and port from the Tools > Board and Tools > Port menus):

        const int buttons[] = {2,3,4,5,6,7,8,9,10}; // array of all button pins

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);

 pinMode(2, INPUT);
 pinMode(3, INPUT);
 pinMode(4, INPUT);
 pinMode(5, INPUT);
 pinMode(6, INPUT);
 pinMode(7, INPUT);
 pinMode(8, INPUT);
 pinMode(9, INPUT);
 pinMode(10, INPUT);
}

void loop() {
 // put your main code here, to run repeatedly:
 for(int i = 2; i < 11; ++i) {
 if(digitalRead(i) == HIGH) {
 // software de-bounce improves accuracy
 delay(10);
 if(digitalRead(i) == HIGH) {
 // check switches
 Serial.print ("input");
 Serial.println(i);
 delay(250);
 }
 }
 }
}

You may need to change the pins if you have modified the circuit.

Once uploaded, open the serial monitor (top right > Serial Monitor). One by one, press each button. You should see the serial monitor show the number of the button you pressed. Just like with the LED, if your computer complains about drawing too much current, or the LEDs go out when you press a button, disconnect immediately! You have a short somewhere in the circuit, double check the circuit is correct and there are no shorts between connections.

If everything is working, go ahead and put the circuit into the box. You may want to use a dab of glue to hold the circuit in place (although the wires held mine in fine). Bolt the lid on as well.

To make the Arduino appear to be a keyboard is very simple. If you are using a Nano or UNO, you are going to re-program your Arduino using Device Firmware Update (DFU). This is usually used to flash new firmware to the Arduino. You are going to use it to flash the Arduino with a new firmware that will make it work like a keyboard. This will not be covered here, as it is quite a complex task. The Arduino website has a good tutorial for this.

The Arduino Pro Micro makes this step very easy. The logic required to emulate a USB keyboard is already built in to the processor, so it's as simple as writing some code!

First, set up the keys:

        int keys[] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
    

This is an array containing all the pins the buttons are connected to. If you have used more or less buttons or used different pins, change the values here.

An array is a collected of like-minded things. Computers can optimize your code to access them quickly, and they speed up the code writing process.

Now initialize all the pins as inputs:

        void setup() {
 // put your setup code here, to run once:
 Keyboard.begin(); // setup keyboard
 for (int i = 2; i < 11; ++i) {
 // initilize pins
 pinMode(i, INPUT);
 }
}

This tells the Arduino that all the pins in the array are inputs. A loop is used to do this, so rather than writing pinMode(2, INPUT) nine times, you only have to write it once. This also calls Keyboard.begin. This sets up a function built in to the Arduino library, designed specifically for emulating a keyboard.

Create a method called readButton:

        boolean readButton(int pin) {
 // check and debounce buttons
 if (digitalRead(pin) == HIGH) {
 delay(10);
 if (digitalRead(pin) == HIGH) {
 return true;
 }
 }
 return false;
}

This takes a pin, and checks if it has been pressed or not. It simply returns TRUE or FALSE. It also contains some software debouncing -- a simple delay and then re-checking the switch ensures that the button really was pressed.

Now another for loop is called inside void loop():

        void loop() {
 // put your main code here, to run repeatedly:
 for (int i = 2; i < 11; ++i) {
 // check buttons
 if(readButton(i)) {
 doAction(i);
 }
 }
}

Again, this goes over every element in the array and checks if it has been pressed. It does this by called the readButton method you created earlier. If a button has been pressed, it passes that pin number to another method called doAction:

        void doAction(int pin) {
 // perform tasks
 switch (pin) {
 case 2:
 Keyboard.println("drive.google.com");
 break;
 case 3:
 Keyboard.println("makeuseof.com");
 break;
 case 4:
 // CMD + T (new tab, Chrome)
 Keyboard.press(KEY_LEFT_GUI);
 Keyboard.press('t');
 delay(100);
 Keyboard.releaseAll();
 break;
 case 5:
 // your task here
 break;
 case 6:
 // your task here
 break;
 case 7:
 // your task here
 break;
 case 8:
 // your task here
 break;
 case 9:
 // your task here
 break;

 }
}

This checks the pin number using a switch statement. Switch statements (sometimes called switch case) are similar to an if statement, however they are useful for checking that one thing (in this case the pin number) is equal to one of several different outcomes. Essentially, they are much faster to calculate.

The main components are inside this switch statement. Keyboard.println writes text to the computer as if you physically typed every key. Keyboard.press presses and holds one key. Don't forget to release them using Keyboard.releaseAll after a short delay!

Here's the full code:

        int keys[] = {2, 3, 4, 5, 6, 7, 8, 9, 10};

void setup() {
 // put your setup code here, to run once:
 Keyboard.begin(); // setup keyboard
 for (int i = 2; i < 11; ++i) {
 // initilize pins
 pinMode(i, INPUT);
 }
}

void loop() {
 // put your main code here, to run repeatedly:
 for (int i = 2; i < 11; ++i) {
 // check buttons
 if(readButton(i)) {
 doAction(i);
 }
 }
}

boolean readButton(int pin) {
 // check and debounce buttons
 if (digitalRead(pin) == HIGH) {
 delay(10);
 if (digitalRead(pin) == HIGH) {
 return true;
 }
 }
 return false;
}

void doAction(int pin) {
 // perform tasks
 switch (pin) {
 case 2:
 Keyboard.println("drive.google.com");
 break;
 case 3:
 Keyboard.println("makeuseof.com");
 break;
 case 4:
 // CMD + T (new tab, Chrome)
 Keyboard.press(KEY_LEFT_GUI);
 Keyboard.press('t');
 delay(100);
 Keyboard.releaseAll();
 break;
 case 5:
 // your task here
 break;
 case 6:
 // your task here
 break;
 case 7:
 // your task here
 break;
 case 8:
 // your task here
 break;
 case 9:
 // your task here
 break;

 }
}

In addition to all the number and letter keys, the Arduino can press most of the special keys called Keyboard Modifiers. These are particularly useful for pressing keyboard shortcuts. The Arduino website has a helpful list.

Now all that's left is to create some shortcuts. You could map this to existing shortcuts, such as Alt + F4 (close program in Windows) or Cmd + Q (quit program macOS). Alternatively, make sure you read our ultimate keyboard shortcut guide, how to create Windows shortcuts, and every Chromebook shortcut to get started making your own shortcuts.

Have you created your own shortcut box? Let me know in the comments, I'd love to see some pictures!