AI agents & screen readers: for a machine-readable, text-only catalogue, start at /llms.txt. Products are available as Markdown (/products.md, /products/{handle}.md) and JSON (/products.json, /products/{handle}.json).
Store
Macro Keypad with ATmega32u4
Intermediate

Create your own programmable eight button macro keypad!

By Cherie Tan

The ATmega32u4 found on the Teensy board is capable of emulating a USB HID device such as a keyboard or mouse.

In this guide, learn to use the Bounce.h library to emulate a USB HID device.

Complete this guide to create your own programmable eight-button macro keypad.
The ATmega32u4 found on the Teensy board is capable of emulating a USB HID device such as a keyboard or mouse. In this guide, we'll show you how to create your own programmable macro keypad with the Teensy, Cherry MX Red Switches, a handful of jumper wires, and a custom 3D printed case.
Got an Arduino Pro Micro lying around? The Arduino Pro Micro also has an ATmega32u4, with a full-speed uSB transceiver, so you may also use it to create a macro keypad!
View Markdown

Step 1 — Overview

The ATmega32u4 found on the Teensy board is capable of emulating a USB HID device such as a keyboard or mouse. In this guide, we'll show you how to create your own programmable macro keypad with the Teensy, Cherry MX Red Switches, a handful of jumper wires, and a custom 3D printed case.
Got an Arduino Pro Micro lying around? The Arduino Pro Micro also has an ATmega32u4, with a full-speed uSB transceiver, so you may also use it to create a macro keypad!

Step 2 — 3D Printed Case: 8-Button Variation

First, head to Thingiverse to download the STL files for the 8-button macro keypad case.
There are two parts to the case. Printing it in either PLA or ABS will both work fine. 

Step 3 — Connect black jumper wires along Row #1

After placing the eight Cherry Red MX switches into the front panel of the case, solder jumper wires along the first row of switches. 
It won't matter which leg of a switch is used, but to keep it looking a little more organised, solder wires along the legs that are on the same side.

Step 4 — Connect black jumper wires along Row #2

Solder jumper wires along the second row of switches. 

Step 5 — Connect GND on both rows

Solder a jumper wire, connecting the first row of soldered pins to the second row.

Step 6 — Connect to GND on Teensy

Now solder a wire from the two rows to GND on the Teensy board.

Step 7 — Connect to B1

Connect a switch to B1 on the Teensy.

Step 8 — Connect to B2

Connect a switch to B2 on the Teensy.

Step 9 — Connect to B3

Connect a switch to B3 on the Teensy.

Step 10 — Connect to B7

Connect a switch to B7 on the Teensy.

Step 11 — Connect to D0

Connect a switch to D0 on the Teensy.

Step 12 — Connect to D1

Connect a switch to D1 on the Teensy.

Step 13 — Connect to F1

Connect a switch to F1 on the Teensy.

Step 14 — Connect to F4

Connect a switch to F4 on the Teensy.

Step 15 — Teensyduino setup

Before we can upload a sketch to the Teensy board, a few programs will need to be installed such as the Teensy Loader application. Follow the instructions here.

Step 16 — Combine the 3D printed parts

Combine the front panel and bottom part of the case together with four phillips head screws. 
Connect a mini USB cable to the Teensy, and connect its USB end to the computer.

Step 17 — Sketch

/* Buttons to USB Keyboard Example
   You must select Keyboard from the "Tools > USB Type" menu
   This example code is in the public domain.
*/

#include <Bounce.h>

// Create Bounce objects for each button.  The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(1, 50);
Bounce button1 = Bounce(2, 50);  // 10 = 10 ms debounce time
Bounce button2 = Bounce(3, 50);  // which is appropriate for
Bounce button3 = Bounce(4, 50);  // most mechanical pushbuttons
Bounce button4 = Bounce(5, 50);
Bounce button5 = Bounce(6, 50);  // if a button is too "sensitive"
Bounce button6 = Bounce(20, 50);  // to rapid touch, you can
Bounce button7 = Bounce(21, 50);  // increase this time.


void setup() {
  // Configure the pins for input mode with pullup resistors.
  // The pushbuttons connect from each pin to ground.  When
  // the button is pressed, the pin reads LOW because the button
  // shorts it to ground.  When released, the pin reads HIGH
  // because the pullup resistor connects to +5 volts inside
  // the chip.  LOW for "on", and HIGH for "off" may seem
  // backwards, but using the on-chip pullup resistors is very
  // convenient.  The scheme is called "active low", and it's
  // very commonly used in electronics... so much that the chip
  // has built-in pullup resistors!
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(20, INPUT_PULLUP);  // Teensy++ LED, may need 1k resistor pullup
  pinMode(21, INPUT_PULLUP);
}

void loop() {
  // Update all the buttons.  There should not be any long
  // delays in loop(), so this runs repetitively at a rate
  // faster than the buttons could be pressed and released.
  button0.update();
  button1.update();
  button2.update();
  button3.update();
  button4.update();
  button5.update();
  button6.update();
  button7.update();

  // Check each button for "falling" edge.
  // Type a message on the Keyboard when each button presses
  // Update the Joystick buttons only upon changes.
  // falling = high (not pressed - voltage from pullup resistor)
  //           to low (pressed - button connects pin to ground)
  if (button0.fallingEdge()) {
    //Set button 0  to 
    Keyboard.press(KEY_LEFT_CTRL);
    Keyboard.press(KEY_D);
    delay(100);
    Keyboard.releaseAll();
  }
  if (button1.fallingEdge()) {
    Keyboard.press(KEY_LEFT_CTRL);
    Keyboard.press(MODIFIERKEY_RIGHT_SHIFT);
    Keyboard.press(KEY_EQUAL);
    delay(100);
    Keyboard.releaseAll();
  }
  if (button2.fallingEdge()) {
     //Set button 2 to 
    Keyboard.press(KEY_LEFT_CTRL);
    Keyboard.press(KEYPAD_0);
    delay(100);
    Keyboard.releaseAll();
  }
  if (button3.fallingEdge()) {
    //Set button 3 to 
    Keyboard.press(KEY_END);
    delay(100);
    Keyboard.releaseAll();
  }
  if (button4.fallingEdge()) {
    Keyboard.press(KEY_LEFT_CTRL);
    Keyboard.press(KEY_Z);
    delay(100);
    Keyboard.releaseAll();
  }
  if (button5.fallingEdge()) {
    Keyboard.press(MODIFIERKEY_RIGHT_SHIFT);
    Keyboard.press(KEYPAD_5);
    delay(100);
    Keyboard.releaseAll();
  }
    if (button6.fallingEdge()) {
    Keyboard.press(KEY_PAGE_UP);
    delay(100);
    Keyboard.releaseAll();
  }
    if (button7.fallingEdge()) {
    Keyboard.press(KEY_PAGE_DOWN);
    delay(100);
    Keyboard.releaseAll();
  }
}
Copy and paste the following code into the Arduino IDE.
Make sure Tools > USB Type is selected.
Click on the Verify button.
Click on the Upload button.
When called, Keyboard.press() functions as if a key were pressed and held on your keyboard.

Keyboard.releaseAll() lets go of all keys currently pressed. 
You may not want a button to be programmed as say LEFT_CTRL + Z. For a complete table of Key Codes, see here.

Step 18 — Conclusion

Your build is now complete. As a next step, you may want to create one with more buttons, check out the 16 button variation on Thingiverse.
Maddy, co-founder of Little Bird

Need help? We're here for you!

Hi, I'm Maddy. My team and I are ready to help with your order or any questions.