🛠 Animer un ruban NeoPixel avec un PIO
Objectifs
Comprendre le bloc PIO du RP2350 — 3 blocs et 12 machines d'état, contre 2/8 sur le RP2040 — en implémentant le protocole WS2812 (NeoPixel) sans consommer de temps CPU. Le PIO génère seul les créneaux de ~1,25 µs par bit, pendant que les deux cœurs M33 font autre chose.
Matériel
- 1 × Raspberry Pi Pico 2
- 1 × ruban ou anneau WS2812B (8 LED suffisent)
- Alimentation 5 V externe pour le ruban
- Broche données : GP3
- MicroPython ≥ 1.24.0 (firmware RPI_PICO2)
Code complet
# neopixel_pio.py — pilote WS2812 minimal via rp2.StateMachine (MicroPython)
import array, time
from machine import Pin
import rp2
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT,
autopull=True, pull_thresh=24)
def ws2812:
T1 = 2; T2 = 5; T3 = 3
wrap_target
mov(x, st) .side(1)
jmp(x <= 1) .side(0) # bit 0 : impulsion courte
jmp(1) .side(0) # bit 1 : impulsion longue
nop .side(0)
wrap
PIN, N = 3, 8
sm = rp2.StateMachine(0, ws2812, freq=3_000_000, jmppin=Pin(PIN))
pix = array.array("I", [0] * N)
def show:
sm.put(0)
for g, r, b in pix: # format GRB 0xGGRRBB
sm.put((g << 16) | (r << 8) | b)
time.sleep_us(50); sm.active(1)
i = 0
while True: # arc-en-ciel tournant
for n in range(N):
pix[n] = ((n + i) * 32 & 255, 255 - ((n + i) * 32 & 255), 64)
show; i += 1; time.sleep_ms(80)
Vérification attendue
Les LED s'animent en boucle. Point clé : le CPU reste disponible — ajoutez un clignotement GP25 dans la boucle, il reste synchrone même pendant show, car le PIO pilote seul le timing. C'est la grande force des 12 SM du RP2350.
Erreurs fréquentes
- Firmware MicroPython RP2040 (≤ 1.23) : impossible de flasher sur Pico 2, il faut ≥ 1.24.0 avec le build RPI_PICO2.
- Ruban alimenté depuis le 3V3 : les WS2812 exigent ~5 V sur DIN ; un niveau 3,3 V est à la limite du seuil et provoque des LED fantômes.
- Oublier la pause > 50 µs sans impulsion : la trame n'est pas verrouillée et les LED clignotent en aléatoire.
- Utiliser une machine d'état déjà occupée : vérifier les SM libres, MicroPython ou un programme précédent peut en réserver.
- Le code MicroPython officiel rp2 de référence est documenté pour RP2040 ; sur RP2350, tester la fréquence si les timings semblent dériver.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython