Being able to send note messages is one of the most popular MIDI projects. In this example, you'll see how to use button inputs to send NoteOn and NoteOff messages to a synth or DAW.

Below, a simple circuit is built using a Feather RP2040 microcontroller board wired to four buttons. The components and wires are seated in a breadboard which facilitates connections via wires.

The Feather will need to have header pins soldered on. The Breadboard can help hold them while you do this.

Circuit Diagram

  • Button 1
    • Pin 1 to Feather pin D5
    • Pin 4 to Feather GND
  • Button 2
    • Pin 1 to Feather pin D6
    • Pin 4 to Feather GND
  • Button 3
    • Pin 1 to Feather pin D9
    • Pin 4 to Feather GND
  • Button 4
    • Pin 1 to Feather pin D10
    • Pin 4 to Feather GND

Setup the Feather RP2040

For this example, you'll be using the Feather RP2040. To make sure it is setup properly with CircuitPython, please follow the steps in the guide below.

CircuitPython Code

Once you've finished setting up your Feather RP2040 with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the Download Project Bundle button in the window below. It will download as a zipped folder.

# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT

import board
import digitalio
import usb_midi
import adafruit_midi
from adafruit_midi.note_on          import NoteOn
from adafruit_midi.note_off         import NoteOff

#  midi setup
midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)

#  midi note numbers
midi_notes = [60, 64, 67, 72]

#  digital pins for the buttons
key_pins = [board.D5, board.D6, board.D9, board.D10]

#  array for buttons
keys = []

#  setup buttons as inputs
for key in key_pins:
    key_pin = digitalio.DigitalInOut(key)
    key_pin.direction = digitalio.Direction.INPUT
    key_pin.pull = digitalio.Pull.UP

#  states for buttons
key0_pressed = False
key1_pressed = False
key2_pressed = False
key3_pressed = False

#  array for button states
key_states = [key0_pressed, key1_pressed, key2_pressed, key3_pressed]

while True:

    #  iterate through 4 buttons
    for i in range(4):
        inputs = keys[i]
        #  if button is pressed...
        if not inputs.value and key_states[i] is False:
            #  update button state
            key_states[i] = True
            #  send NoteOn for corresponding MIDI note
            midi.send(NoteOn(midi_notes[i], 120))

        #  if the button is released...
        if inputs.value and key_states[i] is True:
            #  send NoteOff for corresponding MIDI note
            midi.send(NoteOff(midi_notes[i], 120))
            key_states[i] = False

Upload the Code and Libraries to the Feather RP2040

After downloading the Project Bundle, plug your Feather RP2040 into the computer's USB port. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather RP2040's CIRCUITPY drive. 

  • lib folder

Your Feather RP2040 CIRCUITPY drive should look like this after copying the lib folder and the file.

How the CircuitPython Code Works

The MIDI note numbers assigned to each button are setup in the midi_notes array. When a key press is detected, a NoteOn message with the corresponding MIDI note number is sent. When a key is released, then a NoteOff message is sent.

If you wanted to change the notes or buttons, you would edit the midi_notes and key_pins array.


You can connect your Feather RP2040 via USB to either your computer or a USB MIDI host. Then, press the buttons to play the notes of a C major triad. 

A DIY MIDI keyboard is a very popular project. You can add more buttons, change the notes or create a fun enclosure to customize this project further.

This guide was first published on Mar 02, 2022. It was last updated on May 20, 2024.

This page (Basic MIDI Keyboard) was last updated on May 20, 2024.

Text editor powered by tinymce.