116 lines
4.1 KiB
Python
116 lines
4.1 KiB
Python
# SPDX-FileCopyrightText: 2022 John Park for Adafruit Industries
|
|
# SPDX-License-Identifier: MIT
|
|
# Motorized fader demo
|
|
import time
|
|
import board
|
|
import pwmio
|
|
import analogio
|
|
import touchio
|
|
import neopixel
|
|
from digitalio import DigitalInOut, Pull
|
|
from adafruit_debouncer import Debouncer
|
|
from adafruit_motor import motor
|
|
|
|
MIDI_DEMO = False # set to True to send MIDI CC
|
|
|
|
# optional MIDI setup
|
|
if MIDI_DEMO:
|
|
import usb_midi
|
|
import adafruit_midi
|
|
from adafruit_midi.control_change import ControlChange
|
|
midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)
|
|
fader_cc_number = 16
|
|
|
|
# Button setup to store four saved values
|
|
button_pins = (board.D10, board.D9, board.D6, board.D5)
|
|
buttons = []
|
|
for button_pin in button_pins:
|
|
tmp_pin = DigitalInOut(button_pin)
|
|
tmp_pin.pull = Pull.UP
|
|
buttons.append(Debouncer(tmp_pin))
|
|
|
|
saved_positions = (230, 180, 120, 60) # pre-saved positions for the buttons to call
|
|
|
|
# Slide pot setup
|
|
fader = analogio.AnalogIn(board.A0)
|
|
fader_position = fader.value # ranges from 0-65535
|
|
fader_pos = fader.value // 256 # make 0-255 range
|
|
last_fader_pos = fader_pos
|
|
|
|
# Motor setup
|
|
PWM_PIN_A = board.D12 # pick any pwm pins on their own channels
|
|
PWM_PIN_B = board.D11
|
|
|
|
# DC motor driver setup -- these pins go to h-bridge driver such as L9110
|
|
pwm_a = pwmio.PWMOut(PWM_PIN_A, frequency=50)
|
|
pwm_b = pwmio.PWMOut(PWM_PIN_B, frequency=50)
|
|
motor1 = motor.DCMotor(pwm_a, pwm_b)
|
|
|
|
# Touch setup pin goes from touch pin on slide pot to touch capable pin and then 1MΩ to gnd
|
|
touch = touchio.TouchIn(board.A3)
|
|
touch.threshold = touch.raw_value + 30 # tune for fader knob cap
|
|
|
|
# NeoPixel setup
|
|
led = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2, auto_write=True)
|
|
led.fill(0xff0000)
|
|
|
|
def clamp(num, min_value, max_value): # function for clamping motor throttle -1.0 to 1.0
|
|
return max(min(num, max_value), min_value)
|
|
|
|
def go_to_position(new_position):
|
|
global fader_pos # pylint: disable=global-statement
|
|
fader_pos = int(fader.value//256)
|
|
while abs(fader_pos - new_position) > 2 :
|
|
if fader_pos > new_position :
|
|
speed = 2.25 * abs(fader_pos - new_position) / 256 + 0.12
|
|
speed = clamp(speed, -1.0, 1.0)
|
|
motor1.throttle = speed
|
|
led[0] = (fader_pos, 0, 0)
|
|
|
|
if MIDI_DEMO:
|
|
global fader_cc # pylint: disable=global-statement
|
|
fader_cc = int(fader_pos / 2) # cc is 0-127
|
|
midi.send(ControlChange(fader_cc_number, fader_cc))
|
|
|
|
if fader_pos < new_position:
|
|
speed = -2.25 * abs(fader_pos - new_position) / 256 - 0.12
|
|
speed = clamp(speed, -1.0, 1.0)
|
|
motor1.throttle = speed
|
|
led[0] = (fader_pos, 0, 0)
|
|
|
|
if MIDI_DEMO:
|
|
fader_cc = int(fader_pos / 2) # cc is 0-127
|
|
midi.send(ControlChange(fader_cc_number, fader_cc))
|
|
|
|
fader_pos = int(fader.value//256)
|
|
motor1.throttle = None
|
|
print("--__ Flying Fader Demo __--")
|
|
print("\n"*4)
|
|
|
|
go_to_position(saved_positions[3]) # boot up demo
|
|
go_to_position(saved_positions[0])
|
|
time.sleep(.6)
|
|
|
|
current_saved_position = 0 # state to store which is current position from the list
|
|
|
|
while True:
|
|
for i in range(len(buttons)):
|
|
buttons[i].update()
|
|
if buttons[i].fell: # if a button is pressed, update the position from list
|
|
current_saved_position = i
|
|
|
|
if touch.value:
|
|
motor1.throttle = None # idle
|
|
else:
|
|
go_to_position(saved_positions[current_saved_position])
|
|
|
|
filter_amt = 0.1 # higher number will be a slower filter between 1.0 and 0.1 is good
|
|
fader_pos = int((filter_amt * last_fader_pos) + ((1.0-filter_amt) * fader.value//256))
|
|
led[0] = (fader_pos, 0, 0)
|
|
if abs(fader_pos - last_fader_pos) > 1 : # do things in here, e.g. send MIDI CC
|
|
fader_width = 90 # for text visualization in serial output
|
|
print("-" * (fader_width - int(fader_pos/3)), fader_pos, "-" * int(fader_pos/3), end='\r')
|
|
last_fader_pos = fader_pos
|
|
if MIDI_DEMO:
|
|
fader_cc = int(fader_pos / 2) # cc is 0-127
|
|
midi.send(ControlChange(fader_cc_number, fader_cc))
|