/ BLE_MIDI_Robot_Xylophone / code.py
code.py
1 # SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 import time 6 import board 7 import busio 8 from adafruit_mcp230xx.mcp23017 import MCP23017 9 from digitalio import Direction 10 import adafruit_ble 11 from adafruit_ble.advertising.standard import ProvideServicesAdvertisement 12 import adafruit_ble_midi 13 14 # These import auto-register the message type with the MIDI machinery. 15 # pylint: disable=unused-import 16 import adafruit_midi 17 from adafruit_midi.control_change import ControlChange 18 from adafruit_midi.midi_message import MIDIUnknownEvent 19 from adafruit_midi.note_off import NoteOff 20 from adafruit_midi.note_on import NoteOn 21 from adafruit_midi.pitch_bend import PitchBend 22 23 # i2c setup 24 i2c = busio.I2C(board.SCL, board.SDA) 25 26 # i2c addresses for muxes 27 mcp1 = MCP23017(i2c, address=0x20) 28 mcp2 = MCP23017(i2c, address=0x21) 29 30 # 1st solenoid array, corresponds with 1st mux 31 noids0 = [] 32 33 for pin in range(16): 34 noids0.append(mcp1.get_pin(pin)) 35 for n in noids0: 36 n.direction = Direction.OUTPUT 37 38 # 2nd solenoid array, corresponds with 2nd mux 39 noids1 = [] 40 41 for pin in range(16): 42 noids1.append(mcp2.get_pin(pin)) 43 for n in noids1: 44 n.direction = Direction.OUTPUT 45 46 # MIDI note arrays. notes0 = noids0; notes1 = noids1 47 notes0 = [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70] 48 notes1 = [71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86] 49 50 # setup MIDI BLE service 51 midi_service = adafruit_ble_midi.MIDIService() 52 advertisement = ProvideServicesAdvertisement(midi_service) 53 54 # BLE connection setup 55 ble = adafruit_ble.BLERadio() 56 if ble.connected: 57 for c in ble.connections: 58 c.disconnect() 59 60 # MIDI in setup 61 midi = adafruit_midi.MIDI(midi_in=midi_service, in_channel=0) 62 63 # start BLE advertising 64 print("advertising") 65 ble.start_advertising(advertisement) 66 67 # delay for solenoids 68 speed = 0.01 69 70 while True: 71 72 # waiting for BLE connection 73 print("Waiting for connection") 74 while not ble.connected: 75 pass 76 print("Connected") 77 # delay after connection established 78 time.sleep(1.0) 79 80 while ble.connected: 81 82 # msg holds MIDI messages 83 msg = midi.receive() 84 85 for i in range(16): 86 # states for solenoid on/off 87 # noid0 = mux1 88 # noid1 = mux2 89 noid0_output = noids0[i] 90 noid1_output = noids1[i] 91 92 # states for MIDI note recieved 93 # notes0 = mux1 94 # notes1 = mux2 95 notes0_played = notes0[i] 96 notes1_played = notes1[i] 97 98 # if NoteOn msg comes in and the MIDI note # matches with predefined notes: 99 if isinstance(msg, NoteOn) and msg.note is notes0_played: 100 print(time.monotonic(), msg.note) 101 102 # solenoid is triggered 103 noid0_output.value = True 104 # quick delay 105 time.sleep(speed) 106 # solenoid retracts 107 noid0_output.value = False 108 109 # identical to above if statement but for mux2 110 if isinstance(msg, NoteOn) and msg.note is notes1_played: 111 print(time.monotonic(), msg.note) 112 113 noid1_output.value = True 114 115 time.sleep(speed) 116 117 noid1_output.value = False 118 119 # if BLE disconnects try reconnecting 120 print("Disconnected") 121 print() 122 ble.start_advertising(advertisement)