adding two more examples for the laser harp project one is code using usb midi instead of midi over uart second is two voices depending on height as well as pitch bend control
109 lines
3.6 KiB
Python
109 lines
3.6 KiB
Python
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
import board
|
|
import simpleio
|
|
import adafruit_vl53l4cd
|
|
import adafruit_tca9548a
|
|
import usb_midi
|
|
import adafruit_midi
|
|
from adafruit_midi.note_off import NoteOff
|
|
from adafruit_midi.note_on import NoteOn
|
|
from adafruit_midi.control_change import ControlChange
|
|
|
|
# Create I2C bus as normal
|
|
i2c = board.I2C() # uses board.SCL and board.SDA
|
|
|
|
# Create the TCA9548A object and give it the I2C bus
|
|
tca = adafruit_tca9548a.TCA9548A(i2c)
|
|
|
|
# setup time of flight sensors to use TCA9548A inputs
|
|
tof_0 = adafruit_vl53l4cd.VL53L4CD(tca[0])
|
|
tof_1 = adafruit_vl53l4cd.VL53L4CD(tca[1])
|
|
tof_2 = adafruit_vl53l4cd.VL53L4CD(tca[2])
|
|
tof_3 = adafruit_vl53l4cd.VL53L4CD(tca[3])
|
|
tof_4 = adafruit_vl53l4cd.VL53L4CD(tca[4])
|
|
tof_5 = adafruit_vl53l4cd.VL53L4CD(tca[5])
|
|
tof_6 = adafruit_vl53l4cd.VL53L4CD(tca[6])
|
|
tof_7 = adafruit_vl53l4cd.VL53L4CD(tca[7])
|
|
|
|
# array of tof sensors
|
|
flights = [tof_0, tof_1, tof_2, tof_3, tof_4, tof_5, tof_6, tof_7]
|
|
|
|
# setup each tof sensor
|
|
for flight in flights:
|
|
flight.inter_measurement = 0
|
|
flight.timing_budget = 50
|
|
flight.start_ranging()
|
|
|
|
midi_in_channel = 1
|
|
midi_out_channel = 1
|
|
# midi setup
|
|
# USB is setup as the input
|
|
midi = adafruit_midi.MIDI(
|
|
midi_out=usb_midi.ports[1],
|
|
in_channel=(midi_in_channel - 1),
|
|
out_channel=(midi_out_channel - 1),
|
|
debug=False,
|
|
)
|
|
|
|
# state of each tof sensor
|
|
# tracks if you have hit the laser range
|
|
pluck_0 = False
|
|
pluck_1 = False
|
|
pluck_2 = False
|
|
pluck_3 = False
|
|
pluck_4 = False
|
|
pluck_5 = False
|
|
pluck_6 = False
|
|
pluck_7 = False
|
|
|
|
# array of tof sensor states
|
|
plucks = [pluck_0, pluck_1, pluck_2, pluck_3, pluck_4, pluck_5, pluck_6, pluck_7]
|
|
|
|
# height cutoff for tof sensors
|
|
# adjust depending on the height of your ceiling/performance area
|
|
flight_height = 150
|
|
|
|
# midi notes for each tof sensor
|
|
notes = [48, 52, 55, 59, 60, 64, 67, 71]
|
|
|
|
while True:
|
|
# iterate through the 8 tof sensors
|
|
for f in range(8):
|
|
while not flights[f].data_ready:
|
|
pass
|
|
# reset tof sensors
|
|
flights[f].clear_interrupt()
|
|
# if the reading from a tof is not 0...
|
|
if flights[f].distance != 0.0:
|
|
# map range of tof sensor distance to midi parameters
|
|
# modulation
|
|
mod = round(simpleio.map_range(flights[f].distance, 0, 100, 120, 0))
|
|
# sustain
|
|
sus = round(simpleio.map_range(flights[f].distance, 0, 100, 127, 0))
|
|
# velocity
|
|
vel = round(simpleio.map_range(flights[f].distance, 0, 150, 120, 0))
|
|
modulation = int(mod)
|
|
sustain = int(sus)
|
|
# create sustain and modulation CC message
|
|
pedal = ControlChange(71, sustain)
|
|
modWheel = ControlChange(1, modulation)
|
|
# send the sustain and modulation messages
|
|
midi.send([modWheel, pedal])
|
|
# if tof registers a height lower than the set max height...
|
|
if int(flights[f].distance) < flight_height and not plucks[f]:
|
|
# set state tracker
|
|
plucks[f] = True
|
|
# convert tof distance to a velocity value
|
|
velocity = int(vel)
|
|
# send midi note with velocity and sustain message
|
|
midi.send([NoteOn(notes[f], velocity), pedal])
|
|
# if tof registers a height = to or greater than set max height
|
|
# aka you remove your hand from above the sensor...
|
|
if int(flights[f].distance) > flight_height and plucks[f]:
|
|
# reset state
|
|
plucks[f] = False
|
|
# send midi note off
|
|
midi.send(NoteOff(notes[f], velocity))
|