Back to Projects
Adafruit MIDI Controller
CircuitPython code for Raspberry Pi Pico MIDI controller with keyboard matrix scanning
midi-controller.py
CircuitPythonimport time
import board
import digitalio
import usb_midi
from adafruit_midi import MIDI
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
# Update these lists if you wired differently
ROWS = [board.GP2, board.GP3, board.GP4, board.GP5, board.GP6, board.GP7, board.GP8, board.GP9]
COLS = [board.GP10, board.GP11, board.GP12, board.GP13, board.GP14, board.GP15, board.GP16, board.GP17]
FIRST_NOTE = 36 # MIDI note number for the leftmost key; adjust for your keyboard
DEBOUNCE_DELAY = 0
row_pins = []
for p in ROWS:
d = digitalio.DigitalInOut(p)
d.direction = digitalio.Direction.OUTPUT
d.value = False
row_pins.append(d)
col_pins = []
for p in COLS:
d = digitalio.DigitalInOut(p)
d.direction = digitalio.Direction.INPUT
d.pull = digitalio.Pull.DOWN
col_pins.append(d)
midi = MIDI(midi_out=usb_midi.ports[1], out_channel=0)
key_states = [False] * (8 * 8)
def scan_matrix():
pressed = []
for r, row in enumerate(row_pins):
row.value = True
time.sleep(0.0001)
for c, col in enumerate(col_pins):
if col.value:
pressed.append(r * 8 + c)
row.value = False
return pressed
print("MIDI matrix ready")
while True:
current = scan_matrix()
for i in range(64):
note = FIRST_NOTE + i
now = (i in current)
prev = key_states[i]
if now and not prev:
midi.send(NoteOn(note, 100))
key_states[i] = True
elif not now and prev:
midi.send(NoteOff(note, 0))
key_states[i] = False
time.sleep(DEBOUNCE_DELAY)Configuration
- ROWS: GPIO pins 2-9 (outputs for row selection)
- COLS: GPIO pins 10-17 (inputs for column detection)
- FIRST_NOTE: MIDI note 36 (C2) - adjust as needed
- Key Matrix: 8x8 = 64 keys maximum