WS2812B strips put a tiny controller inside every LED, so one GPIO drives the whole strip. The ESP32 handles the 800 kHz timing in hardware.
Two things matter on an ESP32: power (each LED can draw 60 mA, so anything beyond a short strip needs its own 5 V supply with a shared ground) and logic level (the strip is 5 V, the ESP32 is 3.3 V — usually fine on short wires, with a buffer as the fix if not).
Wiring
| ESP32 DevKit V1 | WS2812B addressable RGB LED strip (NeoPixel) | Wire | Notes |
|---|---|---|---|
| D13 | DIN | green | Via 330 Ω — Series resistor close to the first LED protects its input. |
| VIN | 5V | red | About 8 LEDs at low brightness from USB. Longer strips: separate 5 V supply, 1000 µF capacitor across it, common GND. |
| GND | GND | black |
5 V (about 60 mA per LED at full white) part, 3.3 V board. The strip expects a data HIGH of about 3.5 V at 5 V supply. From ESP32 or Pico the 3.3 V signal often works with short wires, but to be safe drive DIN through a 74AHCT125 (or 74HCT125) powered from 5 V.
Board quirks
- The strip runs at 5 V and expects at least about 3.5 V for a logic HIGH; the ESP32’s 3.3 V usually works on short wires. If the first LED flickers, add a 74AHCT125 buffer powered from 5 V.
- Brightness is capped at 40/255 so 8 LEDs stay well under 500 mA — full white is about 60 mA per LED.
- The ESP32 core sends NeoPixel data with the RMT peripheral, so Wi-Fi doesn’t disturb the timing.
Code
// WS2812B LED strip (8 LEDs) on an ESP32 DevKit V1.
// DIN → D13 through a 330 Ω resistor, strip 5V → VIN (short strip only), GND → GND.
#include <Adafruit_NeoPixel.h>
constexpr uint8_t LED_PIN = 13;
constexpr uint16_t LED_COUNT = 8;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
strip.begin();
strip.setBrightness(40); // keeps current low on USB power (~20 mA per LED at this level)
strip.show();
Serial.println("WS2812B rainbow on GPIO13");
}
void loop() {
static uint16_t hue = 0;
for (uint16_t i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(hue + i * 65536UL / LED_COUNT)));
}
strip.show();
hue += 256;
delay(20);
}// WS2812B LED strip (8 LEDs) on an ESP32 DevKit V1.
// DIN → D13 through a 330 Ω resistor, strip 5V → VIN (short strip only), GND → GND.
#include <Adafruit_NeoPixel.h>
constexpr uint8_t LED_PIN = 13;
constexpr uint16_t LED_COUNT = 8;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
strip.begin();
strip.setBrightness(40); // keeps current low on USB power (~20 mA per LED at this level)
strip.show();
Serial.println("WS2812B rainbow on GPIO13");
}
void loop() {
static uint16_t hue = 0;
for (uint16_t i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(hue + i * 65536UL / LED_COUNT)));
}
strip.show();
hue += 256;
delay(20);
}Library: Adafruit NeoPixel (Adafruit) — compiled with Adafruit NeoPixel 1.15.5.
Expected serial output
WS2812B rainbow on GPIO13WS2812B rainbow on GPIO13
Common errors
First LED wrong colour, rest fine
Marginal 3.3 V data. Shorten the data wire, keep the 330 Ω resistor, or add a 74AHCT125 level buffer.
Colours swapped (red shows green)
Some strips are RGB, not GRB. Change NEO_GRB to NEO_RGB.