Adafruit_Learning_System_Gu.../BLE_MIDI_Robot_Xylophone/code.py
2022-02-23 13:00:24 -05:00

122 lines
3.2 KiB
Python

# 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)