parent
5b70f84441
commit
d3b92742c1
|
@ -0,0 +1,183 @@
|
|||
import board
|
||||
import digitalio
|
||||
import time
|
||||
import usb_midi
|
||||
import neopixel
|
||||
from adafruit_midi import MIDI
|
||||
from adafruit_midi.control_change import ControlChange
|
||||
from adafruit_midi.note_on import NoteOn
|
||||
from adafruit_midi.note_off import NoteOff
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
from adafruit_debouncer import Debouncer
|
||||
|
||||
midi = MIDI(midi_out=usb_midi.ports[1], out_channel=0)
|
||||
led = neopixel.NeoPixel(board.GP5, 7, brightness=0.5, auto_write=True)
|
||||
|
||||
encoder_colors = [
|
||||
(255, 0, 0), # Red
|
||||
(0, 255, 0), # Green
|
||||
(0, 0, 255), # Blue
|
||||
(0, 255, 255), # Cyan
|
||||
(255, 0, 255) # Magenta
|
||||
]
|
||||
|
||||
# Encoder Pins
|
||||
clk = DigitalInOut(board.GP20)
|
||||
clk.direction = Direction.INPUT
|
||||
clk.pull = Pull.UP
|
||||
|
||||
dt = DigitalInOut(board.GP18)
|
||||
dt.direction = Direction.INPUT
|
||||
dt.pull = Pull.UP
|
||||
|
||||
last_clk = clk.value
|
||||
|
||||
# Buttons
|
||||
enc_button_pin = DigitalInOut(board.GP17)
|
||||
enc_button_pin.switch_to_input(pull=Pull.UP)
|
||||
enc_button = Debouncer(enc_button_pin)
|
||||
|
||||
next_button_pin = DigitalInOut(board.GP15)
|
||||
next_button_pin.switch_to_input(pull=Pull.UP)
|
||||
next_button = Debouncer(next_button_pin)
|
||||
|
||||
back_button_pin = DigitalInOut(board.GP14)
|
||||
back_button_pin.switch_to_input(pull=Pull.UP)
|
||||
back_button = Debouncer(back_button_pin)
|
||||
|
||||
mode_toggle_button_pin = DigitalInOut(board.GP13)
|
||||
mode_toggle_button_pin.switch_to_input(pull=Pull.UP)
|
||||
mode_toggle_button = Debouncer(mode_toggle_button_pin)
|
||||
|
||||
# States
|
||||
current_encoder = 0
|
||||
encoder_cc_notes = [1, 2, 3, 4, 5]
|
||||
encoder_bttn_notes = [11, 12, 13, 14, 15]
|
||||
mode_toggle_note = 21
|
||||
|
||||
# Functions
|
||||
def encoder_sweep(direction):
|
||||
sweep_order = [3, 4, 5, 6] if direction == "CW" else [6, 5, 4, 3]
|
||||
for i in sweep_order:
|
||||
led[i] = (255, 255, 255)
|
||||
if direction == "CW" and i > 3:
|
||||
led[i - 1] = (100, 100, 100)
|
||||
elif direction == "CCW" and i < 6:
|
||||
led[i + 1] = (100, 100, 100)
|
||||
|
||||
time.sleep(0.02)
|
||||
led[i] = encoder_colors[current_encoder]
|
||||
|
||||
if direction == "CW" and i > 3:
|
||||
led[i - 1] = encoder_colors[current_encoder]
|
||||
elif direction == "CCW" and i < 6:
|
||||
led[i + 1] = encoder_colors[current_encoder]
|
||||
|
||||
|
||||
def startup_animation():
|
||||
print("Running startup LED test animation...")
|
||||
start_time = time.monotonic()
|
||||
button_indices = [0, 1, 2]
|
||||
encoder_indices = [3, 4, 5, 6]
|
||||
|
||||
while time.monotonic() - start_time < 5:
|
||||
for i in range(len(encoder_indices)):
|
||||
led[encoder_indices[i]] = (255, 255, 255)
|
||||
if i > 0:
|
||||
led[encoder_indices[i - 1]] = (0, 0, 0)
|
||||
time.sleep(0.05)
|
||||
led[encoder_indices[-1]] = (0, 0, 0)
|
||||
|
||||
# Fade up and down the button LEDs
|
||||
for b in range(0, 256, 10):
|
||||
for i in button_indices:
|
||||
led[i] = (b, b, b)
|
||||
time.sleep(0.01)
|
||||
for b in range(255, -1, -10):
|
||||
for i in button_indices:
|
||||
led[i] = (b, b, b)
|
||||
time.sleep(0.01)
|
||||
|
||||
# Fade in to start colors
|
||||
target_colors = [
|
||||
encoder_colors[(current_encoder + 1) % len(encoder_colors)], # LED 0
|
||||
encoder_colors[(current_encoder - 1) % len(encoder_colors)], # LED 1
|
||||
(63, 63, 63), # LED 2 at 25% white
|
||||
]
|
||||
for step in range(0, 101, 5):
|
||||
for i in range(3):
|
||||
led[i] = tuple(int(c * step / 100) for c in target_colors[i])
|
||||
for i in range(3, 7):
|
||||
led[i] = tuple(int(c * step / 100) for c in encoder_colors[current_encoder])
|
||||
time.sleep(0.02)
|
||||
|
||||
# -------------------- Startup -----------------------
|
||||
print("MIDI Encoder Controller started.")
|
||||
startup_animation()
|
||||
led[3:7] = [encoder_colors[current_encoder]] * 4
|
||||
led[0] = encoder_colors[(current_encoder + 1) % len(encoder_colors)]
|
||||
led[1] = encoder_colors[(current_encoder - 1) % len(encoder_colors)]
|
||||
led[2] = (63, 63, 63) # Mode toggle LED default 25% white
|
||||
mode_button_state_note = 0
|
||||
|
||||
# -------------------- Main Loop ---------------------
|
||||
while True:
|
||||
enc_button.update()
|
||||
next_button.update()
|
||||
back_button.update()
|
||||
mode_toggle_button.update()
|
||||
|
||||
# Rotary Encoder Logic
|
||||
if clk.value != last_clk and clk.value == False:
|
||||
direction = None
|
||||
if dt.value != clk.value:
|
||||
direction = "CW"
|
||||
midi.send(ControlChange(encoder_cc_notes[current_encoder], 1))
|
||||
else:
|
||||
direction = "CCW"
|
||||
midi.send(ControlChange(encoder_cc_notes[current_encoder], 127))
|
||||
encoder_sweep(direction)
|
||||
last_clk = clk.value
|
||||
|
||||
# Encoder Button
|
||||
if enc_button.fell:
|
||||
midi.send(NoteOn(encoder_bttn_notes[current_encoder], 127))
|
||||
if enc_button.rose:
|
||||
midi.send(NoteOff(encoder_bttn_notes[current_encoder], 0))
|
||||
|
||||
# Next Encoder Button
|
||||
if next_button.fell:
|
||||
current_encoder = (current_encoder + 1) % len(encoder_cc_notes)
|
||||
forward_color = encoder_colors[(current_encoder + 1) % len(encoder_colors)]
|
||||
backward_color = encoder_colors[(current_encoder - 1) % len(encoder_colors)]
|
||||
led[3:7] = [encoder_colors[current_encoder]] * 4
|
||||
led[0] = forward_color
|
||||
led[1] = backward_color
|
||||
|
||||
# Back Encoder Button
|
||||
if back_button.fell:
|
||||
current_encoder = (current_encoder - 1) % len(encoder_cc_notes)
|
||||
forward_color = encoder_colors[(current_encoder + 1) % len(encoder_colors)]
|
||||
backward_color = encoder_colors[(current_encoder - 1) % len(encoder_colors)]
|
||||
led[3:7] = [encoder_colors[current_encoder]] * 4
|
||||
led[0] = forward_color
|
||||
led[1] = backward_color
|
||||
|
||||
# Mode Toggle Button
|
||||
if mode_toggle_button.fell:
|
||||
if mode_button_state_note == 0:
|
||||
mode_button_state_note = 127
|
||||
elif mode_button_state_note == 127:
|
||||
mode_button_state_note = 0
|
||||
else:
|
||||
mode_button_state_note = 0
|
||||
|
||||
midi.send(NoteOn(mode_toggle_note, mode_button_state_note))
|
||||
|
||||
for b in range(100, 24, -5):
|
||||
level = int(255 * b / 100)
|
||||
led[2] = (level, level, level)
|
||||
time.sleep(0.02)
|
||||
led[2] = (63, 63, 63)
|
||||
|
||||
time.sleep(0.001)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue