/ Flying_Fader / code.py
code.py
1 # SPDX-FileCopyrightText: 2022 John Park for Adafruit Industries 2 # SPDX-License-Identifier: MIT 3 # Motorized fader demo 4 import time 5 import board 6 import pwmio 7 import analogio 8 import touchio 9 import neopixel 10 from digitalio import DigitalInOut, Pull 11 from adafruit_debouncer import Debouncer 12 from adafruit_motor import motor 13 14 MIDI_DEMO = False # set to True to send MIDI CC 15 16 # optional MIDI setup 17 if MIDI_DEMO: 18 import usb_midi 19 import adafruit_midi 20 from adafruit_midi.control_change import ControlChange 21 midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0) 22 fader_cc_number = 16 23 24 # Button setup to store four saved values 25 button_pins = (board.D10, board.D9, board.D6, board.D5) 26 buttons = [] 27 for button_pin in button_pins: 28 tmp_pin = DigitalInOut(button_pin) 29 tmp_pin.pull = Pull.UP 30 buttons.append(Debouncer(tmp_pin)) 31 32 saved_positions = (230, 180, 120, 60) # pre-saved positions for the buttons to call 33 34 # Slide pot setup 35 fader = analogio.AnalogIn(board.A0) 36 fader_position = fader.value # ranges from 0-65535 37 fader_pos = fader.value // 256 # make 0-255 range 38 last_fader_pos = fader_pos 39 40 # Motor setup 41 PWM_PIN_A = board.D12 # pick any pwm pins on their own channels 42 PWM_PIN_B = board.D11 43 44 # DC motor driver setup -- these pins go to h-bridge driver such as L9110 45 pwm_a = pwmio.PWMOut(PWM_PIN_A, frequency=50) 46 pwm_b = pwmio.PWMOut(PWM_PIN_B, frequency=50) 47 motor1 = motor.DCMotor(pwm_a, pwm_b) 48 49 # Touch setup pin goes from touch pin on slide pot to touch capable pin and then 1MΩ to gnd 50 touch = touchio.TouchIn(board.A3) 51 touch.threshold = touch.raw_value + 30 # tune for fader knob cap 52 53 # NeoPixel setup 54 led = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2, auto_write=True) 55 led.fill(0xff0000) 56 57 def clamp(num, min_value, max_value): # function for clamping motor throttle -1.0 to 1.0 58 return max(min(num, max_value), min_value) 59 60 def go_to_position(new_position): 61 global fader_pos # pylint: disable=global-statement 62 fader_pos = int(fader.value//256) 63 while abs(fader_pos - new_position) > 2 : 64 if fader_pos > new_position : 65 speed = 2.25 * abs(fader_pos - new_position) / 256 + 0.12 66 speed = clamp(speed, -1.0, 1.0) 67 motor1.throttle = speed 68 led[0] = (fader_pos, 0, 0) 69 70 if MIDI_DEMO: 71 global fader_cc # pylint: disable=global-statement 72 fader_cc = int(fader_pos / 2) # cc is 0-127 73 midi.send(ControlChange(fader_cc_number, fader_cc)) 74 75 if fader_pos < new_position: 76 speed = -2.25 * abs(fader_pos - new_position) / 256 - 0.12 77 speed = clamp(speed, -1.0, 1.0) 78 motor1.throttle = speed 79 led[0] = (fader_pos, 0, 0) 80 81 if MIDI_DEMO: 82 fader_cc = int(fader_pos / 2) # cc is 0-127 83 midi.send(ControlChange(fader_cc_number, fader_cc)) 84 85 fader_pos = int(fader.value//256) 86 motor1.throttle = None 87 print("--__ Flying Fader Demo __--") 88 print("\n"*4) 89 90 go_to_position(saved_positions[3]) # boot up demo 91 go_to_position(saved_positions[0]) 92 time.sleep(.6) 93 94 current_saved_position = 0 # state to store which is current position from the list 95 96 while True: 97 for i in range(len(buttons)): 98 buttons[i].update() 99 if buttons[i].fell: # if a button is pressed, update the position from list 100 current_saved_position = i 101 102 if touch.value: 103 motor1.throttle = None # idle 104 else: 105 go_to_position(saved_positions[current_saved_position]) 106 107 filter_amt = 0.1 # higher number will be a slower filter between 1.0 and 0.1 is good 108 fader_pos = int((filter_amt * last_fader_pos) + ((1.0-filter_amt) * fader.value//256)) 109 led[0] = (fader_pos, 0, 0) 110 if abs(fader_pos - last_fader_pos) > 1 : # do things in here, e.g. send MIDI CC 111 fader_width = 90 # for text visualization in serial output 112 print("-" * (fader_width - int(fader_pos/3)), fader_pos, "-" * int(fader_pos/3), end='\r') 113 last_fader_pos = fader_pos 114 if MIDI_DEMO: 115 fader_cc = int(fader_pos / 2) # cc is 0-127 116 midi.send(ControlChange(fader_cc_number, fader_cc))