This uses the CircuitPython MacroPad library to make customizable shortcuts with Lights and Sounds.

The main loop checks for key events and handles inputs if it's a keycode or consumer control such as volume and media playback.

The shortcuts are stored in a separate file that contains a dictionary of keys.

Here you can set the tone, label, keycode type and the key sequence.


With CircuitPython, you have access to the code with the USB drive, which is great when developing across different computers.

Code and Shortcuts

Follow the instructions to save the following file, the file, and the necessary libraries to your CIRCUITPY drive.

Click the Download Project Bundle button below to download the necessary libraries. the file, and file in a zip file. Extract the contents of the zip file and choose the folder that matches the version of CircuitPython you are using. Copy the entire lib folder, the file, and the file to your CIRCUITPY drive.

# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
Adafruit MacroPad shortcut macropad with light up keys that play a tone or wav file when a key is
pressed. Displays the associated key command being sent on key press in a grid matching the key
layout for easily viewing what command is associated with what key.

REQUIRES associated file containing a dictionary with all the key info.
import displayio
import terminalio
from rainbowio import colorwheel
from adafruit_displayio_layout.layouts.grid_layout import GridLayout
from adafruit_display_text import bitmap_label as label
from adafruit_macropad import MacroPad
from shortcuts import shortcut_keys

# Initialise MacroPad
macropad = MacroPad()

# Setup title and grid
main_group = displayio.Group()
title = label.Label(
    text="      SHORTCUTS       ",
layout = GridLayout(x=0, y=10, width=128, height=54, grid_size=(3, 4), cell_padding=5)

# Extract data from shortcuts
key_sounds = [sound[0] for sound in shortcut_keys["macros"]]
label_names = [names[1] for names in shortcut_keys["macros"]]
keys = [keys[3] for keys in shortcut_keys["macros"]]

# Generate the labels based on the label names and add them to the appropriate grid cell
labels = []
for index in range(12):
    x = index % 3
    y = index // 3
    labels.append(label.Label(terminalio.FONT, text=label_names[index]))
    layout.add_content(labels[index], grid_position=(x, y), cell_size=(1, 1))

# Display the text

while True:
    key_event =  # Begin checking for key events.

    if key_event:  # If there is a key event, e.g. a key has been pressed...
        if key_event.pressed:  # And a key is currently being pressed...

            # ... light up the pressed key with a color from the rainbow.
            macropad.pixels[key_event.key_number] = colorwheel(
                int(255 / 12) * key_event.key_number

            # If it's a Keycode...
            if "KC" in shortcut_keys["macros"][key_event.key_number][2]:
                # ... send the associated key command or sequence of key commands.
                for key in keys[key_event.key_number]:

            # If it's a ConsumerControlCode...
            if "CC" in shortcut_keys["macros"][key_event.key_number][2]:
                # ... send the associated consumer control code.
                for key in keys[key_event.key_number]:

            sounds = key_sounds[key_event.key_number]  # Assign the tones/wavs to the keys.
            if isinstance(sounds, int):  # If the sound is a tone in Hz...
                macropad.start_tone(sounds)  # ... play the tone while the key is pressed.
            if isinstance(sounds, str):  # If the sound is a wav file name as a string...
                macropad.play_file(sounds)  # ... play the wav file.
            # Otherwise, turn off the NeoPixels and stop the tone.


The file contains a Python dictionary that allows you to easily configure what each key will do in terms of the following:

  • The tone in Hz to play.
  • The label to show on the display (should be kept to 6 characters or less to fit).
  • The key type being sent (e.g. KC for Keycode or CC for Consumer Control Code).
  • The key sequence (the keycode or group of keycodes to send on key press).

Each of the multi-entry lines in the dictionary have all four pieces of information for each key. To configure a key differently, simply update the associated line to have the desired tone, display label, key type abbreviation, and the key sequence.

For example, to update the first key to play a different tone and send the letter "a", I would change line 29 to the following:

(185, 'a', 'KC', [macropad.Keycode.A]),

That's all there is to configuring your MacroPad shortcuts.

This guide was first published on Jul 21, 2021. It was last updated on 2021-07-21 09:53:49 -0400.

This page (Code) was last updated on May 24, 2022.

Text editor powered by tinymce.