/ PowerGlove_BLE_MIDI / code.py
code.py
1 # SPDX-FileCopyrightText: 2021 John Park for Adafruit Industries. 2 # 3 # SPDX-License-Identifier: MIT 4 """ 5 Power Glove BLE MIDI with Feather Sense nRF52840 6 Sends MIDI CC values based on finger flex sensors and accelerometer 7 """ 8 import time 9 import board 10 import adafruit_ble 11 from adafruit_ble.advertising.standard import ProvideServicesAdvertisement 12 import adafruit_ble_midi 13 import adafruit_midi 14 from adafruit_midi.control_change import ControlChange 15 # from adafruit_midi.note_on import NoteOn 16 # from adafruit_midi.pitch_bend import PitchBend 17 import adafruit_lsm6ds.lsm6ds33 # accelerometer 18 import simpleio 19 from analogio import AnalogIn 20 21 i2c = board.I2C() 22 sense_accel = adafruit_lsm6ds.lsm6ds33.LSM6DS33(i2c) 23 24 analog_in_thumb = AnalogIn(board.A3) 25 analog_in_index = AnalogIn(board.A2) 26 analog_in_middle = AnalogIn(board.A1) 27 analog_in_ring = AnalogIn(board.A0) 28 29 # Pick your MIDI CC numbers here 30 cc_x_num = 7 # volume 31 cc_y_num = 70 # unassigned 32 cc_thumb_num = 71 # unassigned 33 cc_index_num = 75 # unassigned 34 cc_middle_num = 76 # unassigned 35 cc_ring_num = 77 # unassigned 36 37 midi_channel = 1 # pick your midi out channel here 38 39 # Use default HID descriptor 40 midi_service = adafruit_ble_midi.MIDIService() 41 advertisement = ProvideServicesAdvertisement(midi_service) 42 43 ble = adafruit_ble.BLERadio() 44 if ble.connected: 45 for c in ble.connections: 46 c.disconnect() 47 48 midi = adafruit_midi.MIDI(midi_out=midi_service, out_channel=midi_channel - 1) 49 50 print("advertising") 51 ble.name="Power Glove MIDI" 52 ble.start_advertising(advertisement) 53 54 # reads an analog pin and returns value remapped to out range, e.g., 0-127 55 def get_flex_cc(sensor, low_in, high_in, min_out, max_out): 56 flex_raw = sensor.value 57 flex_cc = simpleio.map_range(flex_raw, low_in, high_in, min_out, max_out) 58 flex_cc = int(flex_cc) 59 return flex_cc 60 61 62 debug = False # set debug mode True to test raw values, set False to run BLE MIDI 63 64 while True: 65 if debug: 66 accel_data = sense_accel.acceleration # get accelerometer reading 67 accel_x = accel_data[0] 68 accel_y = accel_data[1] 69 accel_z = accel_data[2] 70 71 print( 72 "x:{} y:{} z:{} thumb:{} index:{} middle:{} ring:{}".format( 73 accel_x, 74 accel_y, 75 accel_x, 76 analog_in_thumb.value, 77 analog_in_index.value, 78 analog_in_middle.value, 79 analog_in_ring.value, 80 ) 81 ) 82 time.sleep(0.2) 83 84 else: 85 print("Waiting for connection") 86 while not ble.connected: 87 pass 88 print("Connected") 89 while ble.connected: 90 # Feather Sense accelerometer readings to CC 91 accel_data = sense_accel.acceleration # get accelerometer reading 92 accel_x = accel_data[0] 93 accel_y = accel_data[1] 94 # accel_z = accel_data[2] 95 # Remap analog readings to cc range 96 cc_x = int(simpleio.map_range(accel_x, 0, 9, 127, 0)) 97 cc_y = int(simpleio.map_range(accel_y, 1, -9, 0, 127)) 98 99 cc_thumb = get_flex_cc(analog_in_thumb, 49000, 35000, 127, 0) 100 cc_index = get_flex_cc(analog_in_index, 50000, 35000, 0, 127) 101 cc_middle = get_flex_cc(analog_in_middle, 55000, 40000, 0, 127) 102 cc_ring = get_flex_cc(analog_in_ring, 55000, 42000, 0, 127) 103 ''' 104 print( 105 "CC_X:{} CC_Y:{} CC_Thumb:{} CC_Index:{} CC_Middle:{} CC_Ring:{}".format( 106 cc_x, cc_y, cc_thumb, cc_index, cc_middle, cc_ring 107 ) 108 )''' 109 110 # send all the midi messages in a list 111 midi.send( 112 [ 113 ControlChange(cc_x_num, cc_x), 114 ControlChange(cc_y_num, cc_y), 115 ControlChange(cc_thumb_num, cc_thumb), 116 ControlChange(cc_index_num, cc_index), 117 ControlChange(cc_middle_num, cc_middle), 118 ControlChange(cc_ring_num, cc_ring), 119 ] 120 ) 121 122 # If you want to send NoteOn or Pitch Bend, here are examples: 123 # midi.send(NoteOn(44, 120)) # G sharp 2nd octave 124 # a_pitch_bend = PitchBend(random.randint(0, 16383)) 125 # midi.send(a_pitch_bend) 126 127 print("Disconnected") 128 print() 129 ble.start_advertising(advertisement)