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

Video
Diagrama del circuito

Código fuente
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)
84Preguntas 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.
