Overview
The WS2812B (also known as "NeoPixel" in Adafruit's branding) is a 5V individually-addressable RGB LED strip with a built-in driver IC inside each LED package. A single data wire from your microcontroller can control hundreds of LEDs — each one with full 24-bit color and 256 brightness levels per channel — making it the world's most popular LED strip for makers, lighting designers, and stage builders.
This non-waterproof SMD strip ships in a 5-meter roll with 60 LEDs per meter (300 LEDs total) on a flexible IP30 PCB. The strip can be cut between any two LEDs along the marked cut lines, soldered onto, and chained with additional strips. Compatible with Arduino, ESP32, Raspberry Pi, and Pico via the FastLED, Adafruit NeoPixel, and rpi_ws281x libraries.
At a Glance
Specifications
| Parameter | Value |
| LED Model | WS2812B (5050 SMD package) |
| Operating Voltage | 5V DC (4.5V - 5.5V acceptable) |
| Current per LED (full white) | ~60 mA |
| Current per Meter (full white, 60 LEDs) | ~3.6 A |
| Current per 5m Roll (full white) | ~18 A |
| Communication Protocol | WS2812 single-wire (800 kHz NRZ) |
| Color Depth | 24-bit (8-bit per R / G / B channel) |
| LEDs per Meter | 60 |
| Roll Length | 5 m (300 LEDs total) |
| IP Rating | IP30 (non-waterproof) |
| Strip Width | 10 mm |
| Cuttable | Every 1 LED (~16.7 mm) |
| Backing | Self-adhesive 3M tape |
| Operating Temperature | -25 to +80 C |
Pinout Diagram
Wiring Guide
Arduino Wiring
Arduino's 5V GPIO matches the WS2812B's signal level, so no level shifter is needed. Power the strip from a separate 5V supply sized for your LED count — the Arduino's onboard 5V regulator cannot supply enough current for more than ~10 LEDs at full brightness.
| Strip Pin | Arduino Pin | Details |
|---|---|---|
| +5V | External 5V supply (+) | Size for 60 mA per LED |
| GND | Supply GND + Arduino GND | Common ground required |
| DIN | Digital Pin 6 | With 470 ohm series resistor |
ESP32 Wiring
ESP32 GPIO outputs 3.3V which is BELOW the WS2812B's nominal 0.7 x VCC = 3.5V high threshold. In practice it usually works for the first LED at room temperature, but reliability is marginal — use a 74HCT245 or similar 5V level shifter for production-quality builds.
| Strip Pin | ESP32 Pin | Details |
|---|---|---|
| +5V | External 5V supply (+) | Size for 60 mA per LED |
| GND | Supply GND + ESP32 GND | Common ground required |
| DIN | GPIO 5 | Via 74HCT245 level shifter (recommended) |
Raspberry Pi Wiring
Raspberry Pi GPIO is 3.3V — the same caveat as ESP32 applies. Use a level shifter for reliable operation. The rpi_ws281x Python library uses the PWM or SPI peripheral to generate the strict WS2812 timing.
| Strip Pin | Raspberry Pi Pin | Details |
|---|---|---|
| +5V | External 5V supply (+) | DO NOT use Pi's 5V rail for the strip |
| GND | Supply GND + Pin 6 (Pi GND) | Common ground required |
| DIN | Pin 12 (GPIO 18, PWM0) | Via 74AHCT125 level shifter (recommended) |
Raspberry Pi Pico Wiring
Pico's PIO (Programmable I/O) is ideal for WS2812B — it generates the exact 800 kHz timing in hardware while your main program runs untouched. As with ESP32 and Pi, the 3.3V output is borderline; use a level shifter for reliability.
| Strip Pin | Pico Pin | Details |
|---|---|---|
| +5V | External 5V supply (+) | Size for 60 mA per LED |
| GND | Supply GND + Pico GND | Common ground required |
| DIN | GP0 (PIO) | Via 74AHCT125 level shifter (recommended) |
Code Examples
Arduino (FastLED)
// WS2812B Strip - Arduino with FastLED
// Install: FastLED library via Arduino Library Manager
// DIN on Digital Pin 6, 30 LEDs (cut from a longer strip)
#include <FastLED.h>
#define DATA_PIN 6
#define NUM_LEDS 30
#define BRIGHTNESS 64 // 0 - 255 (lower = less current draw)
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
// Rainbow chase
static uint8_t hue = 0;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(hue + (i * 8), 255, 255);
}
FastLED.show();
hue++;
delay(20);
}
ESP32 (FastLED with RMT)
// WS2812B Strip - ESP32 with FastLED (RMT-driven)
// DIN on GPIO 5, 60 LEDs
#include <FastLED.h>
#define DATA_PIN 5
#define NUM_LEDS 60
#define BRIGHTNESS 64
CRGB leds[NUM_LEDS];
void setup() {
Serial.begin(115200);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
// Sinelon: a single moving pixel with fading trail
fadeToBlackBy(leds, NUM_LEDS, 20);
int pos = beatsin16(13, 0, NUM_LEDS - 1);
leds[pos] += CHSV(millis() / 10, 200, 255);
FastLED.show();
delay(15);
}
Raspberry Pi (Python)
#!/usr/bin/env python3
# WS2812B Strip - Raspberry Pi Example
# sudo pip install rpi_ws281x
# Run as root (sudo) because PWM access requires root.
import time
from rpi_ws281x import PixelStrip, Color
LED_COUNT = 30
LED_PIN = 18 # GPIO 18 (Pin 12, PWM0)
LED_FREQ_HZ = 800000
LED_DMA = 10
LED_BRIGHTNESS = 64 # 0 - 255
LED_INVERT = False
LED_CHANNEL = 0
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,
LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
strip.begin()
def wheel(pos):
if pos < 85:
return Color(pos * 3, 255 - pos * 3, 0)
elif pos < 170:
pos -= 85
return Color(255 - pos * 3, 0, pos * 3)
else:
pos -= 170
return Color(0, pos * 3, 255 - pos * 3)
try:
j = 0
while True:
for i in range(LED_COUNT):
strip.setPixelColor(i, wheel((i * 256 // LED_COUNT + j) & 255))
strip.show()
j = (j + 1) % 256
time.sleep(0.02)
except KeyboardInterrupt:
for i in range(LED_COUNT):
strip.setPixelColor(i, Color(0, 0, 0))
strip.show()
Raspberry Pi Pico (MicroPython)
# WS2812B Strip - Pico MicroPython with PIO
# DIN on GP0, 30 LEDs
import array
import time
from machine import Pin
import rp2
NUM_LEDS = 30
PIN_NUM = 0
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT,
autopull=True, pull_thresh=24)
def ws2812():
T1, T2, T3 = 2, 5, 3
wrap_target()
label("bitloop")
out(x, 1) .side(0) [T3 - 1]
jmp(not_x, "do_zero") .side(1) [T1 - 1]
jmp("bitloop") .side(1) [T2 - 1]
label("do_zero")
nop() .side(0) [T2 - 1]
wrap()
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM))
sm.active(1)
ar = array.array("I", [0] * NUM_LEDS)
def show():
for i in range(NUM_LEDS):
sm.put(ar[i], 8)
def set_pixel(i, r, g, b):
ar[i] = (g << 16) | (r << 8) | b # GRB order
# Rainbow loop
hue = 0
while True:
for i in range(NUM_LEDS):
h = (hue + i * 8) % 360
# naive HSV to RGB
r = int(255 * max(0, min(1, abs((h/60) % 6 - 3) - 1)))
g = int(255 * max(0, min(1, abs((h/60 + 4) % 6 - 3) - 1)))
b = int(255 * max(0, min(1, abs((h/60 + 2) % 6 - 3) - 1)))
set_pixel(i, r // 4, g // 4, b // 4)
show()
hue = (hue + 5) % 360
time.sleep_ms(30)