Adafruit_Learning_System_Gu.../Laser_Harp/usb_midi_code.py
2022-12-21 15:43:26 -05:00

110 lines
3.7 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
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
# 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))