How to Control LED Strips With Arduino – Part 3: Individually Addressable LEDs (WS2812B)

by dziubym in Circuits > Arduino

284 Views, 4 Favorites, 0 Comments

How to Control LED Strips With Arduino – Part 3: Individually Addressable LEDs (WS2812B)

s1.png

Welcome to Part 3 of my LED control series with Arduino! In this final installment, we’ll explore WS2812B individually addressable LED strips — the kind that let you control every single LED separately with vibrant, precise colors and animations.

Unlike the analog RGB strips from Part 2, WS2812B strips require only one data pin and give you full control over brightness, color, and effects at the pixel level.

We’ll cover:

  1. How WS2812B LEDs work
  2. How to wire and power them
  3. How to use the FastLED library
  4. How to animate them using the HSV color model
  5. And how to scale your projects from a simple strip to full LED matrices

🎥 Watch the full video tutorial here:

👉 https://youtu.be/YKSFRmvA9A0

📚 Missed the earlier parts?

  1. 💡 Part 1 – Single Color LED Strips https://youtu.be/ms8_rbJWyoo
  2. 🌈 Part 2 – RGB LED Strips https://youtu.be/PEiDzPVk-9g

Each part builds on the last, so feel free to check them out if you're just joining now!

Supplies

To follow along with this project, you'll need:

Core Components:

  1. Arduino Uno, Nano, or Mega (Uno or Nano recommended for beginners)
  2. WS2812B LED strip or WS2812B matrix
  3. (5V version, individually addressable)
  4. 220Ω resistor (for data line protection)
  5. Breadboard and jumper wires
  6. External 5V power supply (2A or higher, depending on LED count)
  7. Barrel jack or screw terminal adapter

️ Optional/Recommended:

  1. 3D-printed LED diffuser panel (improves color blending)
  2. FastLED or NeoPixel library (we’ll use FastLED)
  3. Power distribution board (for large matrices or multiple strips)
  4. Logic level shifter (if your board runs at 3.3V)

Meet the WS2812B – What Makes It Special?

w.png
w1.png

The WS2812B LED strip looks similar to RGB LED strips, but it’s far more powerful and simpler to use. Instead of controlling the whole strip at once, you can control each LED individually using just four connections:

  1. VCC – 5V power
  2. GND – Ground
  3. DIN – Data in
  4. DOUT – Data out

Each LED has a built-in driver chip, which means all the PWM and color mixing is handled internally. You just send digital color data from your Arduino, and each LED takes care of its own brightness and color output.

📌 Key Features:

  1. Only one Arduino pin needed for control
  2. Integrated capacitor (100nF) on each segment for power stability
  3. Directional data flow – you must connect to the end marked DIN
  4. No PWM required – the library handles everything via serial data


Wiring a WS2812B Strip to an Arduino

cone.png
pow.png
ws.png

Wiring WS2812B LEDs is simpler than RGB strips — just one signal pin and two power lines — but getting it wrong can damage your LEDs or Arduino. Let’s do it right.



🔐 Best Practice Add-ons

To protect your LEDs and Arduino:

  1. 220Ω resistor between Arduino pin and DIN → prevents voltage spikes
  2. 1000µF capacitor across VCC and GND at strip input → stabilizes power
  3. Always power off before connecting/disconnecting the strip

✅ Example for 10 LEDs and Arduino Nano:

  1. VCC → Nano 5V
  2. GND → Nano GND
  3. DIN → D6 with a 220Ω resistor inline
  4. Optional: 1000µF cap between VCC and GND


Choosing a Library – FastLED Vs. Adafruit NeoPixel

Libraries.png
r1.png
g1.png

Before you go too far, let’s address a common question:

Which library should you use? FastLED or Adafruit_NeoPixel?

Both libraries support WS2812B and other addressable LEDs — and both are excellent. The right choice depends on your needs.

🧪 A Simple Comparison: Light Up a 7-LED Strip

Let's light up WS2812B LED strips using two sketches using two different libraries:

📚 Code Comparison:

⚡ FastLED Version


#include <FastLED.h>
#define NUM_LEDS 7
#define DATA_PIN 13

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB(255, 0, 0); // Red
}
FastLED.show();
}

What this does:

  1. Lights up all 7 LEDs in bright red using the CRGB(255, 0, 0) color assignment.
  2. FastLED.show() pushes the updated color data to the strip.


💡 Adafruit NeoPixel Version


#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 7
#define DATA_PIN 13

Adafruit_NeoPixel strip(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}

void loop() {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, strip.Color(0, 255, 0)); // Green
}
strip.show();
}

What this does:

  1. Lights up all 7 LEDs in green using strip.Color(0, 255, 0) for each pixel.
  2. strip.show() updates the strip with the new color values.

🎯 Why I Prefer FastLED

While both libraries are solid, I personally prefer FastLED because:

  1. It supports the HSV color model, which makes color transitions smoother and more intuitive
  2. It allows you to define LED colors in multiple ways
  3. It uses the CRGB object to manage color, which is both powerful and readable

🔍 The CRGB Object

FastLED defines each LED as a CRGB object — a structure with three components: red, green, and blue.

Here’s how it’s defined internally:


struct CRGB {
union {
struct {
uint8_t r; // Red component
uint8_t g; // Green component
uint8_t b; // Blue component
};
uint8_t raw[3]; // Access as raw byte array if needed
};
};

📷 [Image: Visual breakdown of CRGB structure]

This lets you set colors very flexibly — using RGB values, HSV, named colors, or even hexadecimal notation.

🎨 Examples: Setting an LED to Magenta

Let’s say you want to make LED 0 display magenta — here are several valid ways using FastLED:

🔴 Using RGB values directly:

leds[0] = CRGB(255, 0, 255); // Magenta

🧠 Using predefined color constants:

leds[0] = CRGB::Magenta;

🌈 Using HSV (hue-saturation-value):

leds[0] = CHSV(192, 255, 255); // Hue 192 = magenta

🟪 Using hexadecimal notation:

leds[0] = 0xFF00FF; // Hex for magenta

All of these methods result in the same color, but each approach shines in different use cases — for example:

  1. HSV is great for animations and gradients
  2. Named colors are fast and readable
  3. RGB is standard and universal
  4. Hex codes match CSS/web color formats

This flexibility is one of the key reasons I favor FastLED for projects where expressive color control matters.

Creating a Flowing Color Animation Using HSV and CHSV

rainbow.png
p1.png
p2.png

This example brings together a few powerful FastLED features — the CHSV color model, timed animations using millis(), and array manipulation — to create a flowing color stream across your LED strip or matrix.

💻 Full Code Overview



#include <FastLED.h>

#define LED_PIN 13
#define NUM_LEDS 65
#define BRIGHTNESS 200
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB

CRGB leds[NUM_LEDS];

uint8_t startColor = 0;
const uint8_t colorStep = 3;
unsigned long lastUpdate = 0;
const unsigned long timeStep = 50;

void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
fill_solid(leds, NUM_LEDS, CRGB::Black);
}

void loop() {
unsigned long currentTime = millis();
if (currentTime - lastUpdate >= timeStep) {
lastUpdate = currentTime;

// Shift all LEDs one step to the right
for (int i = NUM_LEDS - 1; i > 0; i--) {
leds[i] = leds[i - 1];
}

// Insert new hue at the front
leds[0] = CHSV(startColor, 255, 255);

// Advance to the next hue
startColor += colorStep;

FastLED.show();
}
}

🔍 Code Highlights

  1. millis() and timeStep control the update rate without using delay()
  2. leds[i] = leds[i - 1]; shifts the whole array — like moving pixels to the right
  3. CHSV(startColor, 255, 255) gives you full-saturation hues
  4. startColor += colorStep; cycles through hue values over time

🎉 Result

Your LED strip flows continuously with animated color, seamlessly transitioning through the spectrum. It’s dynamic, bright, and visually impressive — ideal for everything from desk lighting to art installations.

✨ This effect already looks fantastic on a loosely tangled LED strip — the overlapping lights blend and scatter color beautifully.

But for an even more polished look, place your strip inside LED channels with diffusion panels. These soften the light, blur the transitions, and give the animation a smooth, professional finish that’s perfect for ambient lighting, under-cabinet effects, or decorative builds.

From Strip to Matrix – Unlocking Visual Possibilities

p3.png
p4.png
p5.png
p6.png

One of the best things about using addressable LEDs is that you’re not limited to a straight line. By arranging your LED strip into a matrix layout, you can transform it into a low-resolution display capable of showing images, animations, and scrolling text.

A matrix is simply a 2D arrangement — like 13 columns by 5 rows — that turns your strip into a grid of pixels.

✨ Why Use a Matrix?

With a matrix, you can:

  1. Light up specific areas or corners of your display
  2. Animate shapes that move across rows and columns
  3. Create immersive effects like waves, comets, or pixel-based fire
  4. Even build custom light-up signs or visual meters

💡 In my case, I reused the same LED strip from earlier steps, but arranged it as a matrix. The simple comet animation — which already looked good in a linear channel — suddenly came alive as a fluid, colorful wave across the grid.

📺 Watch it in action:

See the matrix effects in my full video tutorial:

👉 https://youtu.be/YKSFRmvA9A0

Project Recap + Support + What’s Next

m1.png

You've now completed Part 3 of my LED strip series — and it’s the most powerful yet. You learned how to use individually addressable LEDs (WS2812B) to create rich, flowing animations using just a single data wire and the FastLED library.

✅ What You’ve Achieved

  1. Explored FastLED vs. NeoPixel libraries
  2. Learned why HSV is great for animation
  3. Created smooth, timed color flow across your strip
  4. Saw how a simple animation becomes next-level when run on a matrix layout
  5. Discovered that LED strips can do far more than just blink — they can paint light in motion

Whether you're lighting up your desk, building a display, or just having fun experimenting, you now have the tools to create something vibrant and custom.

☕ Support My Work

If you enjoyed this project and want to support more tutorials like it, consider buying me a coffee on Ko-fi:

👉 https://ko-fi.com/mariosideas

Your support helps me keep making free, high-quality content for makers like you. Thank you!

📺 Explore More on YouTube

Want more Arduino projects, LED tutorials, and experiments?

Check out my channel — I’ve got over 100 videos on all kinds of maker topics.

👉 https://www.youtube.com/channel/UC_YUPxLXSRu_4_zCO27kRww/

There’s always something new to learn, build, and light up.

Thanks for following along — and I’ll see you in the next build! ✨