Arduino & WS2812

Arduino & WS2812

The WS2812 is an RGB led with a controller built in. More importantly, the built in controller allows for concatenation of the leds and you supply the colors on a bus and each led ‘takes’ one color and passes the rest on. You can buy these as a long string or in various shapes. In this example, I have a 16 led circle.

Connecting the circle is done with four wires, GND to GND, VCC to 5V (please note it is 5 Volts and not 3.3 Volts). There is also a DI and a DO, Data In and Data Out. You connect the DI pin to a pin on your Arduino. In my example, it is pin 6.

The library you need can be found here. Like most Arduino IDE libraries, you install it by going to the menus Sketch, Include Library, Add .ZIP Library. Don’t forget to close all instances of Arduino IDE and restart.

github-mark-32px Available on GitHub with more comment in the code. Direct download.

Let’s first look at the code:

//
// The library from Adafruit which enables the use of the WS2812
// or NeoPixel
//
#include <Adafruit_NeoPixel.h>

//
// The pin the circle of WS2812 leds is connected to
//
#define CIRCLEPIN 6
//
// The number of leds in our circle
//
#define PIXELCOUNT 16

//
// Initialize the Adafruit library
//
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXELCOUNT,CIRCLEPIN,
  NEO_GRB+NEO_KHZ800);

//
// The current position in degrees
//
int degree = 0;

void setup() {
  Serial.begin(115200);
  //
  // Start the led string and turn them all off
  //
  pixels.begin();
  for(int i=0;i<PIXELCOUNT;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0));
  }
  pixels.show();
}

void loop() {
  Serial.println(degree);
  //
  // Turn all leds to black
  //
  for(int i=0;i<PIXELCOUNT;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0));
  }
  //
  // Convert degrees to the pixel position
  //
  int thisPixel = (degree*PIXELCOUNT)/360;
  //
  // Set the pixels with a trailing tail
  //
  pixels.setPixelColor((thisPixel+3)%16,pixels.Color(255,0,0));
  pixels.setPixelColor((thisPixel+2)%16,pixels.Color(100,0,0));
  pixels.setPixelColor((thisPixel+1)%16,pixels.Color(40,0,0));
  pixels.setPixelColor((thisPixel)%16,pixels.Color(15,0,0));
  //
  // Don't forget to call the pixels.show();
  //
  pixels.show();
  delay(50);
  degree += 10;
  if (degree>=360) {
    degree -= 360;
  }
}

In the setup function, we call pixels.begin() to start initialize. Every time we call pixels.show the data is send to the LEDs. With setPixelColor you set the color for each pixel.

So what this code does is make a red light go around in circles followed by a small fading trail.

With regards to the code, I know it would have made more sense to just use the pixel counter instead of degrees, especially since 360 degrees into 16 LEDs means an increase of 22.5.

Also, you do not need to set every color back to black because it remembers the last color. Taking all this into account, the smaller version of the code will be:

//
// The library from Adafruit which enables the use of the WS2812
// or NeoPixel
//
#include <Adafruit_NeoPixel.h>

//
// The pin the circle of WS2812 leds is connected to
//
#define CIRCLEPIN 6
//
// The number of leds in our circle
//
#define PIXELCOUNT 16

//
// Initialize the Adafruit library
//
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXELCOUNT,CIRCLEPIN,
  NEO_GRB+NEO_KHZ800);

//
// The current pixel
//
byte thisPixel = 0;

void setup() {
  //
  // Start the led string and turn them all off
  //
  pixels.begin();
  for(int i=0;i<PIXELCOUNT;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0));
  }
  pixels.show();
}

void loop() {
  //
  // Set the pixels with a trailing tail
  // Since we paint the last pixel black, we do not need to initialize
  // all pixels to black
  //
  pixels.setPixelColor((thisPixel+4)%16,pixels.Color(255,0,0));
  pixels.setPixelColor((thisPixel+3)%16,pixels.Color(100,0,0));
  pixels.setPixelColor((thisPixel+2)%16,pixels.Color(40,0,0));
  pixels.setPixelColor((thisPixel+1)%16,pixels.Color(15,0,0));
  pixels.setPixelColor((thisPixel)%16,pixels.Color(0,0,0));
  //
  // Don't forget to call the pixels.show();
  //
  pixels.show();
  delay(30);
  thisPixel++;
  if (thisPixel>16) {
    thisPixel = 0;
  }
}

One thought on “Arduino & WS2812

Leave a comment