import machine
import time
# ==========================================
# MAPEAMENTO DE PINOS
# ==========================================
# Pinos dos Encoders: (CLK, DT, SW)
PINOS_ENCODERS = [
(0, 1, 2), # Encoder 1
(3, 4, 5), # Encoder 2
(6, 7, 8) # Encoder 3
]
# Pinos da Matriz de 12 Botões
PINOS_BOTOES = [
28, 27, 26, 22,
21, 20, 19, 18,
17, 16, 15, 14
]
# ==========================================
# INICIALIZAÇÃO DE HARDWARE
# ==========================================
# Configurando os 12 Botões com Pull-Up interno
botoes = []
for p in PINOS_BOTOES:
btn = machine.Pin(p, machine.Pin.IN, machine.Pin.PULL_UP)
botoes.append({"pin": btn, "estado_anterior": 1})
# Classe para instanciar e gerenciar os Encoders de forma independente
class RotaryEncoder:
def __init__(self, id_enc, p_clk, p_dt, p_sw):
self.id = id_enc
self.clk = machine.Pin(p_clk, machine.Pin.IN, machine.Pin.PULL_UP)
self.dt = machine.Pin(p_dt, machine.Pin.IN, machine.Pin.PULL_UP)
self.sw = machine.Pin(p_sw, machine.Pin.IN, machine.Pin.PULL_UP)
self.ultimo_clk = self.clk.value()
self.ultimo_sw = 1
# Cria um "Listener" direto no hardware para capturar giros rápidos
self.clk.irq(trigger=machine.Pin.IRQ_FALLING | machine.Pin.IRQ_RISING, handler=self.ao_girar)
def ao_girar(self, pin):
clk_atual = self.clk.value()
if clk_atual != self.ultimo_clk:
# Avalia o pino DT para descobrir a direção do giro
if self.dt.value() != clk_atual:
print(f"[Encoder {self.id}] 🔊 Volume [+] (Direita)")
else:
print(f"[Encoder {self.id}] 🔉 Volume [-] (Esquerda)")
self.ultimo_clk = clk_atual
def checar_clique(self):
sw_atual = self.sw.value()
# Dispara apenas quando o botão afunda (vai para 0)
if sw_atual == 0 and self.ultimo_sw == 1:
print(f"[Encoder {self.id}] 🔇 SW Pressionado (Mute)")
time.sleep(0.05) # Debounce de 50ms
self.ultimo_sw = sw_atual
# Gerando os objetos dos Encoders
encoders = []
for i, pinos in enumerate(PINOS_ENCODERS):
encoders.append(RotaryEncoder(i + 1, pinos[0], pinos[1], pinos[2]))
# ==========================================
# EVENT LOOP PRINCIPAL
# ==========================================
print("🚀 Controladora OBS Iniciada e Pronta!")
print(">> Interaja com os componentes no Wokwi para ver os logs abaixo:\n")
while True:
# Varredura (Polling) dos 12 botões de cena
for i, btn in enumerate(botoes):
estado_atual = btn["pin"].value()
if estado_atual == 0 and btn["estado_anterior"] == 1:
# Formatação do número para ficar alinhado (Ex: 01, 02)
print(f"[Botão {i + 1:02d}] 🎬 Pressionado (Trocar Cena)")
time.sleep(0.05) # Bloqueio temporário (Debounce)
btn["estado_anterior"] = estado_atual
# Varredura apenas do clique físico dos Encoders
for enc in encoders:
enc.checar_clique()
time.sleep(0.01) # Pequeno fôlego para não sobrecarregar a CPU