|
|
@@ -0,0 +1,139 @@
|
|
|
+
|
|
|
+import time
|
|
|
+from midi.midiout import MidiOut
|
|
|
+from midi import constants_min
|
|
|
+from machine import UART
|
|
|
+from machine import ADC
|
|
|
+import uos
|
|
|
+
|
|
|
+DEBUG = 0
|
|
|
+
|
|
|
+def main():
|
|
|
+ global DEBUG
|
|
|
+
|
|
|
+ led = machine.Pin(2 , machine.Pin.OUT)
|
|
|
+ led.value(1)
|
|
|
+ adc_pin = 0
|
|
|
+ adc = ADC(adc_pin)
|
|
|
+
|
|
|
+ # multi_pins = [machine.Pin(16 , machine.Pin.OUT)]
|
|
|
+ wheel = PitchWheel(adc)
|
|
|
+ but = StatePin(0, machine.Pin.IN, machine.Pin.PULL_UP)
|
|
|
+
|
|
|
+ reset_midi()
|
|
|
+
|
|
|
+ print("\nWaiting for Interrupt....")
|
|
|
+ time.sleep(5)
|
|
|
+ print("\nDetaching Terminal for MIDI....")
|
|
|
+
|
|
|
+
|
|
|
+ if but.value() == 1:
|
|
|
+ DEBUG = 0
|
|
|
+ else:
|
|
|
+ DEBUG = 1
|
|
|
+
|
|
|
+ if not DEBUG:
|
|
|
+ uos.dupterm(None, 1)
|
|
|
+ uart = UART(DEBUG, baudrate=115200)
|
|
|
+ midiout = MidiOut(uart)
|
|
|
+
|
|
|
+
|
|
|
+ # # Send all sound off to prevent hanging notes
|
|
|
+ midiout.control_change(0x78, 0)
|
|
|
+
|
|
|
+ midiout.program_change(0) # Acoustic Piano per General MIDI standard
|
|
|
+ midiout.control_change(constants_min.LEGATO_ONOFF, 0)
|
|
|
+ midiout.control_change(constants_min.LEGATO_ONOFF, 127)
|
|
|
+
|
|
|
+ while True:
|
|
|
+ time.sleep_ms(5)
|
|
|
+ but.poll(lambda v: midi_note(midiout, v, led = led))
|
|
|
+ wheel.poll(midiout.pitch_bend)
|
|
|
+
|
|
|
+class PitchWheel():
|
|
|
+ _value = 0
|
|
|
+ _min = 24
|
|
|
+ _max = 1000
|
|
|
+ size = 16368
|
|
|
+ pins = []
|
|
|
+ values = []
|
|
|
+ adc = None
|
|
|
+
|
|
|
+ def __init__(self, adc, pins = [], values = [], size = 16368):
|
|
|
+ self.pins = pins
|
|
|
+ self.values = values
|
|
|
+ self.size = size
|
|
|
+ self.adc = adc
|
|
|
+
|
|
|
+ def value(self):
|
|
|
+ for pin,value in zip(self.pins, self.values):
|
|
|
+ pin.value(value)
|
|
|
+ if len(self.pins) != 0:
|
|
|
+ time.sleep_ms(1)
|
|
|
+ val = self.adc.read()
|
|
|
+ if self._value != val:
|
|
|
+ self._value = val
|
|
|
+ if self._min > val:
|
|
|
+ self._min = val
|
|
|
+ if self._max < val:
|
|
|
+ self._max = val
|
|
|
+ return val
|
|
|
+ return None
|
|
|
+
|
|
|
+ def calibrate(self, val):
|
|
|
+ val_float = (val/(self._max - self._min))
|
|
|
+ return int(min(max((self.size * val_float), 0), self.size))
|
|
|
+
|
|
|
+ def poll(self, cb=None):
|
|
|
+ val = self.value()
|
|
|
+ if val != None:
|
|
|
+ if DEBUG == 1:
|
|
|
+ print("Wheel:", self.values, [self._min, self._max],val,self.calibrate(val))
|
|
|
+ elif cb != None:
|
|
|
+ cb(self.calibrate(val))
|
|
|
+
|
|
|
+class StatePin(machine.Pin):
|
|
|
+ state = 1
|
|
|
+
|
|
|
+ def poll(self, cb=None):
|
|
|
+
|
|
|
+ val = self.value()
|
|
|
+ if val != self.state:
|
|
|
+ self.state = val
|
|
|
+ if DEBUG == 1:
|
|
|
+ print(self, val)
|
|
|
+ else:
|
|
|
+ if cb != None:
|
|
|
+ cb(val)
|
|
|
+
|
|
|
+def midi_note(midiout, val, note=64, led = None):
|
|
|
+ if led:
|
|
|
+ led.value(val)
|
|
|
+ if val == 0:
|
|
|
+ midiout.note_on(note, velocity=100)
|
|
|
+ else:
|
|
|
+ midiout.note_off(note)
|
|
|
+
|
|
|
+def reset_midi():
|
|
|
+ uos.dupterm(None, 1)
|
|
|
+ uart = machine.UART(0, 115200)
|
|
|
+ mdo = MidiOut(uart)
|
|
|
+ mdo.control_change(0x78, 0)
|
|
|
+
|
|
|
+ uart = machine.UART(0, 115200)
|
|
|
+ uos.dupterm(uart, 1)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ try:
|
|
|
+ main()
|
|
|
+ except Exception as ex:
|
|
|
+ reset_midi()
|
|
|
+ raise ex
|
|
|
+#
|
|
|
+# def bend_note():
|
|
|
+# val = adc.read()
|
|
|
+# return 60+int(val/64)
|
|
|
+#
|