from machine import Pin, Timer
import time
# Configuración de LEDs del semáforo VEHICULAR
led_rojo = Pin(1, Pin.OUT)
led_amarillo = Pin(2, Pin.OUT)
led_verde = Pin(3, Pin.OUT)
# Configuración de LEDs del semáforo PEATONAL
led_peat_rojo = Pin(4, Pin.OUT)
led_peat_verde = Pin(5, Pin.OUT)
# Botón para solicitud de peatón
boton_peaton = Pin(6, Pin.IN, Pin.PULL_UP)
# Sensor PIR de movimiento
sensor_pir = Pin(14, Pin.IN)
# Display 7 segmentos
segmentos = [
Pin(7, Pin.OUT), Pin(8, Pin.OUT), Pin(9, Pin.OUT),
Pin(10, Pin.OUT), Pin(11, Pin.OUT), Pin(12, Pin.OUT), Pin(13, Pin.OUT)
]
# Patrones del 0 al 9
digitos = [
[1,1,1,1,1,1,0], # 0
[0,1,1,0,0,0,0], # 1
[1,1,0,1,1,0,1], # 2
[1,1,1,1,0,0,1], # 3
[0,1,1,0,0,1,1], # 4
[1,0,1,1,0,1,1], # 5
[1,0,1,1,1,1,1], # 6
[1,1,1,0,0,0,0], # 7
[1,1,1,1,1,1,1], # 8
[1,1,1,1,0,1,1] # 9
]
# ----------------------------------------------
# Variables de estado
# ----------------------------------------------
estado_semaforo = "verde"
solicitud_peaton = False
ultimo_boton = 0
# PIR control mejorado
pir_en_cooldown = False
tiempo_cooldown = 0
ENFRIAMIENTO_PIR = 15
# Cooldown del botón peatonal
boton_en_cooldown = False
tiempo_cooldown_boton = 0
COOLDOWN_BOTON = 10
# ----------------------------------------------
# DISPLAY
# ----------------------------------------------
def mostrar_numero(n):
if n < 0 or n > 9:
n = 0
patron = digitos[n]
for i in range(7):
segmentos[i].value(patron[i])
# ----------------------------------------------
# SEMÁFORO
# ----------------------------------------------
def cambiar_semaforo(nuevo):
global estado_semaforo
estado_semaforo = nuevo
led_rojo.value(0)
led_amarillo.value(0)
led_verde.value(0)
led_peat_rojo.value(0)
led_peat_verde.value(0)
if nuevo == "rojo":
print("🔴 Vehículos ROJO – Peatones VERDE")
led_rojo.value(1)
led_peat_verde.value(1)
elif nuevo == "amarillo":
print("🟡 Vehículos AMARILLO – Peatones ROJO")
led_amarillo.value(1)
led_peat_rojo.value(1)
elif nuevo == "verde":
print("🟢 Vehículos VERDE – Peatones ROJO")
led_verde.value(1)
led_peat_rojo.value(1)
# ----------------------------------------------
# PIR CON ENFRIAMIENTO REAL
# ----------------------------------------------
def verificar_movimiento():
global pir_en_cooldown, tiempo_cooldown
ahora = time.time()
if pir_en_cooldown:
restante = ENFRIAMIENTO_PIR - int(ahora - tiempo_cooldown)
if restante > 0:
return False
else:
pir_en_cooldown = False
print("✅ PIR listo para detectar otra vez")
if sensor_pir.value() == 1:
print("🚶 PIR detectó peatones - iniciando cooldown 15s")
pir_en_cooldown = True
tiempo_cooldown = ahora
return True
return False
# ----------------------------------------------
# COOLDOWN DEL BOTÓN MOSTRADO EN PANTALLA
# ----------------------------------------------
def actualizar_cooldown_boton():
global boton_en_cooldown, tiempo_cooldown_boton
if not boton_en_cooldown:
return
ahora = time.time()
restante = COOLDOWN_BOTON - int(ahora - tiempo_cooldown_boton)
if restante > 0:
if restante > 9:
restante = 9
mostrar_numero(restante)
else:
boton_en_cooldown = False
mostrar_numero(0)
print("✅ Botón listo nuevamente")
# ----------------------------------------------
# CUENTAS REGRESIVAS
# ----------------------------------------------
def cuenta_regresiva(seg):
for i in range(seg, -1, -1):
mostrar_numero(i if i <= 9 else 9)
time.sleep(1)
# ----------------------------------------------
# CICLOS
# ----------------------------------------------
def transicion_rapida():
if estado_semaforo == "verde":
for i in range(3,0,-1):
led_verde.value(0)
mostrar_numero(i)
time.sleep(0.4)
led_verde.value(1)
time.sleep(0.4)
cambiar_semaforo("amarillo")
cuenta_regresiva(2)
def ciclo_con_peatones():
global solicitud_peaton
print("🚶 Ciclo para peatones activado")
transicion_rapida()
cambiar_semaforo("rojo")
cuenta_regresiva(9)
print("✔ Ciclo peatones terminado")
solicitud_peaton = False
# ----------------------------------------------
# BOTÓN
# ----------------------------------------------
def verificar_boton(pin):
global ultimo_boton, solicitud_peaton
global boton_en_cooldown, tiempo_cooldown_boton
ahora = time.time()
if boton_en_cooldown:
return
if time.ticks_diff(time.ticks_ms(), ultimo_boton) > 500:
if pin.value() == 0:
print("🔘 Botón peatón presionado")
solicitud_peaton = True
boton_en_cooldown = True
tiempo_cooldown_boton = ahora
ultimo_boton = time.ticks_ms()
boton_peaton.irq(trigger=Pin.IRQ_FALLING, handler=verificar_boton)
# ----------------------------------------------
# LOOP PRINCIPAL
# ----------------------------------------------
def main():
print("🚦 Semáforo inteligente iniciado")
cambiar_semaforo("verde")
mostrar_numero(0)
while True:
actualizar_cooldown_boton()
if verificar_movimiento() or solicitud_peaton:
ciclo_con_peatones()
else:
if estado_semaforo != "verde" and not boton_en_cooldown:
cambiar_semaforo("verde")
mostrar_numero(0)
time.sleep(1)
# Iniciar
main()