LED RGB et NeoPixel
Prends le contrôle d’un bandeau de 8 LED RGB WS2812. Couleurs sur mesure, animations de défilement, arc-en-ciel automatique — tout ça avec un seul fil de données.
3h
Ce que tu vas créer
Un bandeau NeoPixel qui propose 6 animations différentes. Le bouton BOOT de l’ESP32 fait défiler les modes :
- Défilement bleu / rouge
- Arc-en-ciel automatique
- Scintillement aléatoire
- Remplissage progressif
Matériel nécessaire
| Composant | Quantité | Notes |
|---|---|---|
| ESP32 | 1 | Fourni en atelier |
| Bandeau NeoPixel WS2812 | 1 (8 LEDs) | Fourni en atelier |
| Condensateur 1000 µF | 1 | Protection contre les pics de courant |
| Résistance 300-500 Ω | 1 | Sur le fil DATA |
| Câble micro-USB | 1 | Fourni en atelier |
Connexions
ESP32 5V ──── NeoPixel 5V
ESP32 GND ──── NeoPixel GND
ESP32 G26 ──── résistance 300Ω ──── NeoPixel DINLe code
NeoPixel MicroPython — main.py .python atelier2-neopixel/main.py 115 lignes
GitHub
# Atelier 02 — LED RGB et NeoPixel (WS2812)
# Fablab Ardèche — MicroPython
#
# Contrôle un bandeau de 8 LED RGB WS2812.
# Les boutons changent l'animation en cours.
#
# Matériel : ESP32, bandeau NeoPixel 8 LED
# Connexions : DATA → GPIO26, BP_A → GPIO0 (PULL_UP)
from machine import Pin
from neopixel import NeoPixel
import time, random
# --- Configuration ---
N = 8 # nombre de LEDs
NP_PIN = 26
BP_PIN = 0 # bouton BOOT (PULL_UP)
np = NeoPixel(Pin(NP_PIN, Pin.OUT), N)
bp = Pin(BP_PIN, Pin.IN, Pin.PULL_UP)
# --- Utilitaires couleur ---
def eteindre():
for i in range(N):
np[i] = (0, 0, 0)
np.write()
def roue(pos):
"""Convertit 0-255 en couleur arc-en-ciel RGB."""
pos = pos % 256
if pos < 85:
return (255 - pos * 3, pos * 3, 0)
elif pos < 170:
pos -= 85
return (0, 255 - pos * 3, pos * 3)
else:
pos -= 170
return (pos * 3, 0, 255 - pos * 3)
# --- Animations ---
def animation_defilement(couleur=(0, 80, 255), delai=80):
"""Une LED qui se déplace de gauche à droite."""
for i in range(N):
eteindre()
np[i] = couleur
np.write()
time.sleep_ms(delai)
if bp.value() == 0:
return
def animation_arc_en_ciel(tours=3):
"""Arc-en-ciel qui défile sur toutes les LEDs."""
for _ in range(tours * 256):
for i in range(N):
np[i] = roue((i * 32 + _) % 256)
np.write()
time.sleep_ms(15)
if bp.value() == 0:
return
def animation_scintillement(duree_ms=3000):
"""LEDs qui s'allument et s'éteignent aléatoirement."""
t0 = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), t0) < duree_ms:
i = random.randint(0, N - 1)
np[i] = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
np.write()
time.sleep_ms(80)
np[i] = (0, 0, 0)
np.write()
if bp.value() == 0:
return
def animation_remplissage(couleur=(255, 50, 0), delai=120):
"""Les LEDs s'allument une par une puis s'éteignent."""
for i in range(N):
np[i] = couleur
np.write()
time.sleep_ms(delai)
if bp.value() == 0:
return
time.sleep_ms(400)
for i in range(N - 1, -1, -1):
np[i] = (0, 0, 0)
np.write()
time.sleep_ms(delai)
if bp.value() == 0:
return
# --- Boucle principale ---
animations = [
("Défilement bleu", lambda: animation_defilement((0, 80, 255))),
("Défilement rouge", lambda: animation_defilement((255, 30, 0))),
("Arc-en-ciel", animation_arc_en_ciel),
("Scintillement", animation_scintillement),
("Remplissage orange", lambda: animation_remplissage((255, 50, 0))),
("Remplissage vert", lambda: animation_remplissage((0, 200, 50))),
]
idx = 0
print("Appuie sur le bouton BOOT pour changer d'animation")
while True:
nom, anim = animations[idx]
print(f"Animation : {nom}")
anim()
# Attendre que le bouton soit relâché
while bp.value() == 0:
time.sleep_ms(20)
time.sleep_ms(100)
idx = (idx + 1) % len(animations)
eteindre()
🤔 Avant de lancer Tu modifies `np[3] = (255, 0, 0)` mais tu oublies `np.write()`. Que se passe-t-il ? voir la réponse
Rien du tout. La LED 3 reste dans son état précédent.
np[3] = (255, 0, 0) ne fait que noter la couleur en mémoire, dans l’ESP32. C’est np.write() qui envoie réellement toutes les couleurs vers le bandeau, sur le fil de données.
C’est d’ailleurs pratique : on prépare les 8 LEDs tranquillement, puis un seul write() les met toutes à jour d’un coup — donc sans scintillement.
- Change la couleur du défilement :
couleur=(255, 0, 0)pour du rouge - Change la vitesse :
delai=20au lieu de80 - Baisse l’intensité :
(0, 20, 60)au lieu de(0, 80, 255)— bien moins éblouissant, et ça consomme trois fois moins - Si ton bandeau a plus de 8 LEDs, ajuste
N = 8 - Dans l’arc-en-ciel, remplace
i * 32pari * 8→ les couleurs se resserrent - Plus dur : fais un chenillard qui rebondit (aller-retour) au lieu de repartir à gauche
Comment ça marche
Couleurs RGB
Chaque LED NeoPixel est contrôlée par un triplet (rouge, vert, bleu), chaque valeur de 0 à 255 :
np[0] = (255, 0, 0) # rouge pur
np[1] = (0, 255, 0) # vert pur
np[2] = (0, 0, 255) # bleu pur
np[3] = (255, 165, 0) # orange
np[4] = (128, 0, 128) # violet
np.write() # envoyer vers les LEDsUn seul fil pour 8 LEDs
C’est la particularité des WS2812 : un seul fil de données commande tout le bandeau, quelle que soit sa longueur.
Chaque LED contient un minuscule circuit qui lit les 24 premiers bits qui lui parviennent (8 pour le rouge, 8 pour le vert, 8 pour le bleu), les garde pour elle, et retransmet tout le reste à sa voisine. De proche en proche, chacune se sert au passage.
D’où deux conséquences pratiques :
- L’ordre compte.
np[0]est toujours la LED la plus proche de l’ESP32. - Rien ne change tant qu’on n’a pas appelé
np.write(). Modifiernp[3]ne fait que préparer la couleur en mémoire ; c’estwrite()qui envoie la trame complète sur le fil.
La fonction arc-en-ciel
roue(pos) transforme un nombre de 0 à 255 en une couleur, en parcourant le cercle des teintes. Elle travaille par tiers :
pos | Transition |
|---|---|
| 0 → 84 | rouge qui s’efface, vert qui monte |
| 85 → 169 | vert qui s’efface, bleu qui monte |
| 170 → 255 | bleu qui s’efface, rouge qui remonte |
À chaque instant, la somme des trois composantes reste constante — la luminosité ne varie pas, seule la teinte tourne. Et comme pos = pos % 256 ramène toujours dans l’intervalle, on peut incrémenter indéfiniment : l’arc-en-ciel boucle tout seul.
Le décalage i * 32 dans l’animation donne à chaque LED une teinte légèrement différente de sa voisine : c’est ce qui étale l’arc-en-ciel sur le bandeau au lieu de le faire clignoter d’un bloc.
Attention à la consommation
Une LED WS2812 à fond en blanc (255, 255, 255) tire environ 60 mA. Pour 8 LEDs, cela fait presque 500 mA — davantage que ce qu’un port USB fournit confortablement.
En atelier, on reste donc sur des couleurs modérées. Pour un bandeau plus long ou à pleine puissance, il faut une alimentation 5 V séparée, avec la masse reliée à celle de l’ESP32.
Pour aller plus loin
Contrôle par boutons
Utilise 3 boutons pour choisir la couleur rouge/vert/bleu en temps réel.
Réagir au son
Branche un micro et fais pulser les LEDs selon le volume ambiant.
Bandeau plus long
Adapte le code pour 30, 60 ou 144 LEDs — change juste N.