Reference
NeoPixels (WS2812B) – Complete Guide
Individually addressable RGB LEDs that need just one data pin to control hundreds of LEDs, each with its own 24-bit color. This guide covers the WS2812B family, wiring to an ESP32-C6 SUPER MINI, power budgeting, and ESP-IDF/Arduino example code.
- 5 V
- 3.5 to 5.3 V
- 800 kHz one-wire
- 24-bit colour
NeoPixels are individually addressable RGB LEDs that need just one data pin to control hundreds of LEDs, each with its own 24-bit color. NeoPixel is Adafruit’s brand name for LEDs based on the WS2812B and its successors, but whatever name they’re sold under, they all speak the same single-wire protocol. Combined with the ESP32-C6 SUPER MINI (which even has one on board!) they are the easiest way to add spectacular lighting to any project.
In this complete guide we cover:
- What NeoPixels are
- Technical specifications
- Pinout
- NeoPixel variants compared (WS2812B, SK6812, WS2813, WS2815)
- The single-wire protocol explained
- ESP32-C6 SUPER MINI wiring
- Power requirements, calculation table
- ESP-IDF example code (RMT / led_strip)
- NeoPixel vs DotStar (APA102) comparison
- Practical engineering tips
The chip numbers in this guide come from the WS2812B datasheet (Worldsemi). Strip, ring and matrix details come from common practice, so check your own product.
What are NeoPixels?
A NeoPixel is a smart LED: an RGB LED with a tiny driver IC built into the same package. Each LED:
- Has its own 24-bit color (8 bits per channel, 16.7 million colors)
- Reads the first 24 bits of incoming data, then passes the rest on to the next LED
- Can be chained almost endlessly: DOUT → DIN → DOUT → DIN…
The result: one GPIO pin controls an entire strip, with every LED individually addressable. No multiplexing, no driver ICs, no PWM channels, just power, ground and one data line.

NeoPixels come in every imaginable form factor: strips (30/60/144 LEDs per meter), rings, matrices, sticks, and single through-hole or SMD LEDs.
Technical Specifications (WS2812B)
| Parameter | Value |
|---|---|
| Supply voltage | 3.5V – 5.3V (5V nominal) |
| Colors | 24-bit (8 bits × R, G, B) |
| Color order | GRB |
| Data protocol | Single-wire, 800 kHz |
| Data input level | ≥ 0.7 × VDD (3.5V at 5V supply!) |
| Current per LED | ~60 mA max (full white), ~1 mA idle |
| PWM refresh rate | ~2 kHz |
| Reset/latch time | > 50 µs (data low) |
| Operating temperature | -25°C to +80°C |
Note that data input level: at a 5V supply, the WS2812B officially wants at least 3.5V on the data line, more than the 3.3V an ESP32 delivers. In practice it almost always works, but it is out of spec. The solutions are covered in the wiring section below.
Dimensions
The WS2812B is an RGB LED with the driver chip in the same 5050 package, which is 5.0 × 5.0 mm. A strip packs these at 30, 60 or 144 pixels per metre, so the size you work with is the strip: width, thickness and pixel pitch differ between makers, and a waterproof sleeve adds more. Measure yours before you design a channel or a diffuser. Rings, sticks and matrices have their own board sizes.
Source: WS2812B datasheet for the package. Strip sizes are typical and not from the datasheet.
Pinout
Every NeoPixel, strip or single LED, has four connections:
| Pin | Description |
|---|---|
| VDD (5V) | Power supply |
| GND | Ground |
| DIN | Data in, from the ESP32 or the previous LED |
| DOUT | Data out, to the next LED |
Direction matters! Data flows only from DIN to DOUT. Strips have arrows printed on them, always connect your ESP32 to the DIN side. Connecting to DOUT does nothing (and breaks nothing, fortunately).
NeoPixel Variants Compared
“NeoPixel” covers a whole family of chips. These are the ones you’ll actually encounter:
| Feature | WS2812B | SK6812 | SK6812 RGBW | WS2813 | WS2815 |
|---|---|---|---|---|---|
| Supply voltage | 5V | 5V | 5V | 5V | 12V |
| Colors | RGB | RGB | RGB + White | RGB | RGB |
| Backup data line | No | No | No | Yes (BIN) | Yes (BIN) |
| One dead LED kills the rest | Yes | Yes | Yes | No | No |
| Current per LED (max) | 60 mA | 60 mA | 80 mA | 60 mA | 15 mA (12V) |
| Voltage drop over long strips | High | High | High | High | Low |
Which one should you pick?
- WS2812B, the default. Cheap, everywhere, fine for most projects
- SK6812 RGBW, when you need proper white light (warm/neutral/cold white die)
- WS2813/WS2815, installations where one dead LED must not take down the chain
- WS2815 (12V), long runs (> 5 m) with minimal voltage drop and thinner wiring
The Single-Wire Protocol Explained
NeoPixels don’t use I²C or SPI, but a timing-based protocol at 800 kHz:
- A 0-bit = short high pulse (~0.4 µs) followed by long low
- A 1-bit = long high pulse (~0.8 µs) followed by short low
- > 50 µs low = latch: all LEDs display their received color
Each LED consumes the first 24 bits (in GRB order) and forwards everything after. The timing tolerances are tight, which is why bit-banging is unreliable. The ESP32 has the perfect answer: the RMT peripheral, which generates these precise pulse trains in hardware while the CPU does other things. The ESP-IDF led_strip component uses it under the hood, so you never touch the timing yourself.
Connecting to the ESP32-C6 SUPER MINI
Fun fact first: the ESP32-C6 SUPER MINI already has one onboard NeoPixel connected to GPIO8, perfect for testing your code before wiring anything.

For an external strip:
| NeoPixel Strip | ESP32-C6 SUPER MINI / PSU | Note |
|---|---|---|
| VDD (5V) | 5V pin (few LEDs) or external 5V PSU | See power table below |
| GND | GND, shared with PSU! | Always connect grounds |
| DIN | GPIO4 (via 330 Ω resistor) | Any free GPIO works |
Three components make the difference between “works sometimes” and “works always”:
- 330–470 Ω resistor in the data line, close to the first LED, protects the first pixel against voltage spikes and reflections
- 1000 µF capacitor across 5V and GND at the strip, absorbs the inrush current at power-on
- Level shifter (74AHCT125) from 3.3V → 5V for the data signal, the official fix for the 0.7 × VDD requirement
No level shifter at hand? Two pragmatic tricks:
- Keep the data wire short (< 20 cm), usually works fine despite being out of spec
- Or the sacrificial pixel trick: power the first LED from ~4.3V (5V through a diode). Its DOUT then swings to ~4.3V, which is comfortably in spec for the rest of the strip at 5V
Never power more than ~10 LEDs from the SUPER MINI’s 5V pin, that pin comes straight from your USB port.
Power Requirements – Calculation Table
The rule of thumb: 60 mA per LED at full white, full brightness. Realistic mixed-color animations average 20 mA. Always size your PSU for the worst case:
| LEDs | Max current (full white) | Recommended 5V PSU |
|---|---|---|
| 8 (stick/ring) | 0.5 A | USB port is fine |
| 30 (1 m @ 30/m) | 1.8 A | 5V 2.5A |
| 60 (1 m @ 60/m) | 3.6 A | 5V 4A |
| 144 (1 m @ 144/m) | 8.6 A | 5V 10A |
| 300 (5 m @ 60/m) | 18 A | 5V 20A + power injection |
From roughly 1–2 meters onwards, inject power at both ends of the strip (and every meter on dense strips). Copper traces have resistance: feed a 5 m strip from one end only and the far end turns visibly orange because the blue channel starves first.
Software helps too: limiting brightness to 50% halves your power budget and is still blindingly bright indoors.
ESP-IDF Example Code
ESP-IDF has an official led_strip component that drives NeoPixels via the RMT peripheral. Add it to your project:
idf.py add-dependency "espressif/led_strip"This example runs a smooth rainbow on a 10-LED strip connected to GPIO4:
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"
#include "esp_log.h"
#define LED_GPIO 4
#define LED_COUNT 10
static const char *TAG = "NEOPIXEL";
static led_strip_handle_t strip;
/* Simple HSV to RGB for smooth rainbows */
static void hsv_to_rgb(uint16_t h, uint8_t *r, uint8_t *g, uint8_t *b)
{
uint8_t region = (h / 60) % 6;
uint8_t rem = (h % 60) * 255 / 60;
switch (region) {
case 0: *r = 255; *g = rem; *b = 0; break;
case 1: *r = 255 - rem; *g = 255; *b = 0; break;
case 2: *r = 0; *g = 255; *b = rem; break;
case 3: *r = 0; *g = 255 - rem; *b = 255; break;
case 4: *r = rem; *g = 0; *b = 255; break;
default:*r = 255; *g = 0; *b = 255 - rem; break;
}
}
void app_main(void)
{
led_strip_config_t strip_config = {
.strip_gpio_num = LED_GPIO,
.max_leds = LED_COUNT,
.led_model = LED_MODEL_WS2812,
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
};
led_strip_rmt_config_t rmt_config = {
.resolution_hz = 10 * 1000 * 1000, /* 10 MHz tick */
};
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &strip));
ESP_LOGI(TAG, "NeoPixel strip initialized: %d LEDs on GPIO%d", LED_COUNT, LED_GPIO);
uint16_t offset = 0;
while (1) {
for (int i = 0; i < LED_COUNT; i++) {
uint8_t r, g, b;
uint16_t hue = (offset + (i * 360 / LED_COUNT)) % 360;
hsv_to_rgb(hue, &r, &g, &b);
/* 25% brightness, easy on the eyes and the PSU */
led_strip_set_pixel(strip, i, r / 4, g / 4, b / 4);
}
led_strip_refresh(strip);
offset = (offset + 2) % 360;
vTaskDelay(pdMS_TO_TICKS(20));
}
}Want to test without wiring anything? Change LED_GPIO to 8 and LED_COUNT to 1, the onboard NeoPixel of the SUPER MINI will run the rainbow.
Prefer Arduino?
With the Adafruit NeoPixel library:
#include <Adafruit_NeoPixel.h>
#define LED_PIN 4
#define LED_COUNT 10
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.setBrightness(64); // 25%
}
void loop() {
static uint16_t offset = 0;
for (int i = 0; i < LED_COUNT; i++) {
uint16_t hue = offset + (i * 65536L / LED_COUNT);
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(hue)));
}
strip.show();
offset += 256;
delay(20);
}NeoPixel vs DotStar (APA102)
The main alternative is the APA102 (Adafruit: DotStar), which uses two-wire SPI:
| Feature | NeoPixel (WS2812B) | DotStar (APA102) |
|---|---|---|
| Wires | 1 (data) | 2 (data + clock) |
| Protocol | Strict 800 kHz timing | SPI, any speed |
| Update speed | ~33 fps @ 1000 LEDs | 10× faster and more |
| PWM refresh | ~2 kHz | ~20 kHz |
| Timing-critical | Yes | No |
| Price | Low | Noticeably higher |
| Availability | Everywhere | Limited |
When to Choose NeoPixels
- Almost always: cheapest, most available, one pin
- Static colors and normal animations
- The ESP32 RMT peripheral makes the timing problem disappear
When to Choose DotStars
- POV displays, light painting (high refresh)
- Video capture without flicker (20 kHz PWM)
- Extremely long chains needing fast updates
Practical Engineering Tips
1. GND First, Always
When connecting a strip to a powered system, connect ground first. A data signal without a common ground reference can kill the first pixel.
2. The First Pixel Is the Fuse
If a strip misbehaves, the first LED is broken in 90% of cases, it absorbs all the abuse (spikes, level issues, hot-plugging). Cut it off, reconnect at LED 2, and the strip usually springs back to life.
3. Set the Brightness Limit in Software
led_strip at full white is a heater. Cap brightness at 25–50% in code: your PSU, your LEDs (heat!) and your eyes will thank you. Add a fuse in the 5V line for larger installations.
4. Watch Out with WiFi and Bit-Banged Drivers
On the ESP32, always use RMT-based drivers (ESP-IDF led_strip, or NeoPixelBus with RMT). Bit-banged or interrupt-based drivers glitch the moment WiFi traffic arrives, resulting in random flashes.
5. Ghosting on Long Data Runs
More than ~2 m between ESP32 and first pixel? Use a proper level shifter and twist the data wire with a ground wire. For really long runs, a differential driver (RS-485 transceiver pair) is bulletproof.
Real gotchas
- The data level is 0.7 × VDD. At 5 V the chip wants at least 3.5 V on DIN, and an ESP32 gives 3.3 V. It often works, but a level shifter (74HCT125 or similar) is the reliable fix, or power the first pixel from a slightly lower voltage.
- The timing is tight. A 0 bit is about 0.4 µs high and 0.85 µs low, a 1 bit is about 0.8 µs high and 0.45 µs low, each with ±150 ns. Do not bit-bang it with interrupts running. Use the RMT peripheral, SPI or a library.
- Reset needs more than 50 µs low. The latch happens after the data line stays low for more than 50 µs. Some newer chips need 280 µs, so allow for that.
- The power supply voltage is 3.5 to 5.3 V. The datasheet says the chip survives a reversed supply (reverse connect protection), but do not rely on it for a whole strip.
- Colour order is GRB. Send green first. Some clones use RGB. If the colours are wrong, change the order in the library.
- One broken pixel stops the rest. The data passes through every chip. A dead pixel cuts off all pixels after it.
- Voltage drops along long strips. The last pixels turn yellow or dim. Inject power at both ends and at intervals.
- Heat. A full-white strip draws about 60 mA per pixel and gets hot. Limit the brightness in software and mount the strip on aluminium for long runs.
- Large capacitors. Put a capacitor of 1000 µF across the supply of a strip to absorb the switch-on surge, and a resistor of 300 to 500 Ω in series with the data line.
- Connect ground first. A data signal without a common ground can destroy the first pixel.
Safety notes
Before you wire anything up
- Use a power supply that matches the strip: 5 V for WS2812B. The datasheet gives 3.5 to 5.3 V. A 12 V supply destroys the pixels at once.
- Size the supply for the worst case: 60 mA per pixel at full white is 18 A for 300 pixels. Use fuses and wires that can take it.
- Wires and strips that carry amps get hot. Do not bundle them under insulation, and never leave a full-white strip unattended.
- Never connect LED strips directly to mains voltage. Use a certified low-voltage supply, and let an electrician do any mains work.
- Flashing patterns can trigger a photosensitive reaction in some people. Avoid fast strobing in public places.
- Never connect the board to mains voltage. Keep it on a low-voltage supply.
- Disconnect the power before you change the wiring.
Conclusion
NeoPixels turned addressable lighting from an engineering challenge into a commodity: one GPIO, three wires, endless possibilities. They offer individual control of every LED over a single pin, 16.7 million colors chainable into the hundreds, hardware-perfect timing thanks to the ESP32 RMT peripheral, a free test pixel on board of the ESP32-C6 SUPER MINI (GPIO8), and an ecosystem of strips, rings, matrices and libraries.
Pair them with a properly sized power supply, add the resistor and capacitor, and you have lighting that simply works, from a single status LED to a room-filling installation. See the HomeKit NeoPixel Controller project for exactly this, built on an ESP32-C3 Super Mini.
More guides
Keep building.
From ESP32 HomeKit accessories to Arduino and ATtiny reference guides, there’s more where this came from.
All guides

