This part has a page of its own, with a note on using it and a circuit to try: the part page.
WS2812 addressable LEDs
Addressable RGB LEDs on one wire, with no clock: aliases WS2812B, NeoPixel. A strip, a ring, or a 16-wide matrix, all the same part.
There is no clock line. A bit is a high pulse whose length is the bit, 0.4 microseconds for a 0 and 0.8 for a 1, twenty-four bits per LED, green first. The part decodes those pulses off the pin's own edges, with the same timing tolerance a real strip has.
Pins
| Pin | What it does |
|---|---|
VDD |
Supply. |
VSS |
Ground. |
DIN |
The pulse-coded data line in. |
DOUT |
Whatever is left of the frame after this device's own LEDs, for chaining. |
Properties
count: how many LEDs. layout: strip, ring or matrix. serpentine: whether a
matrix is wired boustrophedon (every other row reversed), which the wiring decides
and the data alone cannot say.
What the model gets right
layout = "ring" bends the same row of LEDs into a circle, LED 0 at twelve o'clock
and the rest clockwise, exactly how the rings people buy are numbered. A ring is a
strip electrically, so nothing about the wiring or the firmware changes, only the
picture does. Nothing is shown until the latch: 50 microseconds of a quiet line ends
the frame, and every LED takes up its new color at once, the way a real strip does.
What it does not model
No brightness curve beyond a straight RGB value, and no power draw per LED, so a strip here never browns out a board's supply the way a long real one can.
The decode is the datasheet's windows. A high pulse under 125 ns is a glitch and is ignored; from there to 600 ns is a nought and from 600 ns to 950 ns is a one, 950 ns being T1H at the top of its ±150 ns tolerance. The low between bits is checked too (at least 300 ns after a one and 700 ns after a nought, both the bottom of their tolerances), and a stream that breaks either rule abandons the frame, the way a real strip stops following one it cannot read. The total bit period is not checked on top of that: the datasheet's own figure is 1.25 us ±600 ns, which constrains nothing once both halves are, and real strips take faster streams than 1.25 us happily. The 300 ns of forward delay per device is modeled as a flat 150 ns.
The latch is 50 microseconds of quiet, which is the original WS2812B figure; a WS2812B-V5 wants 280 microseconds, so a driver written against this one can produce a frame that never latches on newer strips. The color order is fixed at GRB (there is no RGBW and no way to say a strip is wired otherwise), and there is no per-LED refresh, no gamma, no thermal limit and no maximum of anything except the 1024 LEDs one part will hold.
Common mistakes
Driving it from an Uno's digitalWrite at full software-bus speed: an ESP32-C3
header can bit-bang the WS2812 protocol with a counted loop because it runs fast
enough, but an Uno at 16 MHz has nowhere near enough cycles per bit to do the same
without hand-written assembly, which is why every WS2812 example here uses an
ESP32-C3.
Code
The Adafruit NeoPixel tutorial compiles as it stands on the ESP32-C3 and the ESP32-C6:
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(8, 4, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
}
void loop() {
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 150, 0));
pixels.show();
delay(500);
}
Adafruit_NeoPixel.h is Mokxi's own header on the ESP32-C3's WS2812 driver,
with setPixelColor, Color, ColorHSV, fill, clear, setBrightness,
gamma32 and rainbow. Every strip in a sketch shares one fixed pool of 1024
LEDs rather than taking its buffer from the heap. NEO_RGB and the other orders
send the bytes in that order, so a WS2812B shows them swapped, as a real one
does. On any other board the header stops with a message, for the reason under
Common mistakes above.
See it in action
Ring Simon, Rainbow strip and Plasma panel all drive a WS2812 ring or matrix from an ESP32-C3. Open them at /templates, and read the parts games are made of for more on the protocol and the driver.