🛠 Piloter un ruban WS2812 sans bloquer le CPU : WS2812Serial et OctoWS2811

Teensy 4.0 · intermediaire · Schéma : IMG-teensy-40-intermediaire-4-teensy40-ruban-ws2812-dma.svg — Teensy 4.0 alimentant un ruban de 60 WS2812B : data sur la broche 1 (TX de Serial1), résistance de données, condensateur 1000 µF sur la ligne 5 V du ruban ; encart « DMA : le CPU continue de tourner pendant l'envoi ».

Objectives

The Teensy is THE reference for lighting installations. Two PJRC libraries compete advantageously: WS2812Serial (up to 8 non-blocking instances, each on a UART port used as a DMA waveform generator) and OctoWS2811 (DMA refresh at a video rate of 30 Hz — and on the Teensy 4.0, "supports use of any number of digital pins", so we are no longer limited to the 8 pins of the Teensy 3.x). This tutorial uses WS2812Serial: your sketch continues to run at full speed while the DMA sends the frames.

Hardware

Complete Code

// 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);
}

Expected Verification

The rainbow scrolls at 50 frames/s. Non-blocking test: add a counter Serial.println(millis) in loop — it scrolls normally WHILE the LED frames are being sent, proving that the DMA works on its own. For a massive installation (HUB75 RGB 32x16 panels up to 128x64), look instead at SmartMatrix + the SmartLED v5 shield; for strips driven at a 30 Hz video rate, OctoWS2811.

Common Errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials