import time
import digitalio
import board
# LEDs: LED1..LED4
LED_PINS = [board.GP10, board.GP11, board.GP12, board.GP13]
# Botões: BTN1..BTN14 (usamos 1..11)
BTN_PINS = [
board.GP2, board.GP3, board.GP4, board.GP5,
board.GP6, board.GP7, board.GP8, board.GP9,
board.GP14, board.GP15, board.GP16, board.GP17,
board.GP18, board.GP19
]
DEBOUNCE_MS = 180
STOP_BTN_INDEX = 10 # BTN11
# ---------------- LEDs ----------------
leds = []
for p in LED_PINS:
io = digitalio.DigitalInOut(p)
io.direction = digitalio.Direction.OUTPUT
io.value = False
leds.append(io)
def all_off():
for l in leds:
l.value = False
def set_only(indices_0based):
all_off()
for i in indices_0based:
if 0 <= i < len(leds):
leds[i].value = True
# --------------- Botões ---------------
buttons = []
for p in BTN_PINS:
b = digitalio.DigitalInOut(p)
b.direction = digitalio.Direction.INPUT
# PULL-DOWN interno (dispensa resistor)
b.pull = digitalio.Pull.DOWN
buttons.append(b)
def now_ms():
return int(time.monotonic() * 1000)
last_ms = [0] * len(buttons)
prev = [False] * len(buttons)
def just_pressed(i):
cur = buttons[i].value
jp = cur and not prev[i]
prev[i] = cur
if not jp:
return False
t = now_ms()
if t - last_ms[i] < DEBOUNCE_MS:
return False
last_ms[i] = t
return True
def stop_pressed():
return buttons[STOP_BTN_INDEX].value
# ----------- Loader FX -----------
def load_fx(module_name):
mod = __import__(module_name)
name = getattr(mod, "NAME", module_name)
step_ms = int(getattr(mod, "STEP_MS", 120))
loops = int(getattr(mod, "LOOPS", 1))
steps = getattr(mod, "STEPS", [])
if not isinstance(steps, list) or not steps:
raise ValueError(f"{module_name}.py sem STEPS")
return name, step_ms, loops, steps
def sleep_responsive(ms):
# espera em fatias pequenas pra responder ao STOP
end = time.monotonic() + (ms / 1000.0)
while time.monotonic() < end:
if stop_pressed():
return False
time.sleep(0.01)
return True
def to_0based(step):
# step vem como [1..4] ou [1,2] etc -> vira [0..3]
out = []
for n in step:
n = int(n)
if 1 <= n <= 4:
out.append(n - 1)
return out
def run_fx(module_name):
name, step_ms, loops, steps = load_fx(module_name)
print("EXEC:", name, "| STEP_MS:", step_ms, "| LOOPS:", loops, "| STOP=BTN11")
for _ in range(loops):
for step in steps:
if stop_pressed():
all_off()
print("STOP")
return
set_only(to_0based(step))
if not sleep_responsive(step_ms):
all_off()
print("STOP")
return
# gap curtinho entre loops
all_off()
if not sleep_responsive(30):
all_off()
print("STOP")
return
all_off()
print("FIM:", name)
# BTN1..BTN10 -> FX1..FX10
MAP = {
0: "fx1",
1: "fx2",
2: "fx3",
3: "fx4",
4: "fx5",
5: "fx6",
6: "fx7",
7: "fx8",
8: "fx9",
9: "fx10"
}
print("Pronto: BTN1..BTN10 = FX1..FX10 | BTN11 = STOP")
while True:
if just_pressed(STOP_BTN_INDEX):
all_off()
print("STOP")
time.sleep(0.05)
continue
for btn_i, fx_mod in MAP.items():
if just_pressed(btn_i):
try:
run_fx(fx_mod)
except Exception as e:
print("Erro:", fx_mod, e)
all_off()
time.sleep(0.01)