#158Intermedio

Semáforo Raspberry Pi Pico con selector de 4 modos (máquina de estados, GP11-13 + GP4)

¡4 modos diferentes para el semáforo con un solo botón! Cada vez que se pulsa el botón, cambia el modo: **Ciclo normal** (rojo → ámbar → verde en ese orden), **Solo rojo** (señal de parada), **Ámbar intermitente** (atención/modo nocturno), **Apagado** (mantenimiento). Conceptos: **máquina de estados** (la variable `mode` determina qué comportamiento se ejecutará), **ciclo de modos por módulo** (`(mode + 1) % 4` → 0→1→2→3→0, ciclo infinito), **sincronización sin bloqueo** (las fases de los LED se

5.0(1)
15 completado
Semáforo Raspberry Pi Pico con selector de 4 modos (máquina de estados, GP11-13 + GP4)
Los semáforos de verdad parpadean en amarillo por la noche y a veces se quedan en rojo; en este proyecto eliges cada modo con un solo botón. Cada pulsación pasa al siguiente: el ciclo normal con rojo, amarillo y verde por turnos, solo rojo, amarillo intermitente y todo apagado. La Raspberry Pi Pico maneja las luces sin dejar de escuchar el botón, así que nunca se pierde una pulsación.

Video

Diagrama del circuito

Semáforo Raspberry Pi Pico con selector de 4 modos (máquina de estados, GP11-13 + GP4) - Circuit

Código fuente

MicroPython
1# ─────────────────────────────────────────
2#   BlueGrays · bluegrays.com
3#   Semáforo Raspberry Pi Pico con selector de 4 modos (máquina de estados, GP11-13 + GP4)
4# ─────────────────────────────────────────
5# Un botón recorre 4 modos: ciclo normal (rojo -> amarillo -> verde), solo
6# rojo, destello amarillo y apagado. Usa una máquina de estados y
7# temporización sin bloqueo con time.ticks_ms(), así que el botón siempre
8# responde.
9#
10# Pines:
11#   GP11 -> LED verde
12#   GP12 -> LED amarillo
13#   GP13 -> LED rojo (cada LED con 220 ohmios)
14#   GP4  -> Botón (otra patilla a GND)
15
16from machine import Pin
17import time
18
19# ============ LED ============
20green  = Pin(11, Pin.OUT)   # Verde
21yellow = Pin(12, Pin.OUT)   # Amarillo
22red    = Pin(13, Pin.OUT)   # Rojo
23
24# ============ BOTÓN ============
25button = Pin(4, Pin.IN, Pin.PULL_UP)   # Lee 0 al pulsar
26
27# ============ ESTADO ============
28# Modo: 0 ciclo normal, 1 solo rojo, 2 destello amarillo, 3 apagado
29mode = 0
30last_btn = 1                 # Valor anterior del botón
31blink_state = False          # Estado del destello amarillo
32last_tick = time.ticks_ms()  # Última alternancia del destello
33
34# ============ CICLO NORMAL ============
35normal_step = 0                     # 0: rojo, 1: amarillo, 2: verde
36normal_last = time.ticks_ms()       # Hora de inicio del paso
37NORMAL_TIMES = [3000, 1000, 3000]   # Rojo, amarillo, verde (ms)
38LEDS = [red, yellow, green]
39
40def all_off():
41    # Apagar todos los LED
42    red.off(); yellow.off(); green.off()
43
44# ============ BUCLE PRINCIPAL ============
45while True:
46    btn = button.value()
47
48    # ---- Botón pulsado (1 -> 0): cambio de modo ----
49    if last_btn == 1 and btn == 0:
50        mode = (mode + 1) % 4
51        all_off()
52        normal_step = 0
53        normal_last = time.ticks_ms()
54        time.sleep_ms(200)   # Antirrebote
55    last_btn = btn
56
57    now = time.ticks_ms()
58
59    # ---- Ciclo normal del semáforo ----
60    if mode == 0:
61        if time.ticks_diff(now, normal_last) > NORMAL_TIMES[normal_step]:
62            normal_step = (normal_step + 1) % 3
63            normal_last = now
64        all_off()
65        LEDS[normal_step].on()
66
67    # ---- Solo rojo (alto) ----
68    elif mode == 1:
69        all_off(); red.on()
70
71    # ---- Destello amarillo, 0.4 s (precaución/noche) ----
72    elif mode == 2:
73        if time.ticks_diff(now, last_tick) > 400:
74            blink_state = not blink_state
75            yellow.value(blink_state)
76            last_tick = now
77            red.off(); green.off()
78
79    # ---- Apagado ----
80    else:
81        all_off()
82
83    time.sleep_ms(10)
84

Preguntas frecuentes

¿Qué es una máquina de estados?▾

Una sola variable (mode) decide qué hace el programa en cada momento. Cada pulsación cambia el modo y el bucle solo ejecuta el código del modo actual. Es la forma habitual de mantener ordenados los comportamientos complejos.

¿Qué hace (mode + 1) % 4?▾

Aumenta el modo en uno y vuelve a 0 al llegar a 4, de modo que cambia sin fin: 0, 1, 2, 3, 0, 1...

¿Por qué usar ticks_ms() en lugar de time.sleep()?▾

Durante sleep() la Pico no puede leer el botón y los cambios de modo se retrasan. ticks_ms() y ticks_diff() evitan esperas largas durante las fases de los LED. Sin embargo, esta versión espera 200 ms para el antirrebote al cambiar de modo y 10 ms al final de cada vuelta del bucle; durante esos intervalos no se vuelve a leer el botón.

¿Puedo añadir un modo nuevo?▾

Sí, sube el número de modos a 5 y escribe un bloque de comportamiento para el nuevo, por ejemplo un destello verde o todas las luces encendiéndose en secuencia.

Semáforo Raspberry Pi Pico con selector de 4 modos (máquina de estados, GP11-13 | BlueGrays