🛠 Animer un ruban NeoPixel avec un PIO

Raspberry Pi Pico 2 · intermediaire · Schéma : IMG-pico-2-intermediaire-2-pico2-pio-ruban-led.svg — ruban de LED WS2812 connecté à GP3 de la Pico 2, bloc PIO interne générant le protocole, alimentation 5 V séparée

Objectives

Understand the PIO block of the RP2350 — 3 blocks and 12 state machines, compared to 2/8 on the RP2040 — by implementing the WS2812 (NeoPixel) protocol without consuming CPU time. The PIO alone generates the ~1.25 µs slots per bit, while the two M33 cores do other things.

Hardware

Complete code

# 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)

Expected verification

The LEDs animate in a loop. Key point: the CPU remains available — add a GP25 blink in the loop, it stays synchronous even during show, because the PIO handles the timing alone. This is the great strength of the 12 SMs of the RP2350.

Common errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials