BLE MIDI lets you send MIDI data wirelessly over Bluetooth. In this example, you'll use a CLUE to send arpeggios to a DAW.
This example uses an Adafruit CLUE microcontroller board. To make sure it is setup properly with CircuitPython, please follow the steps in the guide below.
Once you've finished setting up your CLUE 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 time
import adafruit_ble
import touchio
import board
import adafruit_midi
import adafruit_ble_midi
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
# CLUE cap touch setup
c_touch = touchio.TouchIn(board.D0)
f_touch = touchio.TouchIn(board.D1)
g_touch = touchio.TouchIn(board.D2)
# array of touch pads
pads = [c_touch, f_touch, g_touch]
# BLE MIDI setup
midi_service = adafruit_ble_midi.MIDIService()
advertisement = ProvideServicesAdvertisement(midi_service)
ble = adafruit_ble.BLERadio()
if ble.connected:
for c in ble.connections:
c.disconnect()
# midi setup
midi = adafruit_midi.MIDI(midi_out=midi_service, out_channel=0)
print("advertising")
ble.start_advertising(advertisement)
# MIDI note numbers for C, F and G major triads
c_triad = (60, 64, 67)
f_triad = (65, 69, 72)
g_triad = (67, 71, 74)
# array of triads
triads = [c_triad, f_triad, g_triad]
# touch debounce states
c_pressed = False
f_pressed = False
g_pressed = False
# array of debounce states
triad_states = [c_pressed, f_pressed, g_pressed]
# beginning triad
active_triad = c_triad
# variable for triad index
z = 0
while True:
# BLE connection
print("Waiting for connection")
while not ble.connected:
pass
print("Connected")
time.sleep(1.0)
# while BLE is connected...
while ble.connected:
# iterate through the touch inputs
for i in range(3):
inputs = pads[i]
# if a touch input is detected...
if inputs.value and triad_states[i] is False:
# debounce state activated
triad_states[i] = True
# update triad
active_triad = triads[i]
print(active_triad)
# after touch input...
if not inputs.value and triad_states[i] is True:
# reset debounce state
triad_states[i] = False
# send triad arpeggios out with half second delay
midi.send(NoteOn(active_triad[z]))
time.sleep(0.5)
midi.send(NoteOff(active_triad[z]))
time.sleep(0.5)
# increase index by 1
z += 1
# reset index at end of triad
if z > 2:
z = 0
# BLE connection
print("Disconnected")
print()
ble.start_advertising(advertisement)
After downloading the Project Bundle, plug your CLUE 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 CLUE's CIRCUITPY drive.
- lib folder
- code.py
Your CLUE CIRCUITPY drive should look like this after copying the lib folder and the code.py file.
There are three sequences of MIDI note numbers setup: c_triad, f_triad and g_triad. These correspond with the CLUE's three capacitive touch inputs.
In the loop, NoteOn and NoteOff messages are sent every 0.5 seconds to play through the triad. If a touch input is detected, then the triad updates.
The code is using BLE MIDI to utilize the CLUE's nRF52840. The loop is dependent on a BLE connection being active, otherwise the CLUE will wait for a connection.
You can connect your CLUE via BLE to your computer or mobile device. After a BLE connection is established, open your preferred music software to send the arpeggios to a software synth. Tap the three capacitive touch inputs to change the chord.
Going further, you could change the notes being sent and also play with the timing for sending the notes. You could use an additional input to code up a tap tempo to set the beats per minute (BPM) for sending notes.
Page last edited January 22, 2025
Text editor powered by tinymce.