🛠 Piloter un ruban WS2812 sans bloquer le CPU : WS2812Serial et OctoWS2811
Objectifs
Le Teensy est LA référence des installations lumineuses. Deux bibliothèques PJRC s'affrontent avantageusement : WS2812Serial (jusqu'à 8 instances non bloquantes, chacune sur un port UART utilisé comme générateur de forme d'onde DMA) et OctoWS2811 (rafraîchissement DMA au rythme vidéo de 30 Hz — et sur Teensy 4.0, « supports use of any number of digital pins », on n'est plus limité aux 8 broches des Teensy 3.x). Ce tutoriel utilise WS2812Serial : votre sketch continue de tourner à pleine vitesse pendant que le DMA envoie les trames.
Matériel
- 1 Teensy 4.0 + ruban WS2812B (60 LED/m par exemple)
- Alimentation 5 V DÉDIÉE pour le ruban (60 LED blanches à fond ≈ 3,6 A : l'USB ne suffit pas) — masses communes avec le Teensy
- Résistance 300–470 Ω en série sur la ligne data, condensateur 1000 µF / 6,3 V aux bornes du ruban
- Bibliothèque : https://github.com/PaulStoffregen/WS2812Serial
Code complet
// Arc-en-ciel défilant, envoi par DMA non bloquant.
#include <WS2812Serial.h>
const uint32_t NUM_LEDS = 60;
byte drawingBuffer[NUM_LEDS * 3]; // RGB, un octet par canal
// Broche 1 sur T4 = TX de Serial1. Serial1/3/4/6/7/8 → jusqu'à 8 instances.
WS2812Serial myLEDs(NUM_LEDS, drawingBuffer, 1, 20, WS2812_SERIAL_DEFAULT);
void setup { myLEDs.begin; }
void loop {
static uint8_t hue = 0;
for (uint32_t i = 0; i < NUM_LEDS; i++) { // remplissage du buffer
uint8_t h = hue + (i * 256 / NUM_LEDS);
uint8_t r = (h < 85) ? 255 - h * 3 : (h < 170) ? (h - 85) * 3 : 0;
uint8_t g = (h < 85) ? h * 3 : (h < 170) ? 255 : 255 - (h - 170) * 3;
uint8_t b = (h < 85) ? 0 : (h < 170) ? 255 - (h - 85) * 3 : (h - 170) * 3;
drawingBuffer[i * 3 + 0] = g; // le WS2812 veut de l'ordre GRB
drawingBuffer[i * 3 + 1] = r;
drawingBuffer[i * 3 + 2] = b;
}
myLEDs.show(false); // false = retour immédiat : le DMA envoie
hue += 4; // l'animation tourne à pleine vitesse CPU
delay(20);
}
Vérification attendue
L'arc-en-ciel défile à 50 images/s. Test de non-blocage : ajoutez un compteur Serial.println(millis) dans loop — il défile normalement PENDANT l'envoi des trames LED, preuve que le DMA travaille seul. Pour une installation massive (panneaux HUB75 RGB 32x16 jusqu'à 128x64), regardez plutôt SmartMatrix + le shield SmartLED v5 ; pour des rubans pilotés au rythme vidéo 30 Hz, OctoWS2811.
Erreurs fréquentes
- Alimenter le ruban par le 5 V du Teensy : quelques LED passent, un ruban entier fait plonger la tension et redémarre la carte — alimentation externe dédiée, masses reliées.
- Oublier l'ordre GRB : le buffer dessine en RGB, la trame WS2812 est GRB — rouge et vert inversés, c'est ce piège.
- Confondre les bibliothèques : WS2812Serial occupe un UART par instance (max 8) ; OctoWS2811 utilise des broches GPIO dédiées avec un rafraîchissement vidéo DMA continu.
- Data sur une broche qui n'est pas le TX d'un UART éligible : vérifiez la correspondance broche/UART (Serial1/3/4/6/7/8 sur le 4.0).
- Trame coupée par un code bloquant ailleurs : avec show(false), ne réécrivez pas le drawingBuffer pendant que le DMA lit — patientez ou double-buffer.
- Câble data trop long sans résistance : glitches aléatoires sur les premières LED — la résistance de série côté Teensy est votre amie.
Autres tutoriels pour cette carte
- Premiers pas sur le Teensy 4.0 : Teensyduino, Loader et premier Blink
- GPIO et PWM sous 3,3 V : les règles d'or du Teensy 4.0
- Entrées analogiques et capteur de température interne : le ADC et ses limites
- Contrôleur MIDI USB : un potard qui joue du piano (MIDIx4/MIDIx16)
- Comprendre la mémoire : 2 Mo de flash, 1 Mo de RAM TCM/DMA, EEPROM émulée et LittleFS
- Deux ports USB simultanés : périphérique 480 Mbit/s ET hôte USB sur les pastilles
Exemples de code pour cette carte
clignotante.inoArduinotouche-capacitive.inoArduinoanalogique-12-bits.inoArduinomidi-piano.inoArduinopwm-respiration.inoArduinoservo-angle.inoArduino