Skip to content

Commit 86c6bf5

Browse files
committed
adding more laser harp examples
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
1 parent 7c9dc8d commit 86c6bf5

File tree

2 files changed

+236
-0
lines changed

2 files changed

+236
-0
lines changed

Laser_Harp/laser_harp_two_voice.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import board
5+
import busio
6+
import simpleio
7+
import adafruit_vl53l4cd
8+
import adafruit_midi
9+
from adafruit_midi.note_off import NoteOff
10+
from adafruit_midi.note_on import NoteOn
11+
from adafruit_midi.program_change import ProgramChange
12+
# uncomment if using volume CC message in the loop
13+
# from adafruit_midi.control_change import ControlChange
14+
from adafruit_midi.pitch_bend import PitchBend
15+
import adafruit_tca9548a
16+
17+
# Create I2C bus as normal
18+
i2c = board.I2C() # uses board.SCL and board.SDA
19+
20+
# Create the TCA9548A object and give it the I2C bus
21+
tca = adafruit_tca9548a.TCA9548A(i2c)
22+
23+
tof_0 = adafruit_vl53l4cd.VL53L4CD(tca[0])
24+
tof_1 = adafruit_vl53l4cd.VL53L4CD(tca[1])
25+
tof_2 = adafruit_vl53l4cd.VL53L4CD(tca[2])
26+
tof_3 = adafruit_vl53l4cd.VL53L4CD(tca[3])
27+
tof_4 = adafruit_vl53l4cd.VL53L4CD(tca[4])
28+
tof_5 = adafruit_vl53l4cd.VL53L4CD(tca[5])
29+
tof_6 = adafruit_vl53l4cd.VL53L4CD(tca[6])
30+
tof_7 = adafruit_vl53l4cd.VL53L4CD(tca[7])
31+
32+
flights = [tof_0, tof_1, tof_2, tof_3, tof_4, tof_5, tof_6, tof_7]
33+
34+
for flight in flights:
35+
flight.inter_measurement = 0
36+
flight.timing_budget = 50
37+
flight.start_ranging()
38+
39+
# midi uart setup for music maker featherwing
40+
uart = busio.UART(board.TX, board.RX, baudrate=31250)
41+
42+
midi_in_channel = 1
43+
midi_out_channel = 1
44+
# midi setup
45+
# UART is setup as the input
46+
midi = adafruit_midi.MIDI(
47+
midi_in=uart,
48+
midi_out=uart,
49+
in_channel=(midi_in_channel - 1),
50+
out_channel=(midi_out_channel - 1),
51+
debug=False,
52+
)
53+
54+
flight_height = 150
55+
56+
pluck_0 = False
57+
pluck_1 = False
58+
pluck_2 = False
59+
pluck_3 = False
60+
pluck_4 = False
61+
pluck_5 = False
62+
pluck_6 = False
63+
pluck_7 = False
64+
65+
plucks = [pluck_0, pluck_1, pluck_2, pluck_3, pluck_4, pluck_5, pluck_6, pluck_7]
66+
67+
low_notes = [28, 32, 35, 36, 40, 43, 47, 48]
68+
high_notes = [52, 55, 59, 60, 64, 67, 71, 72]
69+
70+
heights = [0, 0, 0, 0, 0, 0, 0]
71+
72+
bend_sense = 5
73+
vel = 120
74+
75+
while True:
76+
for f in range(8):
77+
while not flights[f].data_ready:
78+
pass
79+
flights[f].clear_interrupt()
80+
if flights[f].distance != 0.0:
81+
if int(flights[f].distance) < flight_height:
82+
if int(flights[f].distance) < 30 and not plucks[f]:
83+
bass = ProgramChange(81)
84+
vel = round(simpleio.map_range(flights[f].distance, 0, 30, 127, 75))
85+
bend_sense = 5
86+
velocity = int(vel)
87+
# send midi message
88+
midi.send([bass, NoteOn(low_notes[f], velocity)])
89+
plucks[f] = True
90+
heights[f] = int(flights[f].distance)
91+
if (int(flights[f].distance) > 40) and not plucks[f]:
92+
lead = ProgramChange(54)
93+
vel = round(simpleio.map_range(flights[f].distance, 30, flight_height, 127, 75))
94+
bend_sense = 10
95+
velocity = int(vel)
96+
# send midi message
97+
midi.send([lead, NoteOn(high_notes[f], velocity)])
98+
plucks[f] = True
99+
heights[f] = int(flights[f].distance)
100+
# this section affects pitchbend OR volume control_change while you are playing a note
101+
# comment/uncomment lines to change effect affected
102+
if abs(int(flights[f].distance) - heights[f]) > bend_sense and plucks[f]:
103+
bend_up = round(simpleio.map_range(flights[f].distance, heights[f], flight_height,
104+
8192, 16383))
105+
bend_down = round(simpleio.map_range(flights[f].distance, heights[f], 0,
106+
8192, 0))
107+
'''vol_up = round(simpleio.map_range(flights[f].distance, heights[f], flight_height,
108+
velocity, 0))
109+
vol_down = round(simpleio.map_range(flights[f].distance, heights[f], 0,
110+
velocity, 127))'''
111+
if int(flights[f].distance) > heights[f]:
112+
pitchUp = PitchBend(int(bend_up))
113+
midi.send(pitchUp)
114+
# volume = ControlChange(7, int(vol_down))
115+
# midi.send(volume)
116+
print("bend up!")
117+
if int(flights[f].distance) < heights[f]:
118+
pitchDown = PitchBend(int(bend_down))
119+
midi.send(pitchDown)
120+
# volume = ControlChange(7, int(vol_up))
121+
# midi.send(volume)
122+
print("bend down!")
123+
# send note off message
124+
if int(flights[f].distance) > flight_height and plucks[f]:
125+
plucks[f] = False
126+
midi.send(NoteOff(low_notes[f], velocity))
127+
midi.send(NoteOff(high_notes[f], velocity))

Laser_Harp/usb_midi_code.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import board
6+
import simpleio
7+
import adafruit_vl53l4cd
8+
import adafruit_tca9548a
9+
import usb_midi
10+
import adafruit_midi
11+
from adafruit_midi.note_off import NoteOff
12+
from adafruit_midi.note_on import NoteOn
13+
from adafruit_midi.control_change import ControlChange
14+
15+
# Create I2C bus as normal
16+
i2c = board.I2C() # uses board.SCL and board.SDA
17+
18+
# Create the TCA9548A object and give it the I2C bus
19+
tca = adafruit_tca9548a.TCA9548A(i2c)
20+
21+
# setup time of flight sensors to use TCA9548A inputs
22+
tof_0 = adafruit_vl53l4cd.VL53L4CD(tca[0])
23+
tof_1 = adafruit_vl53l4cd.VL53L4CD(tca[1])
24+
tof_2 = adafruit_vl53l4cd.VL53L4CD(tca[2])
25+
tof_3 = adafruit_vl53l4cd.VL53L4CD(tca[3])
26+
tof_4 = adafruit_vl53l4cd.VL53L4CD(tca[4])
27+
tof_5 = adafruit_vl53l4cd.VL53L4CD(tca[5])
28+
tof_6 = adafruit_vl53l4cd.VL53L4CD(tca[6])
29+
tof_7 = adafruit_vl53l4cd.VL53L4CD(tca[7])
30+
31+
# array of tof sensors
32+
flights = [tof_0, tof_1, tof_2, tof_3, tof_4, tof_5, tof_6, tof_7]
33+
34+
# setup each tof sensor
35+
for flight in flights:
36+
flight.inter_measurement = 0
37+
flight.timing_budget = 50
38+
flight.start_ranging()
39+
40+
midi_in_channel = 1
41+
midi_out_channel = 1
42+
# midi setup
43+
# USB is setup as the input
44+
midi = adafruit_midi.MIDI(
45+
midi_out=usb_midi.ports[1],
46+
in_channel=(midi_in_channel - 1),
47+
out_channel=(midi_out_channel - 1),
48+
debug=False,
49+
)
50+
51+
# state of each tof sensor
52+
# tracks if you have hit the laser range
53+
pluck_0 = False
54+
pluck_1 = False
55+
pluck_2 = False
56+
pluck_3 = False
57+
pluck_4 = False
58+
pluck_5 = False
59+
pluck_6 = False
60+
pluck_7 = False
61+
62+
# array of tof sensor states
63+
plucks = [pluck_0, pluck_1, pluck_2, pluck_3, pluck_4, pluck_5, pluck_6, pluck_7]
64+
65+
# height cutoff for tof sensors
66+
# adjust depending on the height of your ceiling/performance area
67+
flight_height = 150
68+
69+
# midi notes for each tof sensor
70+
notes = [48, 52, 55, 59, 60, 64, 67, 71]
71+
72+
while True:
73+
# iterate through the 8 tof sensors
74+
for f in range(8):
75+
while not flights[f].data_ready:
76+
pass
77+
# reset tof sensors
78+
flights[f].clear_interrupt()
79+
# if the reading from a tof is not 0...
80+
if flights[f].distance != 0.0:
81+
# map range of tof sensor distance to midi parameters
82+
# modulation
83+
mod = round(simpleio.map_range(flights[f].distance, 0, 100, 120, 0))
84+
# sustain
85+
sus = round(simpleio.map_range(flights[f].distance, 0, 100, 127, 0))
86+
# velocity
87+
vel = round(simpleio.map_range(flights[f].distance, 0, 150, 120, 0))
88+
modulation = int(mod)
89+
sustain = int(sus)
90+
# create sustain and modulation CC message
91+
pedal = ControlChange(71, sustain)
92+
modWheel = ControlChange(1, modulation)
93+
# send the sustain and modulation messages
94+
midi.send([modWheel, pedal])
95+
# if tof registers a height lower than the set max height...
96+
if int(flights[f].distance) < flight_height and not plucks[f]:
97+
# set state tracker
98+
plucks[f] = True
99+
# convert tof distance to a velocity value
100+
velocity = int(vel)
101+
# send midi note with velocity and sustain message
102+
midi.send([NoteOn(notes[f], velocity), pedal])
103+
# if tof registers a height = to or greater than set max height
104+
# aka you remove your hand from above the sensor...
105+
if int(flights[f].distance) > flight_height and plucks[f]:
106+
# reset state
107+
plucks[f] = False
108+
# send midi note off
109+
midi.send(NoteOff(notes[f], velocity))

0 commit comments

Comments
 (0)