To use with CircuitPython, you need to first install a few libraries, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory BLE_MIDI_ROBOT_Xylophone/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.
CIRCUITPY
# SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import board
import busio
from adafruit_mcp230xx.mcp23017 import MCP23017
from digitalio import Direction
import adafruit_ble
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
import adafruit_ble_midi
# These import auto-register the message type with the MIDI machinery.
# pylint: disable=unused-import
import adafruit_midi
from adafruit_midi.control_change import ControlChange
from adafruit_midi.midi_message import MIDIUnknownEvent
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
from adafruit_midi.pitch_bend import PitchBend
# i2c setup
i2c = busio.I2C(board.SCL, board.SDA)
# i2c addresses for muxes
mcp1 = MCP23017(i2c, address=0x20)
mcp2 = MCP23017(i2c, address=0x21)
# 1st solenoid array, corresponds with 1st mux
noids0 = []
for pin in range(16):
noids0.append(mcp1.get_pin(pin))
for n in noids0:
n.direction = Direction.OUTPUT
# 2nd solenoid array, corresponds with 2nd mux
noids1 = []
for pin in range(16):
noids1.append(mcp2.get_pin(pin))
for n in noids1:
n.direction = Direction.OUTPUT
# MIDI note arrays. notes0 = noids0; notes1 = noids1
notes0 = [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70]
notes1 = [71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]
# setup MIDI BLE service
midi_service = adafruit_ble_midi.MIDIService()
advertisement = ProvideServicesAdvertisement(midi_service)
# BLE connection setup
ble = adafruit_ble.BLERadio()
if ble.connected:
for c in ble.connections:
c.disconnect()
# MIDI in setup
midi = adafruit_midi.MIDI(midi_in=midi_service, in_channel=0)
# start BLE advertising
print("advertising")
ble.start_advertising(advertisement)
# delay for solenoids
speed = 0.01
while True:
# waiting for BLE connection
print("Waiting for connection")
while not ble.connected:
pass
print("Connected")
# delay after connection established
time.sleep(1.0)
while ble.connected:
# msg holds MIDI messages
msg = midi.receive()
for i in range(16):
# states for solenoid on/off
# noid0 = mux1
# noid1 = mux2
noid0_output = noids0[i]
noid1_output = noids1[i]
# states for MIDI note recieved
# notes0 = mux1
# notes1 = mux2
notes0_played = notes0[i]
notes1_played = notes1[i]
# if NoteOn msg comes in and the MIDI note # matches with predefined notes:
if isinstance(msg, NoteOn) and msg.note is notes0_played:
print(time.monotonic(), msg.note)
# solenoid is triggered
noid0_output.value = True
# quick delay
time.sleep(speed)
# solenoid retracts
noid0_output.value = False
# identical to above if statement but for mux2
if isinstance(msg, NoteOn) and msg.note is notes1_played:
print(time.monotonic(), msg.note)
noid1_output.value = True
time.sleep(speed)
noid1_output.value = False
# if BLE disconnects try reconnecting
print("Disconnected")
print()
ble.start_advertising(advertisement)
Page last edited January 21, 2025
Text editor powered by tinymce.