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)