Programmable Christmas Lights Using Arduino and Neopixels

satb100I have a little Christmas tree that I put up in my office every year that I call my “Charlie Brown tree”. It’s a scrawny looking little artificial tree with a little white Christmas balls on it and a strand of cheap flights. This year I decided to fancy it up a little bit by adding a 3 meter strand of Adafruit neopixels containing 90 pixels. I started out with the standard strand test sketch that is available from Adafruit and then modified it to add my own special patterns. I showed it on a recent Adafruit Saturday night Show-and-Tell Google+ video chat. There were a number of other Christmas displays shown that night but people seem to especially like my candy stripe pattern.

One viewer liked it so much he wrote me and asked me for the candy stripe code. He then incorporated it into his outdoor display and showed it in a subsequent Show-and-Tell a few weeks later. I had always intended to write a blog post about it and to include the code but I got so busy over the holidays that I didn’t have time to clean up the code and make it suitable for public sharing. The holidays are over and I’m finally getting around to sharing the code.

Here is a YouTube video showing a slightly earlier version of the pattern.

Here is the Adafruit Show-and-Tell on Google+ where I showed off the tree and my blinking Christmas card.

Here is the Show-and-Tell of the other guy named Kenneth who borrowed my candy stripe code. His display used a full 10 meters of pixels. Unfortunately there were bad audio problems that evening but I will put the video here anyway. His segment starts at about six minutes into the video.

Here are some links to the products used in this project. All were purchased from Adafruit.com

Now finally here is the code edited for public consumption with comments.

#include <Adafruit_NeoPixel.h>

#define Count 12
#define Pin 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(Count,Pin,NEO_GRB + NEO_KHZ800);

#define Brightness 10 //Set brightness to 1/10th
#define Full (255/Brightness)
//Create scrolling red and white candy cane stripes.
//Try adjusting the width in pixels for various results.
//Value "sets" should evenly divide into strand length
void CandyCane  (int sets,int width,int wait) {
  int L;
  for(int j=0;j<(sets*width);j++) {
    for(int i=0;i< strip.numPixels();i++) {
      L=strip.numPixels()-i-1;
      if ( ((i+j) % (width*2) )<width)
        strip.setPixelColor(L,Full,0,0);
      else
        strip.setPixelColor(L,Full,Full, Full);
    };
    strip.show();
    delay(wait);
  };
};

//Create sets of random white or gray pixels
void RandomWhite (int sets, int wait) {
  int V,i,j;
  for (i=0;i<sets;i++) {
    for(j=0;j<strip.numPixels();j++) {
      V=random(Full);
      strip.setPixelColor(j,V,V,V);
    }
    strip.show();
    delay(wait);
  }
};
//Create sets of random colors
void RandomColor (int sets, int wait) {
  int i,j;
  for (i=0;i<sets;i++) {
    for(j=0;j<strip.numPixels();j++) {
      strip.setPixelColor(j,random(255)/Brightness,random(255)/Brightness,random(255)/Brightness);
    }
    strip.show();
    delay(wait);
  }
};
void RainbowStripe (int sets,int width,int wait) {
  int L;
  for(int j=0;j<(sets*width*6);j++) {
    for(int i=0;i< strip.numPixels();i++) {
      L=strip.numPixels()-i-1;
      switch ( ( (i+j)/width) % 6 ) {
        case 0: strip.setPixelColor(L,Full,0,0);break;//Red
        case 1: strip.setPixelColor(L,Full,Full,0);break;//Yellow
        case 2: strip.setPixelColor(L,0,Full,0);break;//Green
        case 3: strip.setPixelColor(L,0,Full,Full);break;//Cyan
        case 4: strip.setPixelColor(L,0,0,Full);break;//Blue
        case 5: strip.setPixelColor(L,Full,0,Full);break;//Magenta
//        default: strip.setPixelColor(L,0,0,0);//Use for debugging only
      }
    };
    strip.show();
    delay(wait);
  };
};
//These routines were modified from Adafruit strand test sketch
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

void rainbowCycle(uint8_t sets, uint8_t wait) {
  uint16_t i, j;
  for(j=0; j<256*sets; j++) { //cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(strip.numPixels()-i-1, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color((WheelPos * 3)/Brightness, (255 - WheelPos * 3)/Brightness, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color((255 - WheelPos * 3)/Brightness, 0, (WheelPos * 3)/Brightness);
  } else {
   WheelPos -= 170;
   return strip.Color(0,(WheelPos * 3)/Brightness, (255 - WheelPos * 3)/Brightness);
  }
}

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  randomSeed(1234);//Set up random number generator
}

void loop() {
  CandyCane(30,8,50);//30 sets, 8 pixels wide, 50us delay
  RainbowStripe(5,4,75);//5 cycles, 4 pixels wide, 50 delay
  RandomWhite(50,200);//50 sets of random grayscale
  RandomColor(50,200);//50 sets of random colors
  colorWipe(strip.Color(Full, 0, 0), 50); // Red
  colorWipe(strip.Color(Full, Full, 0), 50); // Yellow
  colorWipe(strip.Color(0, Full, 0), 50); // Green
  colorWipe(strip.Color(0, Full, Full), 50); // Cyan
  colorWipe(strip.Color(0, 0, Full), 50); // Blue
  colorWipe(strip.Color(Full, 0, Full), 50); // Magenta
  rainbowCycle(10,2);//10 rainbow cycles
  colorWipe(0,5);//Black
}

Hope you find this code useful. Have a very Merry Christmas and a blessed new year.

8 thoughts on “Programmable Christmas Lights Using Arduino and Neopixels

  1. Hi thanks for the code, I loaded it to two pro mini arduinos each with a 24 led neo pixel ring attached and fitted them inside two christmas stars, looks fantastic. Thanks you

  2. Excellent, thanks for sharing. I am just learning Arduino and your post has helped me loads. I have modified the code and got just candy cane and random colours cycling over 2 minutes. I now am on a mission to incorporate a light sensor so that it is read and directly effects the brightness so that the lights are bright during the day and dimmer at night.

  3. Hi,
    thanks for sharing your project! I’d like to ask, how can I run the CandyCane program at reverse direction? I’ve changed this command: for(int i=0;i0; i–) but doesn’t work. Thanks for your help!
    Merry Christmas!

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.