#158Intermédiaire

Feu de signalisation Raspberry Pi Pico avec sélecteur à 4 modes (machine à états, GP11-13 + GP4)

4 modes différents pour le feu tricolore avec un seul bouton ! À chaque pression sur le bouton, le mode change : **Cycle normal** (rouge → orange → vert dans cet ordre), **Rouge uniquement** (ordre d'arrêt), **Orange clignotant** (attention/mode nuit), **Éteint** (entretien). Notions : **state machine** (machine à états — la variable `mode` détermine le comportement à adopter), **modulo mod cycling** (`(mode + 1) % 4` → 0→1→2→3→0, boucle infinie), **synchronisation non bloquante** (les phases de

5.0(1)
15 terminé
Feu de signalisation Raspberry Pi Pico avec sélecteur à 4 modes (machine à états, GP11-13 + GP4)
Les vrais feux clignotent à l'orange la nuit et restent parfois au rouge ; dans ce projet, tu choisis tout cela avec un seul bouton. Chaque appui passe au mode suivant : le cycle normal avec rouge, orange et vert à tour de rôle, rouge seul, orange clignotant, et tout éteint. La Raspberry Pi Pico gère les lumières tout en continuant d'écouter le bouton, donc aucun appui n'est perdu.

Vidéo

Schéma du circuit

Feu de signalisation Raspberry Pi Pico avec sélecteur à 4 modes (machine à états, GP11-13 + GP4) - Circuit

Code source

MicroPython
1# ─────────────────────────────────────────
2#   BlueGrays · bluegrays.com
3#   Feu de signalisation Raspberry Pi Pico avec sélecteur à 4 modes (machine à états, GP11-13 + GP4)
4# ─────────────────────────────────────────
5# Un bouton fait défiler 4 modes : cycle normal (rouge -> jaune -> vert),
6# rouge seul, jaune clignotant et éteint. Utilise une machine à états et
7# un timing non bloquant avec time.ticks_ms(), donc le bouton reste
8# toujours réactif.
9#
10# Broches :
11#   GP11 -> LED verte
12#   GP12 -> LED jaune
13#   GP13 -> LED rouge (chaque LED avec 220 ohm)
14#   GP4  -> Bouton (autre patte sur GND)
15
16from machine import Pin
17import time
18
19# ============ LED ============
20green  = Pin(11, Pin.OUT)   # Vert
21yellow = Pin(12, Pin.OUT)   # Jaune
22red    = Pin(13, Pin.OUT)   # Rouge
23
24# ============ BOUTON ============
25button = Pin(4, Pin.IN, Pin.PULL_UP)   # Lit 0 quand appuyé
26
27# ============ ÉTAT ============
28# Mode : 0 cycle normal, 1 rouge seul, 2 jaune clignotant, 3 éteint
29mode = 0
30last_btn = 1                 # Valeur précédente du bouton
31blink_state = False          # État du clignotement jaune
32last_tick = time.ticks_ms()  # Dernière bascule du flash
33
34# ============ CYCLE NORMAL ============
35normal_step = 0                     # 0 : rouge, 1 : jaune, 2 : vert
36normal_last = time.ticks_ms()       # Heure de début du pas
37NORMAL_TIMES = [3000, 1000, 3000]   # Rouge, jaune, vert (ms)
38LEDS = [red, yellow, green]
39
40def all_off():
41    # Éteindre toutes les LED
42    red.off(); yellow.off(); green.off()
43
44# ============ BOUCLE PRINCIPALE ============
45while True:
46    btn = button.value()
47
48    # ---- Bouton appuyé (1 -> 0) : changement de mode ----
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)   # Anti-rebond
55    last_btn = btn
56
57    now = time.ticks_ms()
58
59    # ---- Cycle normal du feu tricolore ----
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    # ---- Rouge seul (arrêt) ----
68    elif mode == 1:
69        all_off(); red.on()
70
71    # ---- Clignotement jaune, 0.4 s (prudence/nuit) ----
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    # ---- Éteint ----
80    else:
81        all_off()
82
83    time.sleep_ms(10)
84

FAQ

Qu'est-ce qu'une machine à états ?▾

Une seule variable (mode) détermine ce que fait le programme à un instant donné. Chaque appui change le mode, et la boucle n'exécute que le code du mode courant. C'est la méthode classique pour garder un comportement complexe bien organisé.

À quoi sert (mode + 1) % 4 ?▾

Il augmente le mode de un et revient à 0 en atteignant 4 : le mode tourne ainsi sans fin, 0, 1, 2, 3, 0, 1…

Pourquoi utiliser ticks_ms() plutôt que time.sleep() ?▾

Pendant sleep(), la Pico ne peut pas lire le bouton et les changements de mode sont retardés. ticks_ms() et ticks_diff() évitent les longues attentes pendant les phases des LED. Toutefois, cette version attend 200 ms pour l'anti-rebond lors d'un changement de mode et 10 ms à la fin de chaque tour de boucle ; le bouton n'est pas relu pendant ces intervalles.

Puis-je ajouter un nouveau mode ?▾

Oui, passe le nombre de modes à 5 et écris un bloc de comportement pour le nouveau, par exemple un flash vert ou tous les feux qui s'allument l'un après l'autre.

Feu de signalisation Raspberry Pi Pico à 4 modes avec sélecteur à boutons (machi | BlueGrays