from machine import Pin, I2C, PWM
import time
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
# ------------------------------------------------------------
# Configuración física mejorada del keypad
# ------------------------------------------------------------
class Keypad:
def __init__(self, rows, cols):
self.rows = [Pin(pin, Pin.OUT) for pin in rows]
self.cols = [Pin(pin, Pin.IN, Pin.PULL_UP) for pin in cols]
self.keys = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
def get_key(self):
for row in range(4):
self.rows[row].value(0)
for col in range(4):
if not self.cols[col].value():
self.rows[row].value(1)
return self.keys[row][col]
self.rows[row].value(1)
return None
# ------------------------------------------------------------
# Configuración de pines (actualizada con pull-ups correctos)
# ------------------------------------------------------------
# Semáforos vehiculares
va_red = Pin(2, Pin.OUT)
va_yellow = Pin(3, Pin.OUT)
va_green = Pin(4, Pin.OUT)
vb_red = Pin(5, Pin.OUT)
vb_yellow = Pin(6, Pin.OUT)
vb_green = Pin(7, Pin.OUT)
# Semáforos peatonales
peaton_a_red = Pin(8, Pin.OUT, value=1)
peaton_a_green = Pin(9, Pin.OUT, value=0)
peaton_b_red = Pin(10, Pin.OUT, value=1)
peaton_b_green = Pin(11, Pin.OUT, value=0)
# Botones peatonales
boton_a = Pin(12, Pin.IN, Pin.PULL_UP)
boton_b = Pin(13, Pin.IN, Pin.PULL_UP)
# Buzzer
buzzer = PWM(Pin(14))
buzzer.freq(1000)
buzzer.duty_u16(0)
# LCD
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# Keypad configurado CORRECTAMENTE
keypad = Keypad(rows=[15, 16, 17, 18], cols=[19, 20, 21, 22])
# ------------------------------------------------------------
# Variables de configuración
# ------------------------------------------------------------
config = {
'A': 5, # Tiempo rojo vehicular (segundos)
'B': 2, # Tiempo amarillo vehicular (segundos)
'C': 10 # Tiempo verde vehicular (segundos)
}
# ------------------------------------------------------------
# Funciones clave mejoradas
# ------------------------------------------------------------
def control_peatonal(estado):
peaton_a_green.value(estado)
peaton_a_red.value(not estado)
peaton_b_green.value(estado)
peaton_b_red.value(not estado)
lcd.clear()
lcd.putstr("SIGA" if estado else "PARE")
def apagar_vehiculares():
va_red.value(1)
va_yellow.value(0)
va_green.value(0)
vb_red.value(1)
vb_yellow.value(0)
vb_green.value(0)
def modo_peatonal():
apagar_vehiculares()
buzzer.duty_u16(32768)
control_peatonal(1)
inicio = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), inicio) < 2 * 1000:
if time.ticks_diff(time.ticks_ms(), inicio) >= 500:
buzzer.duty_u16(0)
if keypad.get_key() == '*':
break
control_peatonal(0)
buzzer.duty_u16(0)
def ciclo_vehicular():
# Fase A Verde
va_red.value(0)
va_green.value(1)
vb_red.value(1)
inicio = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), inicio) < config['C'] * 1000:
if not boton_a.value() or not boton_b.value():
return False
# Transición A Amarillo
va_green.value(0)
va_yellow.value(1)
time.sleep(config['B'])
va_yellow.value(0)
# Fase B Verde
vb_red.value(0)
vb_green.value(1)
va_red.value(1)
inicio = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), inicio) < config['C'] * 1000:
if not boton_a.value() or not boton_b.value():
return False
# Transición B Amarillo
vb_green.value(0)
vb_yellow.value(1)
time.sleep(config['B'])
vb_yellow.value(0)
return True
def modo_configuracion():
lcd.clear()
lcd.putstr("Configurar:\nA-Rojo B-Ama C-Ver")
time.sleep(1)
while True:
tecla = keypad.get_key()
if tecla in ['A', 'B', 'C']:
lcd.clear()
lcd.putstr(f"Tiempo {tecla}\nNuevo (seg):")
valor = ""
while True:
digito = keypad.get_key()
if digito == '#':
if valor:
config[tecla] = int(valor)
lcd.putstr(f"\nGuardado: {valor}s")
time.sleep(2)
break
elif digito == '*':
break
elif digito and digito.isdigit():
valor += digito
lcd.move_to(0,1)
lcd.putstr(" "*16)
lcd.putstr(valor)
break
# ------------------------------------------------------------
# Programa principal
# ------------------------------------------------------------
lcd.putstr("INICIANDO")
control_peatonal(0)
time.sleep(2)
while True:
# 1. Chequear keypad primero (prioridad absoluta)
tecla = keypad.get_key()
if tecla == '#':
modo_configuracion()
# 2. Chequear botones peatonales
elif not boton_a.value() or not boton_b.value():
modo_peatonal()
# 3. Ciclo normal
else:
ciclo_vehicular()