ESP32 Part 1 - Foundations

E06. Addressable RGB LEDs: NeoPixel / WS2812 Strips

Power a short NeoPixel strip safely, fill it with one colour, then send a single dot running along it.

Estimated time 3 hours

Learning outcomes

  • Explain how many LEDs can share one data wire
  • Power a strip from 5 V with a shared GND and a data resistor
  • Set colours with Color(red, green, blue) and send them with show()
  • Use a for loop to light the LEDs one at a time

Parts and preparation

ESP32 DevKit, 8-LED WS2812 / NeoPixel strip or stick, external 5 V supply, ~330-470 ohm data resistor, optional bulk capacitor, jumper wires. Library: Adafruit NeoPixel by Adafruit.

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

Libraries for this lesson

In Arduino IDE 2 open Tools → Manage Libraries…. Search by the Library Manager name and install the package by the exact author below. Similar names from other authors can use different APIs and will break the example.

IncludeLibrary Manager nameAuthorInstall note
Adafruit_NeoPixel.hAdafruit NeoPixelAdafruitInstall via Library Manager. Choose Adafruit NeoPixel by Adafruit.

What you will do

NeoPixels are colour LEDs that each have a tiny chip inside, so one wire can set every LED to its own colour.

Sketch 1 fills the whole strip with one colour. Sketch 2 sends a single green dot running along the strip.

ESP32 data pin feeding chained NeoPixels
One data wire; power is a separate path.

One data wire, many LEDs

The LEDs are numbered from 0, starting at the end with the data input (DIN). Commands like setPixelColor() and fill() only change the colours in the ESP32's memory. Nothing changes on the strip until you call show().

CommandWhat it does
strip.Color(r, g, b)Makes a colour from red, green and blue, each 0-255
strip.fill(colour)Sets every LED to the colour (in memory)
strip.setPixelColor(i, colour)Sets LED number i (in memory)
strip.clear()Sets every LED to off (in memory)
strip.show()Sends the colours to the strip - now they light up

Power first: 5 V, GND and current

Each LED can use up to about 60 mA at full white. Eight LEDs at full white is nearly half an amp. Do not power the strip from the ESP32 3V3 pin. Use 5 V, and connect the strip GND to the ESP32 GND. Keep colour values low (about 80 out of 255) in class - it is still bright.

External 5 V NeoPixel supply with common GND and data resistor
External 5 V; common GND; data through ~330-470 ohm.
Strip pinConnect to
5 V / VCC5 V supply (not the ESP32 3V3 pin)
GNDSupply GND and ESP32 GND
DINGPIO 5 through a 330-470 ohm resistor

Arrows and colour order

Strips have arrows printed on them. Feed data in at the start of the arrows (DIN). If red shows as green, change NEO_GRB to NEO_RGB in the sketch.

Wiring and safe build sequence

  1. Power off before connecting the strip
  2. Strip 5 V -> 5 V supply; strip GND -> supply GND and ESP32 GND
  3. ESP32 GPIO 5 -> 330-470 ohm -> strip DIN
  4. Sketch 1 only, short 8-LED stick at low brightness: strip 5 V may come from the DevKit VIN/5V pin, as in the first photo
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.

Worked sketch 1: Fill the strip with one colour

Download .ino

What this sketch is for: The whole strip should glow dim red. That proves the power, the data wire and the library all work. Match the breadboard layout below before upload (short 8-LED stick only).

Breadboard layout for ESP32 NeoPixel stick: GPIO 5 data, VIN 5 V and GND to an 8-LED strip
Breadboard for sketch 1: ESP32 GPIO 5 to strip DIN; strip 5 V from ESP32 VIN/V5; strip GND to ESP32 GND. USB can power a short 8-LED stick at low brightness - use the sketch 2 wiring for longer strips. Click to enlarge.
#include <Adafruit_NeoPixel.h>         // the NeoPixel library

const int dataPin = 5;                 // the strip's DIN wire is on GPIO 5
const int ledCount = 8;                // how many LEDs are on the strip

// describe the strip: how many LEDs, which pin, and the usual NeoPixel settings
Adafruit_NeoPixel strip(ledCount, dataPin, NEO_GRB + NEO_KHZ800);

void setup() {                         // runs once
  strip.begin();                       // get the strip ready
  strip.fill(strip.Color(80, 0, 0));   // every LED dim red (red 80, green 0, blue 0)
  strip.show();                        // send the colours to the strip
}

void loop() {                          // nothing to repeat in this sketch
}

How the code works

  1. Color(80, 0, 0) is red 80, green 0, blue 0 - each can go up to 255.
  2. Without strip.show() nothing lights up.
  3. Build from the breadboard photo: data on GPIO 5; a short stick may use VIN 5 V.
  4. GPIO 5 is a start-up pin, but the strip does not disturb it, so it is safe for the data wire.

Worked sketch 2: A running dot

Download .ino

What this sketch is for: A for loop lights the LEDs one at a time, so a green dot runs along the strip. Match the 5 V supply breadboard below before upload.

Breadboard layout for ESP32 NeoPixel with external 5 V DC supply, GPIO 5 data and common GND
Breadboard for sketch 2: external DC jack feeds strip 5 V and GND; ESP32 GPIO 5 to DIN; ESP32 GND tied to the supply ground (common GND). A long strip needs its own 5 V supply as shown - do not power it through the ESP32. USB still powers the ESP32 only. Click to enlarge.
#include <Adafruit_NeoPixel.h>                     // the NeoPixel library

const int dataPin = 5;                             // the strip's DIN wire is on GPIO 5
const int ledCount = 8;                            // how many LEDs are on the strip

// describe the strip: how many LEDs, which pin, and the usual NeoPixel settings
Adafruit_NeoPixel strip(ledCount, dataPin, NEO_GRB + NEO_KHZ800);

void setup() {                                     // runs once
  strip.begin();                                   // get the strip ready
}

void loop() {                                      // runs over and over
  for (int i = 0; i < ledCount; i++) {             // i counts 0, 1, 2 ... 7
    strip.clear();                                 // all LEDs off (in memory)
    strip.setPixelColor(i, strip.Color(0, 80, 0)); // LED number i green (in memory)
    strip.show();                                  // send the colours to the strip
    delay(100);                                    // wait so you can see the dot
  }
}

How the code works

  1. clear() before each new dot turns the previous LED off.
  2. LED numbers start at 0, so an 8-LED strip uses 0 to 7.
  3. A long strip needs its own 5 V supply as shown in the breadboard.

Test and record evidence

Expected result: Sketch 1: every LED glows dim red and stays on. Sketch 2: one green dot runs from the first LED to the last, then starts again.

Practical evidence checklist

Common faults and checks
  • Nothing lights: check 5 V, the shared GND, the arrow direction (DIN end), and that Adafruit NeoPixel is installed.
  • Wrong colours: change NEO_GRB to NEO_RGB.
  • Board resets when the strip lights: lower the colour values or use a stronger 5 V supply.
  • Flicker or random colours: keep the data wire short. For long strips, a 3.3 V to 5 V level shifter (for example 74AHCT125) helps.
Challenge (extension - optional): Change sketch 1 to blue (0, 0, 80), then amber (50, 30, 0). Harder: in sketch 2, make the dot run faster, then make it red.

Check your understanding

Q1. Why must you call show()?

Show answer

Colour changes stay in the ESP32's memory until show() sends them to the strip.

Q2. What does strip.Color(0, 80, 0) make?

Show answer

A dim green.

Q3. About how much current can one LED use at full white?

Show answer

About 60 mA.

Q4. Where should the strip's 5 V come from?

Show answer

A 5 V supply - not the ESP32 3V3 pin.

Q5. What must the ESP32 and the strip supply share?

Show answer

GND.

Q6. Which GPIO carries the strip data in this lesson?

Show answer

GPIO 5.

Q7. On an 8-LED strip, what is the number of the last LED?

Show answer

7 - the numbers start at 0.