Guide for WS2812B Addressable RGB LED Strip with Arduino

This post is about the WS2812B LED strip, which is an addressable RGB LED strip. The information in this post also works with other similar LED strips, such as strips of the WS28XX family, Neopixel strip and others.

Introducing the WS2812B LED Strip

The WS2812B addressable LED strip comes in several models that differ in size, sealant or LED density. Choose the one that best fits your purposes. 

Where to buy?

You can visit Maker Advisor and find the WS2812B RGB LED Strip best price.

In the following figure you can see my WS2812B LED strip. It is 5 meters long and the LEDs are enclosed in a weatherproof silicone. So, they can be left outside at the rain and dust without any problem.

led-strip

In my opinion, this is the coolest type of LED strips. You can control the brightness and the color of each LED individually, which allows you to produce amazing and complex effects in a simple way.

This LED strip is made by WS2812B LEDs wired in series. These LEDs have an IC built right into the LED. This allows a communication via a one-wire interface. This means that you can control lots of LEDs using just one digital pin of your Arduino. 

In the following figure you can see the chip inside the LED. The LED is an RGB LED and works like so.

led-with-arrow

This kind of strips are very flexible and can be cut to any length you want. As you can see, the strip is divided into segments, and each segment contains one RGB LED.  

sections2

You can adjust its size by cutting the strip with a scissors in the right place (the proper places to cut the strip are marked).

cutting-the-strip

These strips come with  connectors  at each end. I’ve decided to cut the connectors, and solder header pins. It’s more handy if you want to connect the strip to an Arduino or to a breadboard.

stripheader

Powering the WS2812B LED Strip

The LED strip should be powered using a 5V power source. At 5V, each LED draws about 50mA, when set to its full brightness.  This means that for every 30 LEDs, the strip may draw as much as 1.5 A. Make sure you select a power source that matches the strip’s needs. An AC to DC power adapter that provides 5V and 2A should do the job:

If you use an external power source, don’t forget to connect the power source ground to the Arduino ground.

Schematics

In this example, the WS2812B LED strip will be powered using the 5V Arduino pin. In my case, I’m controlling 14 LEDs. If you want to control many LEDs, you’ll need to use an external power source.

ws2812b-with-arduino_bb

Useful tips:

  • Connect a capacitor with a capacitance between 100uF and 1000uF from power to ground to smooth out the power supply.
  • Add a 220 or 470 Ohm resistor between the Arduino digital output pin and the strip data input pin to reduce noise on that line.
  • Make your wires between the arduino, power supply and the strip as short as possible to minimize voltage loss.
  • If your strip gets damaged and doesn’t work, check if the first LED is broken. If so, cut it, resolder the header pins, and it should work again.

Code

To control the WS2812B LED strip, you’ll need to download the FastLED library.

Installing the FastLED library

  1. Click here to download the FastLED library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get FastLED-master folder
  3. Rename your folder from FastLED-master to FastLED
  4. Move the FastLED folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

After installing the needed library, upload the following code to your Arduino board (this is an example sketch provided in the library examples folder). Go to File > Examples > FastLED > ColorPalette or copy the code below.

#include <FastLED.h>

#define LED_PIN     5
#define NUM_LEDS    14
#define BRIGHTNESS  64
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100

// This example shows several ways to set up and use 'palettes' of colors
// with FastLED.
//
// These compact palettes provide an easy way to re-colorize your
// animation on the fly, quickly, easily, and with low overhead.
//
// USING palettes is MUCH simpler in practice than in theory, so first just
// run this sketch, and watch the pretty lights as you then read through
// the code.  Although this sketch has eight (or more) different color schemes,
// the entire sketch compiles down to about 6.5K on AVR.
//
// FastLED provides a few pre-configured color palettes, and makes it
// extremely easy to make up your own color schemes with palettes.
//
// Some notes on the more abstract 'theory and practice' of
// FastLED compact palettes are at the bottom of this file.



CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;


void setup() {
    delay( 3000 ); // power-up safety delay
    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    
    currentPalette = RainbowColors_p;
    currentBlending = LINEARBLEND;
}


void loop()
{
    ChangePalettePeriodically();
    
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1; /* motion speed */
    
    FillLEDsFromPaletteColors( startIndex);
    
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
    uint8_t brightness = 255;
    
    for( int i = 0; i < NUM_LEDS; i++) {
        leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
        colorIndex += 3;
    }
}


// There are several different palettes of colors demonstrated here.
//
// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
//
// Additionally, you can manually define your own color palettes, or you can write
// code that creates color palettes on the fly.  All are shown here.

void ChangePalettePeriodically()
{
    uint8_t secondHand = (millis() / 1000) % 60;
    static uint8_t lastSecond = 99;
    
    if( lastSecond != secondHand) {
        lastSecond = secondHand;
        if( secondHand ==  0)  { currentPalette = RainbowColors_p;         currentBlending = LINEARBLEND; }
        if( secondHand == 10)  { currentPalette = RainbowStripeColors_p;   currentBlending = NOBLEND;  }
        if( secondHand == 15)  { currentPalette = RainbowStripeColors_p;   currentBlending = LINEARBLEND; }
        if( secondHand == 20)  { SetupPurpleAndGreenPalette();             currentBlending = LINEARBLEND; }
        if( secondHand == 25)  { SetupTotallyRandomPalette();              currentBlending = LINEARBLEND; }
        if( secondHand == 30)  { SetupBlackAndWhiteStripedPalette();       currentBlending = NOBLEND; }
        if( secondHand == 35)  { SetupBlackAndWhiteStripedPalette();       currentBlending = LINEARBLEND; }
        if( secondHand == 40)  { currentPalette = CloudColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 45)  { currentPalette = PartyColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 50)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND;  }
        if( secondHand == 55)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
    }
}

// This function fills the palette with totally random colors.
void SetupTotallyRandomPalette()
{
    for( int i = 0; i < 16; i++) {
        currentPalette[i] = CHSV( random8(), 255, random8());
    }
}

// This function sets up a palette of black and white stripes,
// using code.  Since the palette is effectively an array of
// sixteen CRGB colors, the various fill_* functions can be used
// to set them up.
void SetupBlackAndWhiteStripedPalette()
{
    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
    
}

// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
    CRGB purple = CHSV( HUE_PURPLE, 255, 255);
    CRGB green  = CHSV( HUE_GREEN, 255, 255);
    CRGB black  = CRGB::Black;
    
    currentPalette = CRGBPalette16(
                                   green,  green,  black,  black,
                                   purple, purple, black,  black,
                                   green,  green,  black,  black,
                                   purple, purple, black,  black );
}


// This example shows how to set up a static color palette
// which is stored in PROGMEM (flash), which is almost always more
// plentiful than RAM.  A static PROGMEM palette like this
// takes up 64 bytes of flash.
const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
    CRGB::Red,
    CRGB::Gray, // 'white' is too bright compared to red and blue
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Red,
    CRGB::Gray,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Blue,
    CRGB::Black,
    CRGB::Black
};



// Additionl notes on FastLED compact palettes:
//
// Normally, in computer graphics, the palette (or "color lookup table")
// has 256 entries, each containing a specific 24-bit RGB color.  You can then
// index into the color palette using a simple 8-bit (one byte) value.
// A 256-entry color palette takes up 768 bytes of RAM, which on Arduino
// is quite possibly "too many" bytes.
//
// FastLED does offer traditional 256-element palettes, for setups that
// can afford the 768-byte cost in RAM.
//
// However, FastLED also offers a compact alternative.  FastLED offers
// palettes that store 16 distinct entries, but can be accessed AS IF
// they actually have 256 entries; this is accomplished by interpolating
// between the 16 explicit entries to create fifteen intermediate palette
// entries between each pair.
//
// So for example, if you set the first two explicit entries of a compact 
// palette to Green (0,255,0) and Blue (0,0,255), and then retrieved 
// the first sixteen entries from the virtual palette (of 256), you'd get
// Green, followed by a smooth gradient from green-to-blue, and then Blue.

View raw code

You have to change NUM_LEDS variable to the number of LEDs in your LED strip. In our example, the LED strip is 14 LEDs long.

#define NUM_LEDS 14

If you want to use another pin of the Arduino to control the LED strip, you need to change the LED_PIN variable:

#define LED_PIN 5

Demonstration

In the end, this is what you’ll have. Amazing effects like this one:

gif1

And this one:

gif2

And this one:

gif3

And so on (…)

Using an LED Strip Case

These LED strips usually come with a removable tape, so that you can stick them wherever you want. The problem is that they don’t stick very well, so chances are that you’ll find your strip in the floor the following day.

The solution: I found this strip case that diffuses the light well and you can screw it to a shelf, for example, if you want a permanent solution. You can find a similar strip case on Amazon.

foto1

Wrapping Up

This post is an introduction to the addressable RGB LED strip with the Arduino. We’ve just experimented with the library example. You should modify the example to only display the effects you want. We hope you’ve found this guide useful.

If like this post, you may also like:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

48 thoughts on “Guide for WS2812B Addressable RGB LED Strip with Arduino”

  1. Is there any way to set a timer in the code, say for every 10 minutes the leds flash? Also could that be done on an ESP with arduino IDE, instead of lua?

  2. Hi, I was wondering how bright these LEDs are, and if they would be visible (in maybe an amber/orange color) during daylight hours, if flashing? thank you.

  3. Awesome! This is the first sample code I’ve gotten for some crazy new project that has just *worked* right off the bat!! I’m so excited to start playing with my LED strip.

  4. Although a competent assembly language programmer with Z80, 8085 & Microchip PIC’s for some reason I’d always shied away from using an Arduino but upon deciding to try found the web full of so much banter I felt it confusing but your website proved just the ticket!! Clearly presented, smoothing the way for my 10 LED’s sequence (using PL9823’s!) Nice work!!

  5. Hi, Thanks for the description. I always end up with an issue. Compiles and updates just fine, but the LED strip always ending up the first 5-7 (depending on the program) fully lit in white, and the rest of the strip is off. I tried to write simple command only for specific LED position to turn on to a set colour, but always the first LED is lit with some other (usually green or white) colour and I don’t know why… Any idea? I’m using a WS2812B chip strip.

    • I haven’t encountered that issue before. This example was tested (recently) and it works with any strip that has the WS2812B chip.
      I would report your exact problem on the Library github issues pages or use another LED strip to see if it’s a problem with your specific strip.

      Regards,
      Rui

  6. Hi,
    I am trying to find the WS2812B LED strip that has GND, Din and 5V as shown in the example, but I can’t. Please, can you help?

  7. Dear Admin,
    This is a request :
    Can you show, how this strip works with Raspberry PI. Only code will be enough.

    Waiting for your reply..

  8. I am planning to purchase this item
    https://www.pololu.com/product/2551 (the high density, 72 led/0.5m)

    Do you know if the channel you linked is the proper size for that strip?
    https://www.amazon.com/LEDwholesalers-Aluminum-Mounting-Installations-Ultra-Thin/dp/B072HP5K3C/ref=as_li_ss_tl?ie=UTF8&linkCode=sl1&tag=makeradvisor-20&linkId=2d7b19711dec30293c3b4c2093a68e1c

    Also, how would i modify your example scripts to have just one light on at a time, for about 2-3 seconds? Any suggestions for how to do this or resources will be appreciated.

    Thanks so much.
    Anita

    • Hi Anita.
      LED strips usually have a standard width. So, that channel should do the job for most LED strips.
      However, the LED strip you’re referring has an extra sealant protecting the strip. So, I’m not sure if it will fit on that channel.

      To make your own patterns on the strip, I recommend taking a look at the examples provided in the FastLED library, and modify them to achieve what you want.
      Here’s a link to the examples:
      github.com/FastLED/FastLED/tree/master/examples
      I hope this helps.
      Regards,
      Sara 🙂

  9. Thanks for the tutorial. It’s my first Arduino project so I appreciate you putting this up.

    I am having a weird problem. I’ve cut a strip of SK6812 with 8 LEDs and I set NUM_LEDS to 8. The first 6 LEDs work as expected but the last 2 stay dark. If I change NUM_LEDS to 10 they all light up and work correctly.

    I suppose I could always set it +2 but I’d rather understand the underlying issue. Have you seen anything like this?

    • Hi John.
      Unfortunately, I have no idea why that happens with your strip.
      We’ve tested the code with a WS2812B LED strip, and it worked fine.
      I don’t know if it has something to do with the SK6812 LED strip (we don’t have one of those to test).
      Regards,
      Sara 🙂

  10. Hello – great tutorial & sample code. Unfortunately, on my Windows 10 box, trying to compile for Intel Edison board, upon loading I get compile error:

    \Documents\Arduino\libraries\FastLED/platforms/avr/led_sysdefs_avr.h:12:20: fatal error: avr/io.h: No such file or directory

    I searched quite a bit and found an io.h file in system directory
    ….Documents\ArduinoData\packages\Intel\tools\core2-32-poky-linux\1.6.2+1.0\core2-32-poky-linux\usr\include\sys
    and I COPIED io.h from the buried location into the path where led_sysdefs_avr.h is looking for it (I think..) but compilation continues to fail, complaining that io.h isn’t found.

    Any hints please?? Thanks, D.

    • Hi Dave.
      I’m not sure, but I think the problem is that this Arduino code is not compatible with the Intel Edison board :/
      Regards,
      Sara 🙂

  11. Hello i have a problem with the code or the version of fast Led
    Problem: pragma message “FastLED version 3.002.000”
    what means that ? im totally inexperienced. Need help

    • Hi Markus.
      I’ve never get that error. So, I’m not sure what that means.
      Take a look at this: forum.arduino.cc/index.php?topic=566711.0 and see if that solves your problem.
      Regards,
      Sara

    • Hi Edward.
      The LEDs are addressable, but with a digital pin (not serial).
      You can find the datasheet if you search for its name online (“WS18B20 datasheet pdf”) or get it from your parts supplier.
      Regards,
      Sara

  12. Thank you for the interesting article. I plan to build a lighting fixture which will be
    a) long (appx 10ft)
    b) not exactly close to a power outlet because
    c) it will be hanging halfway up in a corridor that is pretty high.
    So Ideally I’d like to connect the light fixture with those modern decorative trans-white electrical wiring harnesses. This will probably be close to 2 meters (6ft) long.
    Is there anything I should keep in mind in terms of power supply (i.e. do I have to compensate for that long electrical connection)?

    • Hi Paul.
      It will really depend on your setup, and how many LEDs your strip has.
      You need to test it yourself.
      Sorry that I can’t help you more.
      Regards,
      Sara

  13. Great tutorial, simple and concise. Just one question. I have a one meter WS2812B that is powered directly by the Arduino Uno with an added capacitor. However, when I put in a 330Ω resistor, as described, I get no lights at all. Remove the resistor and everything works great. Does it really need the resistor since my understanding is the strip already has resistors?
    Thanks

    • Hi John.
      They may take some time to update (a few milliseconds) depending on the length of your strip.
      The first LEDs receive the signal first, so they will light up before the LEDs on the other end of the strip.
      Regards,
      Sara

  14. Hi,

    I am using the same LEDs for some work.
    Components I am using: NodeMCU, Jumper Wires, 5V 5A Adapter since I am using 150 LEDs.
    I am having an issue with the LEDs that after some time the LED strip stops working. When I checked them through multimeter, I found that the GND pin and the 5V pin is short-circuited. I am not able to understand how this is possible.

    To confirm this, I checked a new LED Strip with the multimeter and it was not getting short-circuited.

    Can someone please tell me the reason for this? Right now, 5*5metres of LEDs got wasted by this reason.

    • Hi Kevin.
      Probably, the USB is not providing enough power to your strip.
      How many LEDs are you trying to light up?
      Regards,
      Sara

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.