How to Control WS2812 RGB LED (NeoPixel) w/ Arduino [Tutorial]

Table of Contents

Overview

NeoPixel LEDs are widely used these days in electronic projects, due to their attractive visual effects. These LEDs are available in various sizes and shapes and in the strip form. In this tutorial, you’ll learn about NeoPixel LEDs and how to control them with Arduino. 

What You Will Learn

What Is NeoPixel?

After 1962, when the first LED was made and tested, this valuable piece became an inseparable part of our lives. In most electronic projects, you can find at least one single LED. Using the LEDs in different colors was so attractive that it caused the production of multi–color LEDs or RGB LEDs.  The RGB LED creates all the colors based on the three colors of red, green, and blue. for example, a red and blue combination produces a magenta color. In this model, each color has a value between 0 and 255 for each red, green and blue colors. For instance, these values ​​are 255 0 255 (maximum red, maximum blue, and minimum green value) for Magenta. This numeric value is expressed by the Hex code (2550255 = # FF00FF). RGB LEDs make a variety of colors based on this model. 
To control each RGB LED, you need three digital pins of a microcontroller (or the development boards like Arduino). For example, if you want to control an RGB LED string containing 60 LEDs, in order to control the color of each LED separately, you need 180 digital pins! So you have to forget controlling each LED individually or use LEDs that are addressable.  Addressable LEDs are a new generation of LEDs including a controller IC, in addition to RGB LEDs. This controller IC, usually WS2812, allows you to access multiple LEDs with a single digital pin by assigning an address to each LED and providing one wire communication. But unlike simple LEDs, these types of LEDs do not turn on only by applying voltage, they also require a microcontroller. NeoPixel is the Adafruit brand for addressable LEDs. 

Why NeoPixel?

The ability to control each LED in an LED strip will create great visual effects in your projects. But it should be noted that in the very fast processes like POVs, the use of NeoPixels is not recommended. The other important advantage of the NeoPixels is their lower price compared to other addressable LEDs. NeoPixels are also available in the ring, strip, square and circular models and you can select the suitable model according to your project.  Neopoxes are also chainable, so you can control multiple NeoPixels with only one command line and one power line. 
Note
Increasing the number of NeoPixel LEDs will require more RAM, more power and more processing time, so choose the most optimal NeoPixel according to your microcontroller type.

Required Materials

Hardware Components

WS2812 RGB LED Ring Module × 1
Arduino Uno R3 × 1

Software Apps

Arduino IDE

NeoPixel and Arduino interfacing

Pinout

Circuit

Note
The resistor must be used to prevent the NeoPixel from damage and to transmit data correctly.
Note
If you use a strip LED that contains a high number of LEDs, we recommend you to put a large capacitor (eg 1000uf)  in parallel with + and –  of the supply voltage. 
Note
The best distance to connect the first NeoPixel module is about 1 to 2 meters from the controller board. 

Ex.1: Setting Up the NeoPixel with Arduino

In this example, you are going to turn on the NeoPixels and control the color and intensity of each LED separately using the Arduino UNO. Use the NeoPixel Adafruit library to set up the NeoPixel with Arduino.

code

/*
  NeoPixel LEDs

  modified on 7 May 2019
  by Saeed Hosseini @ Electropeak
**This code is based on Adafruit NeoPixel library Example**
  
Home
*/ #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif #define PIN 6 #define NUMPIXELS 7 Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels void setup() { pixels.begin(); } void loop() { pixels.clear(); pixels.setBrightness(10); pixels.setPixelColor(0, pixels.Color(255, 255, 255)); pixels.setPixelColor(1, pixels.Color(255, 0, 0)); pixels.setPixelColor(2, pixels.Color(0, 255, 0)); pixels.setPixelColor(3, pixels.Color(0, 0, 255)); pixels.setPixelColor(4, pixels.Color(255, 0, 255)); pixels.setPixelColor(5, pixels.Color(255, 255, 0)); pixels.setPixelColor(6, pixels.Color(0, 255, 255)); pixels.show(); }

Code Explanation

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
The above function determine the number of LEDs and Arduino pins.
pixels.begin();
This function does the initializations.
pixel.setBrightness(b);
The above function set the light intensity. (The minimum number is 1 and maximum number is 255.)
pixels.setPixelColor(Wich LED,Wich color(Red,Green,Blue));
Defines the LEDs color with the RGB system, after specifying the LED number (from 0 to NUMPIXELS-1). 
pixels.show();
Displays the applied values. 

Ex.2: NeoPixel Blinking Mode with Arduino

In this example, we set up NeoPixels in blinking mode. To make the blinker, all the LEDs must be turned on and off at the same time, and they can have different colors when they are turned on. 
/*

  NeoPixel LEDs

  modified on 7 May 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif #define PIN 6 #define NUMPIXELS 7 Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); void NeoBlink(int num, int wait) { for (int i = 0; i < num; i++) { pixels.setPixelColor(i, 35, 35, 35); } pixels.show(); delay(wait); for (int j = 0; j < num; j++) { pixels.setPixelColor(j, 0, 255, 0); } pixels.show(); delay(wait); } void setup() { pixels.begin(); pixels.setBrightness(50); } void loop() { NeoBlink(7, 500); }

Ex.3: NeoPixel Fading Mode with Arduino

Fading is one of the fascinating effects of NeoPixels. The slower the fade, the better the effect will be. 
/*

  NeoPixel LEDs

  modified on 7 May 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif #define PIN 6 #define NUMPIXELS 7 Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels void NeoFade(int FadeSpeed) { int fspeed; for (int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, 165, 242, 243); } for (int j = 255; j > 0; j=j-2) { pixels.setBrightness(j); pixels.show(); delay(FadeSpeed); } } void setup() { pixels.begin(); } void loop() { NeoFade(100); }

Ex.4: NeoPixel Random Mode with Arduino

In this example, we use the random(num1, num2) function to generate and display a random number between num1 and num2 to choose a color and an LED. 
/*

  NeoPixel LEDs
  modified on 7 May 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif #define PIN 6 #define NUMPIXELS 7 Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels void setup() { pixels.begin(); } void loop() { pixels.clear(); pixels.setPixelColor(random(0, 7), random(0, 255), random(0, 255), random(0, 255)); pixels.show(); delay(500); }

Ex.5: Neopixel rainbow mode with Arduino

One of the most interesting tools on the web, to create effects on NeoPixels is the NeoPixel Effects Generator, which lets you specify the number of LEDs and Arduino pins, and after creating the effects and required settings, you can click on the generate Arduino code and copy the generated code to IDE. To do this, do the following steps: 

  1. Click on Add Led Strip after entering the website. 
      2. Click on the added NeoPixel Strip and specify the number of LEDs and Arduino pins.
      3. Click on the Add Effect in the loop part and choose an effect. 
      4. Apply your preferences in the Animation and Color sections.
      5. Click on generate Arduino code and copy the generated code to Arduino IDE.  
/*
This code is generated by:
https://adrianotiger.github.io/NeoPixel-Effect-Generator/

*/
#include <Adafruit_NeoPixel.h>

class Strip
{
public:
  uint8_t   effect;
  uint8_t   effects;
  uint16_t  effStep;
  unsigned long effStart;
  Adafruit_NeoPixel strip;
  Strip(uint16_t leds, uint8_t pin, uint8_t toteffects) : strip(leds, pin, NEO_GRB + NEO_KHZ800) {
    effect = -1;
    effects = toteffects;
    Reset();
  }
  void Reset(){
    effStep = 0;
    effect = (effect + 1) % effects;
    effStart = millis();
  }
};

struct Loop
{
  uint8_t currentChild;
  uint8_t childs;
  bool timeBased;
  uint16_t cycles;
  uint16_t currentTime;
  Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};

Strip strip_0(7, 6, 7 );
struct Loop strip0loop0(1, false, 1);

//[GLOBAL_VARIABLES]

void setup() {

  //Your setup here:

  strip_0.strip.begin();
}

void loop() {

  //Your code here:

  strips_loop();
}

void strips_loop() {
  if(strip0_loop0() & 0x01)
    strip_0.strip.show();
}

uint8_t strip0_loop0() {
  uint8_t ret = 0x00;
  switch(strip0loop0.currentChild) {
    case 0: 
           ret = strip0_loop0_eff0();break;
  }
  if(ret & 0x02) {
    ret &= 0xfd;
    if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
      strip0loop0.currentChild = 0;
      if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
    }
    else {
      strip0loop0.currentChild++;
    }
  };
  return ret;
}

uint8_t strip0_loop0_eff0() {
    // Strip ID: 0 - Effect: Rainbow - LEDS: 7
    // Steps: 8 - Delay: 87
    // Colors: 7 (255.0.0, 0.255.0, 0.0.255, 255.157.0, 255.0.255, 0.255.255, 255.255.255, )
    // Options: toLeft=true, 
  if(millis() - strip_0.effStart < 87 * (strip_0.effStep)) return 0x00;
  float factor1, factor2;
  uint16_t ind;
  for(uint16_t j=0;j<7;j++) { ind = strip_0.effStep + j * 1.1428571428571428; switch((int)((ind % 8) / 1.1428571428571428)) { case 0: factor1 = 1.0 - ((float)(ind % 8 - 0 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 0) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2); break; case 1: factor1 = 1.0 - ((float)(ind % 8 - 1 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 1.1428571428571428) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 2: factor1 = 1.0 - ((float)(ind % 8 - 2 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 2.2857142857142856) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 157 * factor2, 255 * factor1 + 0 * factor2); break; case 3: factor1 = 1.0 - ((float)(ind % 8 - 3 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 3.4285714285714284) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 157 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 4: factor1 = 1.0 - ((float)(ind % 8 - 4 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 4.571428571428571) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2); break; case 5: factor1 = 1.0 - ((float)(ind % 8 - 5 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 5.7142857142857135) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2); break; case 6: factor1 = 1.0 - ((float)(ind % 8 - 6 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 6.857142857142857) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 255 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2); break; } } if(strip_0.effStep >= 8) {strip_0.Reset(); return 0x03; }
  else strip_0.effStep++;
  return 0x01;
}

What’s Next?

  • Test the other effects on your NeoPixel.
  • Try to control your NeoPixel wirelessly. (WiFi, Bluetooth, …) 

Similar Tutorials

Liked What you see?

Get updates and learn from the best

More To Explore

Leave a Reply

Your email address will not be published. Required fields are marked *