adafruit_macropad

A helper library for the Adafruit MacroPad RP2040.

  • Author(s): Kattni Rembor

Implementation Notes

Hardware:

Software and Dependencies:

class adafruit_macropad.MacroPad(rotation=0, midi_in_channel=1, midi_out_channel=1)

Class representing a single MacroPad.

Parameters
  • rotation (int) – The rotational position of the MacroPad. Allows for rotating the MacroPad in 90 degree increments to four different positions and rotates the keypad layout and display orientation to match. Keypad layout is always left to right, top to bottom, beginning with key number 0 in the top left, and ending with key number 11 in the bottom right. Supports 0, 90, 180, and 270 degree rotations. 0 is when the USB port is at the top, 90 is when the USB port is to the left, 180 is when the USB port is at the bottom, and 270 is when the USB port is to the right. Defaults to 0.

  • midi_in_channel (int or tuple) – The MIDI input channel. This can either be an integer for one channel, or a tuple of integers to listen on multiple channels. Defaults to 1.

  • midi_out_channel (int) – The MIDI output channel. Defaults to 1.

The following shows how to initialise the MacroPad library with the board rotated 90 degrees, and the MIDI channels both set to 1.

from adafruit_macropad import MacroPad

macropad = MacroPad(rotation=90, midi_in_channel=1, midi_out_channel=1)
static ControlChange(control, value, *, channel=None)

Control Change MIDI message. For more details, see the adafruit_midi.control_change documentation in CircuitPython MIDI: https://circuitpython.readthedocs.io/projects/midi/en/latest/

Parameters
  • control – The control number, 0-127.

  • value – The 7bit value of the control, 0-127.

  • channel – The channel number of the MIDI message where appropriate. This is updated by MIDI.send() method.

The following example sets a control change value.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Set a CC value")
macropad.midi.send(macropad.ControlChange(7, 64))

The following example sweeps a control change value.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Sweep a CC value")
for i in range(127):
    macropad.midi.send(macropad.ControlChange(1, i))
    time.sleep(0.01)
for i in range(127):
    macropad.midi.send(macropad.ControlChange(1, 127-i))
    time.sleep(0.01)
static NoteOff(note, velocity=127, *, channel=None)

Note Off Change MIDI message. For more details, see the adafruit_midi.note_off documentation in CircuitPython MIDI: https://circuitpython.readthedocs.io/projects/midi/en/latest/

Parameters
  • note – The note (key) number either as an int (0-127) or a str which is parsed, e.g. “C4” (middle C) is 60, “A4” is 69.

  • velocity – The release velocity, 0-127, defaults to 0.

  • channel – The channel number of the MIDI message where appropriate. This is updated by MIDI.send() method.

The following example plays a single note by MIDI number, at half velocity.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("NoteOn/NoteOff using note name")
macropad.midi.send(macropad.NoteOn("G#2", 64))
time.sleep(0.5)
macropad.midi.send(macropad.NoteOff("G#2", 0))
time.sleep(1)
static NoteOn(note, velocity=127, *, channel=None)

Note On Change MIDI message. For more details, see the adafruit_midi.note_on documentation in CircuitPython MIDI: https://circuitpython.readthedocs.io/projects/midi/en/latest/

Parameters
  • note – The note (key) number either as an int (0-127) or a str which is parsed, e.g. “C4” (middle C) is 60, “A4” is 69.

  • velocity – The strike velocity, 0-127, 0 is equivalent to a Note Off, defaults to 127.

  • channel – The channel number of the MIDI message where appropriate. This is updated by MIDI.send() method.

The following example plays a single note by MIDI number, at full velocity.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("NoteOn/NoteOff MIDI using note number")
macropad.midi.send(macropad.NoteOn(44, 127))
time.sleep(0.5)
macropad.midi.send(macropad.NoteOff(44, 0))
time.sleep(1)

The following example plays a chord.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Multiple notes on/off in one message")
macropad.midi.send([macropad.NoteOn(44, 127),
                    macropad.NoteOn(48, 127),
                    macropad.NoteOn(51, 127)])
time.sleep(1)
macropad.midi.send([macropad.NoteOff(44, 0),
                    macropad.NoteOff(48, 0),
                    macropad.NoteOff(51, 0)])
time.sleep(1)
static PitchBend(pitch_bend, *, channel=None)

Pitch Bend Change MIDI message. For more details, see the adafruit_midi.pitch_bend documentation in CircuitPython MIDI: https://circuitpython.readthedocs.io/projects/midi/en/latest/

Parameters
  • pitch_bend – A 14bit unsigned int representing the degree of bend from 0 through 8192 (midpoint, no bend) to 16383.

  • channel – The channel number of the MIDI message where appropriate. This is updated by MIDI.send() method.

The following example sets a pitch bend.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Set pitch bend")
macropad.midi.send(macropad.PitchBend(4096))

The following example sweeps a pitch bend.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Sweep pitch bend")
for i in range(0, 4096, 8):
    macropad.midi.send(macropad.PitchBend(i))
for i in range(0, 4096, 8):
    macropad.midi.send(macropad.PitchBend(4096-i))
static ProgramChange(patch, *, channel=None)

Program Change MIDI message. For more details, see the adafruit_midi.program_change documentation in CircuitPython MIDI: https://circuitpython.readthedocs.io/projects/midi/en/latest/

Parameters
  • patch – The note (key) number either as an int (0-127) or a str which is parsed, e.g. “C4” (middle C) is 60, “A4” is 69.

  • channel – The channel number of the MIDI message where appropriate. This is updated by MIDI.send() method.

The following example sends a program change for bank switching.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Send ProgramChange bank messages")
macropad.midi.send(macropad.ProgramChange(63))
time.sleep(2)
macropad.midi.send(macropad.ProgramChange(8))
time.sleep(2)
property consumer_control

Send ConsumerControl code reports, used by multimedia keyboards, remote controls, etc.

The following example decreases the volume when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.consumer_control.send(macropad.ConsumerControlCode.VOLUME_DECREMENT)
display_image(file_name=None, position=None)

Display an image on the built-in display.

Parameters
  • file_name (str) – The path to a compatible bitmap image, e.g. "/image.bmp". Must be a string.

  • position (tuple) – Optional (x, y) coordinates to place the image.

The following example displays an image called “image.bmp” located in / on the CIRCUITPY drive on the display.

from adafruit_macropad import MacroPad

macropad = MacroPad()

macropad.display_image("image.bmp")

while True:
    pass
static display_text(title=None, title_scale=1, title_length=80, text_scale=1, font=None)

Display lines of text on the built-in display. Note that if you instantiate this without a title, it will display the first ([0]) line of text at the top of the display - use this feature to have a dynamic “title”.

Parameters
  • title (str) – The title displayed above the data. Set title="Title text" to provide a title. Defaults to None.

  • title_scale (int) – Scale the size of the title. Not necessary if no title is provided. Defaults to 1.

  • title_length (int) – The maximum number of characters allowed in the title. Only necessary if the title is longer than the default 80 characters. Defaults to 80.

  • text_scale (int) – Scale the size of the data lines. Scales the title as well. Defaults to 1.

  • font – The font or the path to the custom font file to use to display the text. Defaults to the built-in terminalio.FONT. Custom font files must be provided as a string, e.g. "/Arial12.bdf".

The following example displays a title and lines of text indicating which key is pressed, the relative position of the rotary encoder, and whether the encoder switch is pressed. Note that the key press line does not show up until a key is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

text_lines = macropad.display_text(title="MacroPad Info")

while True:
    key_event = macropad.keys.events.get()
    if key_event:
        text_lines[0].text = "Key {} pressed!".format(key_event.key_number)
    text_lines[1].text = "Rotary encoder {}".format(macropad.encoder)
    text_lines[2].text = "Encoder switch: {}".format(macropad.encoder_switch)
    text_lines.show()
property encoder

The rotary encoder relative rotation position. Always begins at 0 when the code is run, so the value returned is relative to the initial location.

The following example prints the relative position to the serial console.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    print(macropad.encoder)
property encoder_switch

The rotary encoder switch. Returns True when pressed.

The following example prints the status of the rotary encoder switch to the serial console.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    print(macropad.encoder_switch)
property encoder_switch_debounced

The rotary encoder switch debounced. Allows for encoder_switch_debounced.pressed and encoder_switch_debounced.released. Requires you to include encoder_switch_debounced.update() inside your loop.

The following example prints to the serial console when the rotary encoder switch is pressed and released.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    macropad.encoder_switch_debounced.update()
    if macropad.encoder_switch_debounced.pressed:
        print("Pressed!")
    if macropad.encoder_switch_debounced.released:
        print("Released!")
property keyboard

A keyboard object used to send HID reports. For details, see the Keyboard documentation in CircuitPython HID: https://circuitpython.readthedocs.io/projects/hid/en/latest/index.html

The following example types out the letter “a” when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.keyboard.send(macropad.Keycode.A)
property keyboard_layout

Map ASCII characters to the appropriate key presses on a standard US PC keyboard. Non-ASCII characters and most control characters will raise an exception. Required to send a string of characters.

The following example sends the string "Hello World" when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.keyboard_layout.write("Hello World")
property keys

The keys on the MacroPad. Uses events to track key number and state, e.g. pressed or released. You must fetch the events using keys.events.get() and then the events are available for usage in your code. Each event has three properties:

  • key_number: the number of the key that changed. Keys are numbered starting at 0.

  • pressed: True if the event is a transition from released to pressed.

  • released: True if the event is a transition from pressed to released.

    released is always the opposite of pressed; it’s provided for convenience and clarity, in case you want to test for key-release events explicitly.

The following example prints the key press and release events to the serial console.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    key_event = macropad.keys.events.get()
    if key_event:
        print(key_event)
property midi

The MIDI object. Used to send and receive MIDI messages. For more details, see the adafruit_midi documentation in CircuitPython MIDI: https://circuitpython.readthedocs.io/projects/midi/en/latest/

The following example plays a single note by MIDI number, at full velocity.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("NoteOn/NoteOff MIDI using note number")
macropad.midi.send(macropad.NoteOn(44, 127))
time.sleep(0.5)
macropad.midi.send(macropad.NoteOff(44, 0))
time.sleep(1)

The following example reads incoming MIDI messages.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

print("Read incoming MIDI messages")
msg_in = macropad.midi.receive()
if msg_in is not None:
    print("Received:", msg_in.__dict__)
property mouse

Send USB HID mouse reports.

The following example sends a left mouse button click when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.mouse.click(macropad.Mouse.LEFT_BUTTON)
property pixels

Sequence-like object representing the twelve NeoPixel LEDs in a 3 x 4 grid on the MacroPad. Each pixel is at a certain index in the sequence, numbered 0-11. Colors can be an RGB tuple like (255, 0, 0) where (R, G, B), or an RGB hex value like 0xFF0000 for red where each two digits are a color (0xRRGGBB). Set the global brightness using any number from 0 to 1 to represent a percentage, i.e. 0.3 sets global brightness to 30%. Brightness defaults to 1.

See neopixel.NeoPixel for more info.

The following example turns all the pixels green at 50% brightness.

from adafruit_macropad import MacroPad

macropad = MacroPad()

macropad.pixels.brightness = 0.5

while True:
    macropad.pixels.fill((0, 255, 0))

The following example sets the first pixel red and the twelfth pixel blue.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    macropad.pixels[0] = (255, 0, 0)
    macropad.pixels[11] = (0, 0, 255)
play_file(file_name)

Play a .wav or .mp3 file using the onboard speaker.

Parameters

file_name – The name of your .wav or .mp3 file in quotation marks including .wav or .mp3, e.g. “sound.wav” or “sound.mp3”. Include location if file is placed somewhere other than /, e.g. “audio/sound.wav”.

The following example plays the file “sound.wav” when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.play_file("sound.wav")

The following example plays the file “sound.mp3” when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.play_file("sound.mp3")
play_tone(frequency, duration)

Produce a tone using the speaker at a specified hz for a specified duration in seconds.

Parameters
  • frequency (int) – The frequency of the tone in Hz

  • duration (float) – The duration of the tone in seconds

The following example plays a 292hz tone for 1 second when the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.play_tone(292, 1)
property red_led

The red led next to the USB port.

The following example blinks the red LED every 0.5 seconds.

import time
from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
  macropad.red_led = True
  time.sleep(0.5)
  macropad.red_led = False
  time.sleep(0.5)
start_tone(frequency)

Produce a tone using the speaker. Will continue playing until stop_tone is called.

Parameters

frequency (int) – The frequency of the tone in Hz

The following example plays 292hz a tone while the rotary encoder switch is pressed.

from adafruit_macropad import MacroPad

macropad = MacroPad()

while True:
    if macropad.encoder_switch:
        macropad.start_tone(292)
    else:
        macropad.stop_tone()
stop_tone()

Use with start_tone to stop the tone produced. See usage example in start_tone documentation.

MacroPad.Keycode

The contents of the Keycode module are available as a property of MacroPad. This includes all keycode constants available within the Keycode module, which includes all the keys on a regular PC or Mac keyboard.

Remember that keycodes are the names for key _positions_ on a US keyboard, and may not correspond to the character that you mean to send if you want to emulate non-US keyboard.

For usage example, see the keyboard documentation in this library.

MacroPad.ConsumerControlCode

The contents of the ConsumerControlCode module are available as a property of MacroPad. This includes the available USB HID Consumer Control Device constants. This list is not exhaustive.

For usage example, see the consumer_control documentation in this library.

MacroPad.Mouse

The contents of the Mouse module are available as a property of MacroPad. This includes the LEFT_BUTTON, MIDDLE_BUTTON, and RIGHT_BUTTON constants. The rest of the functionality of the Mouse module should be used through macropad.mouse.

For usage example, see the mouse documentation in this library.