Project tutorial
NeoPixel Christmas (Color) Animation

NeoPixel Christmas (Color) Animation © LGPL

A simple project with an Arduino and NeoPixels, animating the LEDs in Christmas colors.

  • 5,796 views
  • 3 comments
  • 10 respects

Components and supplies

Apps and online services

About this project

A (very) simple Christmas (color) animation using an Arduino Nano and a NeoPixel ring with 60 leds and a few color schemes. The setup is easy: connect the power input and ground of your NeoPixels to the 5V output and ground of the Arduino and connect the DIN to pin 3. Note: you might need an external power supply depending on the number of leds (and the brightness).

Make sure you have the Adafruit NeoPixel libary installed and open the np-xmas-share-20181225.ino file.

Change the following line to the number of pixels of your setup:

#define NUMOFPIXELS     60

and, additionally, set the colorwheel value from 0 to 3 to chose a color scheme.

#define COLORWHEEL 3

Bonus

I added a bonus sketch: a simple but useful program to quickly determine the number of leds on a NeoPixel strip, ring or matrix by providing visual (color) information (instead of counting each led).

Note: the camera had trouble capturing the bright NeoPixels, the image quality is pretty poor. The colors look and the overall experience is much better in reality.

Update 20191209

I added support for 2 rings and some other enhancements.



Code

Neopixel Christmas animation - version 20191208Arduino
/*
**********************************************************************
* Neopixel Christmas animation by ericBcreator
* Designed to be used with an Arduino UNO, Nano or compatible device.
**********************************************************************
* Last update 20191208 by ericBcreator
*   - added support for 2 rings
*   - added offset support for setting the pixel 0
*   - added circle in and -out animations
*   - other enhancements
*
* This code is free for personal use, not for commercial purposes.
* Please leave this header intact.
*
* contact: ericBcreator@gmail.com
**********************************************************************
*/ 

//
// includes
//

#include <Adafruit_NeoPixel.h>

//
// debug settings
//

//#define DEBUG                                 // print debug messages
//#define DEBUGVERBOSE                          // print calculated delay for fly in and out
//#define DEBUGCHECKPIXEL0                      // visual check which pixel is at 0 (after MAINPIXELOFFSET), sets it off after the startup fade in

#ifdef DEBUG
  #define DEBUGPRINT(x)   Serial.print(x)
  #define DEBUGPRINTLN(x) Serial.println(x)
#else
  #define DEBUGPRINT(x)
  #define DEBUGPRINTLN(x)
#endif

//
// definitions
//

#define SIGNALPIN           3                   // @EB-setup the digital output pin

// definition for 2 24 LED rings
//#define NUMOFPIXELS        48                   // @EB-setup the number of pixels
//#define TWOSTRIPS                               // @EB-setup define when using 2 LED strips
//#define MAINPIXELOFFSET     0                   // @EB-setup offset for pixel 0
//#define STRIP2OFFSET        1                   // @EB-setup offset for the 2nd strip (only works with 2 strips)

// definition for 1 60 LED ring
#define NUMOFPIXELS        60                   // @EB-setup the number of pixels
#define MAINPIXELOFFSET     0                   // @EB-setup offset for pixel 0

//
// settings
//

const int colorWheel = 0;                       // 0 red-green, 1 red-green-yellow, 2 red-green-white, 3 red-green-yellow-red-green-white
                                                // 4 red-green-blue 5 red-green-blue-red-green-yellow
const int maxColorWheel = 5;
const bool loopColorWheel = true;               // if true, loop through the color wheels
const int multiplier = 3;                       // multiplier for the number of loops of the animations

int startFadeDelay = 50;
int maxBrightness = 30;
int ledBrightness = maxBrightness;

int fadeDelay = 750;
int fadeHoldDelay = 5000;

int flyDelay = 5;
int flyStep = 1;
float flyDelayFactor = .8;

int circleDelay = 30;

int slowLoopDelay = 500;
int slowLoopCount = 25 * multiplier;

int fastLoopDelay = 60;
int fastLoopCount = 100 * multiplier;

int walkDelay = 500;
int walkCount = 5 * multiplier;

int flashDelay = 200;
int flashCount = 10 * multiplier / 2;

//
// setup variables
//

int pixelOffset = 0;
int colorRange = 0;
int currentColorWheel = colorWheel;
bool mainLoopBit = false;

#ifdef TWOSTRIPS
  int middlePixel = NUMOFPIXELS / 2;
#endif

uint32_t stripColor[NUMOFPIXELS + 6];

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMOFPIXELS, SIGNALPIN, NEO_GRB + NEO_KHZ800); // grb

//
// setup
//

void setup() {
  #ifdef DEBUGPRINT
    Serial.begin(115200);
    DEBUGPRINTLN("Setup");
  #endif
  pixels.begin();
  fadeIn();

  #ifdef DEBUGCHECKPIXEL0
    setOneLed(0, 0);
    #ifdef TWOSTRIPS
      setOneLed(middlePixel ,0);
    #endif
    pixels.show();
    delay(7500);
  #endif
}

//
// main loop
//

void loop() {  
  DEBUGPRINTLN("Main loop");
  slowLoop();
  fastLoop();
  walk();
  flash();
  
  #ifdef TWOSTRIPS
    circleOut();
    circleIn();
    circleOut();
  #else
    if (mainLoopBit)
      circleOut();
    else
      flyOut();
  #endif

  if (loopColorWheel) {
    pixelOffset = 0;
    currentColorWheel++;
    if (currentColorWheel > maxColorWheel)
      currentColorWheel = 0;
    DEBUGPRINTLN("  Colorwheel set to " + String(currentColorWheel));
    setStripColors();
  }

  #ifdef TWOSTRIPS
    circleIn();
  #else
    if (mainLoopBit)
      circleIn();
    else
      flyIn();
  #endif

  mainLoopBit = !mainLoopBit;
}

//
// functions
//

void fadeIn() {
  DEBUGPRINTLN("Fade in");
  for (int i = 0; i <= maxBrightness; i += 2) {  
    ledBrightness = i;
    setStripColors();
    setPixelColors();
    delay(startFadeDelay);
  }
}

void slowLoop() {
  DEBUGPRINTLN("  Anim: Slow loop");
  for (int i = 0; i < slowLoopCount; i++) {
    setPixelColors();
    pixelOffset++;
    pixelOffset = pixelOffset % (colorRange + 1);
    delay(slowLoopDelay);
  }
}

void fastLoop() {
  DEBUGPRINTLN("  Anim: Fast loop");
  for (int i = 0; i < fastLoopCount; i++) {
    setPixelColors();
    pixelOffset++;
    pixelOffset = pixelOffset % (colorRange + 1);
    delay(fastLoopDelay);
  }
}

void flyOut() {
  int i, j, delayTime;
  DEBUGPRINTLN("  Anim: Fly out");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    for (j = i; j > 0; j = j - flyStep) {
      setOneLed(j, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
      pixels.show();
      
      delayTime = flyDelay - ((i * flyDelay * flyDelayFactor) / NUMOFPIXELS);
      #ifdef DEBUGVERBOSE
        DEBUGPRINT(delayTime);
        DEBUGPRINT("  ");
      #endif
      delay(delayTime);
      setOneLed(j, 0);
    }
  }
  
  #ifdef DEBUGVERBOSE
    DEBUGPRINTLN();
  #endif
  pixels.show();
}

void flyIn() {
  int i, j, delayTime;
  DEBUGPRINTLN("  Anim: Fly in");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    for (j = NUMOFPIXELS - i % flyStep; j > i; j = j - flyStep) {
      if (j >= 0) {
        setOneLed((j - 1), stripColor[(i + pixelOffset) % NUMOFPIXELS]);        
        pixels.show();
        
        delayTime = flyDelay - (((NUMOFPIXELS - i) * flyDelay * flyDelayFactor) / NUMOFPIXELS);
        #ifdef DEBUGVERBOSE
          DEBUGPRINT(delayTime);
          DEBUGPRINT("  ");
        #endif
        delay(delayTime);
        setOneLed((j - 1), 0);
      }
    }
    setOneLed((i - 1), stripColor[(i + pixelOffset) % NUMOFPIXELS]);
  }

  #ifdef DEBUGVERBOSE
    DEBUGPRINTLN();
  #endif
  pixels.show();
}

void circleOut() {
  int i;
  DEBUGPRINTLN("  Anim: Circle out");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    setOneLed(i, 0);
    pixels.show();
    delay(circleDelay);
  }
}

void circleIn() {
  int i;
  DEBUGPRINTLN("  Anim: Circle in");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    setOneLed(i, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
    pixels.show();
    delay(circleDelay);
  }
}

void flash() {
  DEBUGPRINTLN("  Anim: Flash");
  
  for (int i = 0; i < flashCount; i++) {
    ledBrightness = maxBrightness * .2;
    setStripColors();
    setPixelColors();
    delay(flashDelay);

    ledBrightness = maxBrightness * .7;
    setStripColors();
    setPixelColors();
    delay(flashDelay);
  }
  
  ledBrightness = maxBrightness;
  setStripColors();
}

void walk() { 
  DEBUGPRINTLN("  Anim: Walk");
  
  int i, j, k, pixelCol;
  uint32_t pixelColor;

  for (k = 0; k < walkCount; k++) {
    for (j = colorRange; j >= 0; j--) {
      for (i = 0; i < NUMOFPIXELS; i++) {
        if ((i % (colorRange + 1)) == j) {
          pixelCol = i + pixelOffset;
          if (pixelCol >= NUMOFPIXELS)
            pixelCol -= colorRange + 1; 
          pixelColor = stripColor[pixelCol];
        } else
          pixelColor = 0;
        setOneLed(i, pixelColor);
      }
      pixels.show();
      delay(walkDelay);
    }
  }
}

//
// function for settings colors
//

void setStripColors() {  
  switch (currentColorWheel) {
    case 0: setStripColorsRG();     break;
    case 1: setStripColorsRGY();    break;
    case 2: setStripColorsRGW();    break;
    case 3: setStripColorsRGYRGW(); break;
    case 4: setStripColorsRGB();    break;
    case 5: setStripColorsRGBRGY(); break;
  }
}

void setStripColorsRG() {
  int r, g, b;
  colorRange = 1;
  
  r = ledBrightness;
  g = ledBrightness;
  b = 0;

  for (int i = 0; i < NUMOFPIXELS; i += 2) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
  }
}

void setStripColorsRGY() {
  int r, g, gy, b;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;  
  gy = (ledBrightness * 215 / 255);
  b = 0;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, gy, 0);
  }
}

void setStripColorsRGW() {
  int r, g, bw;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;
  bw = ledBrightness / 3;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, g, bw);
  }
}

void setStripColorsRGYRGW() {
  int r, g, gy, bw;
  colorRange = 5;
  
  r = ledBrightness;
  g = ledBrightness;  
  gy = (ledBrightness * 215 / 255);
  bw = ledBrightness / 3;

  for (int i = 0; i < NUMOFPIXELS ; i += 6) {
    stripColor[i] =  pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, gy, 0);
    stripColor[i+3] = pixels.Color(r, 0, 0);    
    stripColor[i+4] = pixels.Color(0, g, 0);
    stripColor[i+5] = pixels.Color(r, g, bw);
  }
}

void setStripColorsRGB() {
  int r, g, b;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;  
  b = ledBrightness;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(0, 0, b);
  }
}

void setStripColorsRGBRGY() {
  int r, g, gy, b;
  colorRange = 5;
  
  r = ledBrightness;
  g = ledBrightness;  
  gy = (ledBrightness * 215 / 255);
  b = ledBrightness;

  for (int i = 0; i < NUMOFPIXELS ; i += 6) {
    stripColor[i] =  pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, gy, 0);
    stripColor[i+3] = pixels.Color(r, 0, 0);    
    stripColor[i+4] = pixels.Color(0, g, 0);
    stripColor[i+5] = pixels.Color(0, 0, b);
  }
}

void setPixelColors() {
  int pixelCol;
  
  for (int i = 0; i < NUMOFPIXELS; i++) {
    pixelCol = i + pixelOffset;
    if (pixelCol >= NUMOFPIXELS)
      pixelCol -= colorRange + 1;
      
    setOneLed(i, stripColor[pixelCol]);
  }
  pixels.show();
}

void setOneLed(int pixel, uint32_t color) {
  int targetPixel;

  #ifdef TWOSTRIPS
    if (pixel < middlePixel) {
      targetPixel = (pixel + MAINPIXELOFFSET) % middlePixel;
      if (targetPixel < 0)
        targetPixel += middlePixel;

      pixels.setPixelColor(targetPixel, color);  
    } else {
      targetPixel = (NUMOFPIXELS - pixel - MAINPIXELOFFSET - STRIP2OFFSET) % middlePixel;
      if (targetPixel < 0)
        targetPixel += middlePixel;
        
      pixels.setPixelColor((middlePixel + targetPixel), color);  
    }
  #else
    targetPixel = (pixel + MAINPIXELOFFSET) % NUMOFPIXELS;
    if (targetPixel < 0)
      targetPixel += NUMOFPIXELS;

    pixels.setPixelColor(targetPixel, color);
  #endif
}
Neopixel Christmas animationArduino
/*
**********************************************************************
* Neopixel Christmas animation by ericBcreator
* Designed to be used with an Arduino UNO, Nano or compatible device.
**********************************************************************
* Last updated 20181225 by ericBcreator
*
* This code is free for personal use, not for commercial purposes.
* Please leave this header intact.
*
* contact: ericBcreator@gmail.com
**********************************************************************
*/ 

#include <Adafruit_NeoPixel.h>

#define SIGNALPIN       3
#define NUMOFPIXELS     60
#define COLORWHEEL      3  // 0 red-green, 1 red-green-yellow, 2 red-green-white, 3 red-green-yellow-red-green-white

uint32_t stripColor[NUMOFPIXELS + 6];
  
int startFadeDelay = 50;
int maxBrightness = 50;
int ledBrightness = maxBrightness;

int fadeDelay = 750;
int fadeHoldDelay = 5000;

int flyDelay = 5;
float flyDelayFactor = .8;

int slowLoopDelay = 500;
int slowLoopCount = 25;

int fastLoopDelay = 60;
int fastLoopCount = 100;

int flashDelay = 200;
int flashCount = 10;

int walkDelay = 500;
int walkCount = 10;

int pixelOffset = 0;
int colorRange = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMOFPIXELS, SIGNALPIN, NEO_GRB + NEO_KHZ800); // grb

void setup() {
  pixels.begin();
  fadeIn();
}

void loop() {  
  slowLoop();
  fastLoop();
  walk();
  flash();
  flyOut();
  flyIn();
}

void fadeIn() {  
  for (int i = 0; i <= maxBrightness; i += 2) {  
    ledBrightness = i;
    setStripColors();
    setPixelColors();
    delay(startFadeDelay);
  }
}

void slowLoop() {
  for (int i = 0; i < slowLoopCount; i++) {
    setPixelColors();
    pixelOffset++;
    pixelOffset = pixelOffset % (colorRange + 1);
    delay(slowLoopDelay);
  }
}

void fastLoop() {
  for (int i = 0; i < fastLoopCount; i++) {
    setPixelColors();
    pixelOffset++;
    pixelOffset = pixelOffset % (colorRange + 1);
    delay(fastLoopDelay);
  }
}

void flyIn() {
  int i, j, delayTime;
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    for (j = NUMOFPIXELS - 1; j >= i; j--) {
      pixels.setPixelColor(j, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
      pixels.show();
      delayTime = flyDelay - (((NUMOFPIXELS - i) * flyDelay * flyDelayFactor) / NUMOFPIXELS);
      delay(delayTime);
      pixels.setPixelColor(j, 0);
    }
    pixels.setPixelColor(i, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
  }
  pixels.show();
  delay(slowLoopDelay);
}

void flyOut() {
  int i, j, delayTime;
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    for (j = i; j >= 0; j--) {
      pixels.setPixelColor(j, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
      pixels.show();
      delayTime = flyDelay - ((i * flyDelay * flyDelayFactor) / NUMOFPIXELS);
      delay(delayTime);
      pixels.setPixelColor(j, 0);
    }
  }
  pixels.show();
  delay(fastLoopDelay);
}

void flash() {
  for (int i = 0; i < flashCount; i++) {
    ledBrightness = maxBrightness * .2;
    setStripColors();
    setPixelColors();
    delay(flashDelay);

    ledBrightness = maxBrightness * .7;
    setStripColors();
    setPixelColors();
    delay(flashDelay);
  }
  
  ledBrightness = maxBrightness;
  setStripColors();
}

void walk() { 
  int i, j, k, pixelCol;
  uint32_t pixelColor;

  for (k = 0; k < walkCount; k++) {
    for (j = colorRange; j >= 0; j--) {
      for (i = 0; i < NUMOFPIXELS; i++) {
        if ((i % (colorRange + 1)) == j) {
          pixelCol = i + pixelOffset;
          if (pixelCol >= NUMOFPIXELS)
            pixelCol -= colorRange + 1; 
          pixelColor = stripColor[pixelCol];
        } else
          pixelColor = 0;
        pixels.setPixelColor(i, pixelColor);
      }
      pixels.show();
      delay(walkDelay);
    }
  }
}

void setStripColors() {
  if (COLORWHEEL == 0)
    setStripColorsRG();
  else if (COLORWHEEL == 1)
    setStripColorsRGY();
  else if (COLORWHEEL == 2)
    setStripColorsRGW();
  else if (COLORWHEEL == 3)
    setStripColorsRGYW();
}

void setStripColorsRG() {
  int r, g, b;
  colorRange = 1;
  
  r = ledBrightness;
  g = ledBrightness;
  b = 0;

  for (int i = 0; i < NUMOFPIXELS; i += 2) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
  }
}

void setStripColorsRGY() {
  int r, g, y, b;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;  
  y = (ledBrightness * 215 / 255);
  b = 0;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, y, 0);
  }
}

void setStripColorsRGW() {
  int r, g, b;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;
  b = ledBrightness / 3;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, g, b);
  }
}

void setStripColorsRGYW() {
  int r, g, y, b;
  colorRange = 5;
  
  r = ledBrightness;
  g = ledBrightness;  
  y = (ledBrightness * 215 / 255);
  b = ledBrightness / 3;

  for (int i = 0; i < NUMOFPIXELS ; i += 6) {
    stripColor[i] =  pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, y, 0);
    stripColor[i+3] = pixels.Color(r, 0, 0);    
    stripColor[i+4] = pixels.Color(0, g, 0);
    stripColor[i+5] = pixels.Color(r, g, b);
  }
}

void setPixelColors() {
  int pixelCol;
  
  for (int i = 0; i < NUMOFPIXELS; i++) {
    pixelCol = i + pixelOffset;
    if (pixelCol >= NUMOFPIXELS)
      pixelCol -= colorRange + 1;
      
    pixels.setPixelColor(i, stripColor[pixelCol]);
  }
  pixels.show();
}
Neopixel visual counterArduino
A simple program that gives visual information about the number of LEDs on a Neopixel strip, ring or matrix.
/*
**********************************************************************
* Neopixel counter by ericBcreator
* Designed to be used with an Arduino UNO, Nano or compatible device.
**********************************************************************
* easy visual counting of the number of pixels of an LED strip, 
* ring or matrix
*
* the     1st led: green
* every   5th led: blue
* every  10th led: red
* every 100th led: green 
* other leds:      white
*
* important: check the color setting, NEO_GRB for most NeoPixels
**********************************************************************
* Last updated 20181225 by ericBcreator
*
* This code is free for personal use, not for commercial purposes.
* Please leave this header intact.
*
* contact: ericBcreator@gmail.com
**********************************************************************
*/ 

#include <Adafruit_NeoPixel.h>

#define SIGNALPIN       3
#define MAXPIXELS       200

int showDelay = 20;
int pixNum;

uint32_t pc, pc0, pc5, pc10, pc100;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(MAXPIXELS, SIGNALPIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin(); 

  pc    = pixels.Color(20, 20, 20);
  pc0   = pixels.Color( 0, 40,  0);
  pc5   = pixels.Color( 0,  0, 40);
  pc10  = pixels.Color(40,  0,  0);
  pc100 = pixels.Color(40, 40,  0);

  pixels.setPixelColor(0, pc0);

  for (int i = 1; i < MAXPIXELS; i++) {
    pixNum = i + 1;
    if (pixNum % 100 == 0)
      pixels.setPixelColor(i, pc100);
    else if (pixNum % 10 == 0)
      pixels.setPixelColor(i, pc10);
    else if (pixNum % 5 == 0)
      pixels.setPixelColor(i, pc5);
    else
      pixels.setPixelColor(i, pc);

    pixels.show();
    delay(showDelay);
  }  
}

void loop() {
  // empty...
}
Neopixel Christmas animation - version 20191208Arduino
/*
**********************************************************************
* Neopixel Christmas animation by ericBcreator
* Designed to be used with an Arduino UNO, Nano or compatible device.
**********************************************************************
* Last update 20191209 by ericBcreator
*   - added support for 2 rings
*   - added offset support for setting the pixel 0
*   - added circle in/out and sparkle animations
*   - other enhancements
*
* This code is free for personal use, not for commercial purposes.
* Please leave this header intact.
*
* contact: ericBcreator@gmail.com
**********************************************************************
*/ 

//
// includes
//

#include <Adafruit_NeoPixel.h>

//
// debug settings
//

//#define DEBUG                                 // print debug messages
//#define DEBUGVERBOSE                          // print calculated delay for fly in and out
//#define DEBUGCHECKPIXEL0                      // visual check which pixel is at 0 (after MAINPIXELOFFSET), sets it off after the startup fade in (also the 0 pixel of a 2nd ring)

#ifdef DEBUG
  #define DEBUGPRINT(x)   Serial.print(x)
  #define DEBUGPRINTLN(x) Serial.println(x)
#else
  #define DEBUGPRINT(x)
  #define DEBUGPRINTLN(x)
#endif

//
// definitions
//

#define SIGNALPIN           3                   // @EB-setup the digital output pin
#define TWO24RINGS                              // @EB-setup setup for 2 24 led rings
//#define ONE60RING                               // @EB-setup setup for 1 60 led ring

#ifdef TWO24RINGS                                 // definition for 2 24 LED rings
  #define NUMOFPIXELS        48                   // the number of pixels
  #define TWOSTRIPS                               // define when using 2 LED strips
  #define MAINPIXELOFFSET     0                   // offset for pixel 0
  #define STRIP2OFFSET        1                   // offset for the 2nd strip (only works with 2 strips)
  
#elif defined ONE60RING                           // definition for 1 60 LED ring
  #define NUMOFPIXELS        60                   // the number of pixels
  #define MAINPIXELOFFSET     2                   // offset for pixel 0
#endif

//
// settings
//

const int colorWheel = 0;                       // 0 red-green, 1 red-green-yellow, 2 red-green-white, 3 red-green-yellow-red-green-white
                                                // 4 red-green-blue 5 red-green-blue-red-green-yellow
const int maxColorWheel = 5;
const bool loopColorWheel = true;               // if true, loop through the color wheels
const int multiplier = 1;                       // multiplier for the number of loops of the animations

int startFadeDelay = 50;
int maxBrightness = 30;
int ledBrightness = maxBrightness;

int fadeDelay = 750;
int fadeHoldDelay = 5000;

int flyDelay = 5;
int flyStep = 1;
float flyDelayFactor = .8;

int circleDelay = 30;

int slowLoopDelay = 500;
int slowLoopCount = 25 * multiplier;

int fastLoopDelay = 60;
int fastLoopCount = 100 * multiplier;

int walkDelay = 500;
int walkCount = 5 * multiplier;

int sparkleDelay = 40;
int sparkleCount = 350 * multiplier;
int sparkleStep = 2;
int sparkleRandomMax = 100;
int sparkleRandomLimit = 40;

int flashDelay = 200;
int flashCount = 10 * multiplier / 2;

//
// setup variables
//

int pixelOffset = 0;
int colorRange = 0;
int currentColorWheel = colorWheel;
bool mainLoopBit = false;

#ifdef TWOSTRIPS
  int middlePixel = NUMOFPIXELS / 2;
#endif

uint32_t stripColor[NUMOFPIXELS + 6];

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMOFPIXELS, SIGNALPIN, NEO_GRB + NEO_KHZ800); // grb

//
// setup
//

void setup() {
  #ifdef DEBUGPRINT
    Serial.begin(115200);
    DEBUGPRINTLN("Setup");
  #endif

  randomSeed(analogRead(0));
  
  pixels.begin();
  fadeIn();

  #ifdef DEBUGCHECKPIXEL0
    setOneLed(0, 0);
    #ifdef TWOSTRIPS
      setOneLed(middlePixel ,0);
    #endif
    pixels.show();
    delay(7500);
  #endif
}

//
// main loop
//

void loop() {  
  DEBUGPRINTLN("Main loop");
  slowLoop();
  fastLoop();
  walk(0);
  sparkleFade();
  flash();
  
  #ifdef TWOSTRIPS
    circleOut();
    circleIn();
    circleOut();
  #else
    if (mainLoopBit)
      circleOut();
    else
      flyOut();
  #endif

  if (loopColorWheel) {
    pixelOffset = 0;
    currentColorWheel++;
    if (currentColorWheel > maxColorWheel)
      currentColorWheel = 0;
    DEBUGPRINTLN("  Colorwheel set to " + String(currentColorWheel));
    setStripColors();
  }

  #ifdef TWOSTRIPS
    circleIn();
  #else
    if (mainLoopBit)
      circleIn();
    else
      flyIn();
  #endif

  mainLoopBit = !mainLoopBit;
}

//
// functions
//

void fadeIn() {
  DEBUGPRINTLN("Fade in");
  for (int i = 0; i <= maxBrightness; i += 2) {  
    ledBrightness = i;
    setStripColors();
    setPixelColors();
    delay(startFadeDelay);
  }
}

void slowLoop() {
  DEBUGPRINTLN("  Anim: Slow loop");
  for (int i = 0; i < slowLoopCount; i++) {
    setPixelColors();
    pixelOffset++;
    pixelOffset = pixelOffset % (colorRange + 1);
    delay(slowLoopDelay);
  }
}

void fastLoop() {
  DEBUGPRINTLN("  Anim: Fast loop");
  for (int i = 0; i < fastLoopCount; i++) {
    setPixelColors();
    pixelOffset++;
    pixelOffset = pixelOffset % (colorRange + 1);
    delay(fastLoopDelay);
  }
}

void flyOut() {
  int i, j, delayTime;
  DEBUGPRINTLN("  Anim: Fly out");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    for (j = i; j > 0; j = j - flyStep) {
      setOneLed(j, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
      pixels.show();
      
      delayTime = flyDelay - ((i * flyDelay * flyDelayFactor) / NUMOFPIXELS);
      #ifdef DEBUGVERBOSE
        DEBUGPRINT(delayTime);
        DEBUGPRINT("  ");
      #endif
      delay(delayTime);
      setOneLed(j, 0);
    }
  }
  
  #ifdef DEBUGVERBOSE
    DEBUGPRINTLN();
  #endif
  pixels.show();
}

void flyIn() {
  int i, j, delayTime;
  DEBUGPRINTLN("  Anim: Fly in");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    for (j = NUMOFPIXELS - i % flyStep; j > i; j = j - flyStep) {
      if (j >= 0) {
        setOneLed((j - 1), stripColor[(i + pixelOffset) % NUMOFPIXELS]);        
        pixels.show();
        
        delayTime = flyDelay - (((NUMOFPIXELS - i) * flyDelay * flyDelayFactor) / NUMOFPIXELS);
        #ifdef DEBUGVERBOSE
          DEBUGPRINT(delayTime);
          DEBUGPRINT("  ");
        #endif
        delay(delayTime);
        setOneLed((j - 1), 0);
      }
    }
    setOneLed((i - 1), stripColor[(i + pixelOffset) % NUMOFPIXELS]);
  }

  #ifdef DEBUGVERBOSE
    DEBUGPRINTLN();
  #endif
  pixels.show();
}

void circleOut() {
  int i;
  DEBUGPRINTLN("  Anim: Circle out");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    setOneLed(i, 0);
    pixels.show();
    delay(circleDelay);
  }
}

void circleIn() {
  int i;
  DEBUGPRINTLN("  Anim: Circle in");
  
  for (i = 0; i < NUMOFPIXELS; i++) {
    setOneLed(i, stripColor[(i + pixelOffset) % NUMOFPIXELS]);
    pixels.show();
    delay(circleDelay);
  }
}

void flash() {
  DEBUGPRINTLN("  Anim: Flash");
  
  for (int i = 0; i < flashCount; i++) {
    ledBrightness = maxBrightness * .2;
    setStripColors();
    setPixelColors();
    delay(flashDelay);

    ledBrightness = maxBrightness * .7;
    setStripColors();
    setPixelColors();
    delay(flashDelay);
  }
  
  ledBrightness = maxBrightness;
  setStripColors();
}

void walk(byte setting) { 
  DEBUGPRINTLN("  Anim: Walk");
  
  int i, j, k, pixelCol;
  uint32_t pixelColor;

  for (k = 0; k < walkCount; k++) {
    for (j = colorRange; j >= 0; j--) {
      for (i = 0; i < NUMOFPIXELS; i++) {
        pixelCol = i + pixelOffset;
        if (pixelCol >= NUMOFPIXELS)
          pixelCol -= colorRange + 1; 
        pixelColor = stripColor[pixelCol];
          
        if ((i % (colorRange + 1)) != j)
          pixelColor = 0; 
          
        setOneLed(i, pixelColor);
      }
      pixels.show();
      delay(walkDelay);
    }
  }
}

void sparkleFade() {
  DEBUGPRINTLN("  Anim: Fading sparkles");
  
  int r, g, b, j, i, maxLoop, pixel;
  int sparklePos[NUMOFPIXELS] = {};
  int sparkleDir[NUMOFPIXELS] = {};
  uint32_t pixelColor;

  maxLoop = sparkleCount + (maxBrightness / sparkleStep);

  for (j = 0; j < maxLoop; j++) {
    if (j < sparkleCount) {                                     // stop adding sparkles after reaching the max...
      if (random(sparkleRandomMax) < sparkleRandomLimit) {
        pixel = random(NUMOFPIXELS);
        if (sparkleDir[pixel] == 0)
          sparkleDir[pixel] = 1;
      }
    } else if (j == sparkleCount) {                             // ...then fade out the sparkles 
      for (i = 0; i < NUMOFPIXELS; i++) {
        if (sparkleDir[i] == 1) 
          sparkleDir[i] = 2;
      }      
    }
    
    for (i = 0; i < NUMOFPIXELS; i++) {
      if (sparkleDir[i] == 0) 
        setOneLed(i, 0);
        
      else {
        if (sparkleDir[i] == 1) {
          sparklePos[i] += sparkleStep;
          if (sparklePos[i] >= maxBrightness) {
            sparkleDir[i] = 2;
            sparklePos[i] = maxBrightness;
          }
        } else {
          sparklePos[i] -= sparkleStep;            
          if (sparklePos[i] <= 0) {
            sparkleDir[i] = 0;
            sparklePos[i] = 0;
          }
        }
        
        pixelColor = stripColor[i];
        r = (pixelColor >> 16) * sparklePos[i] / maxBrightness;
        g = ((pixelColor >> 8) & 0xFF) * sparklePos[i] / maxBrightness;
        b = (pixelColor & 0xFF) * sparklePos[i] / maxBrightness;
        pixelColor = pixels.Color(r, g, b);
        setOneLed(i, pixelColor);          
      }
    }

    pixels.show();
    delay(sparkleDelay);
  }
}

//
// functions for settings colors
//

void setStripColors() {  
  switch (currentColorWheel) {
    case 0: setStripColorsRG();     break;
    case 1: setStripColorsRGY();    break;
    case 2: setStripColorsRGW();    break;
    case 3: setStripColorsRGYRGW(); break;
    case 4: setStripColorsRGB();    break;
    case 5: setStripColorsRGBRGY(); break;
  }
}

void setStripColorsRG() {
  int r, g, b;
  colorRange = 1;
  
  r = ledBrightness;
  g = ledBrightness;
  b = 0;

  for (int i = 0; i < NUMOFPIXELS; i += 2) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
  }
}

void setStripColorsRGY() {
  int r, g, gy, b;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;  
  gy = (ledBrightness * 215 / 255);
  b = 0;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, gy, 0);
  }
}

void setStripColorsRGW() {
  int r, g, bw;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;
  bw = ledBrightness / 3;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, g, bw);
  }
}

void setStripColorsRGYRGW() {
  int r, g, gy, bw;
  colorRange = 5;
  
  r = ledBrightness;
  g = ledBrightness;  
  gy = (ledBrightness * 215 / 255);
  bw = ledBrightness / 3;

  for (int i = 0; i < NUMOFPIXELS ; i += 6) {
    stripColor[i] =  pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, gy, 0);
    stripColor[i+3] = pixels.Color(r, 0, 0);    
    stripColor[i+4] = pixels.Color(0, g, 0);
    stripColor[i+5] = pixels.Color(r, g, bw);
  }
}

void setStripColorsRGB() {
  int r, g, b;
  colorRange = 2;
  
  r = ledBrightness;
  g = ledBrightness;  
  b = ledBrightness;

  for (int i = 0; i < NUMOFPIXELS ; i += 3) {
    stripColor[i] = pixels.Color(r, 0, 0);    
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(0, 0, b);
  }
}

void setStripColorsRGBRGY() {
  int r, g, gy, b;
  colorRange = 5;
  
  r = ledBrightness;
  g = ledBrightness;  
  gy = (ledBrightness * 215 / 255);
  b = ledBrightness;

  for (int i = 0; i < NUMOFPIXELS ; i += 6) {
    stripColor[i] =  pixels.Color(r, 0, 0);
    stripColor[i+1] = pixels.Color(0, g, 0);
    stripColor[i+2] = pixels.Color(r, gy, 0);
    stripColor[i+3] = pixels.Color(r, 0, 0);
    stripColor[i+4] = pixels.Color(0, g, 0);
    stripColor[i+5] = pixels.Color(0, 0, b);
  }
}

void setPixelColors() {
  int pixelCol;
  
  for (int i = 0; i < NUMOFPIXELS; i++) {
    pixelCol = i + pixelOffset;
    if (pixelCol >= NUMOFPIXELS)
      pixelCol -= colorRange + 1;
      
    setOneLed(i, stripColor[pixelCol]);
  }
  pixels.show();
}

void setOneLed(int pixel, uint32_t color) {
  int targetPixel;

  #ifdef TWOSTRIPS
    if (pixel < middlePixel) {
      targetPixel = (pixel + MAINPIXELOFFSET) % middlePixel;
      if (targetPixel < 0)
        targetPixel += middlePixel;

      pixels.setPixelColor(targetPixel, color);  
    } else {
      targetPixel = (NUMOFPIXELS - pixel - MAINPIXELOFFSET - STRIP2OFFSET) % middlePixel;
      if (targetPixel < 0)
        targetPixel += middlePixel;
        
      pixels.setPixelColor((middlePixel + targetPixel), color);  
    }
  #else
    targetPixel = (pixel + MAINPIXELOFFSET) % NUMOFPIXELS;
    if (targetPixel < 0)
      targetPixel += NUMOFPIXELS;

    pixels.setPixelColor(targetPixel, color);
  #endif
}

Schematics

Adafruit Neopixel wiring diagram
Note: in the code output pin 3 is used. In the picture, the led strip is connected to output pin 6, connect to pin 3 instead.
Leds wiring diagram luuoqxwbfh

Comments

Similar projects you might like

Arduino Clock with Neopixel Ring Animation

Project tutorial by Alexander

  • 66,744 views
  • 45 comments
  • 100 respects

NeoPixel Multiple Ring Animation

Project showcase by ericBcreator

  • 5,061 views
  • 0 comments
  • 6 respects

5 Minute Christmas Neopixel Led Strip

Project showcase by Alexander

  • 26,431 views
  • 30 comments
  • 42 respects

How to Make a NeoPixel Matrix

Project tutorial by Arduino “having11” Guy

  • 16,000 views
  • 6 comments
  • 19 respects

Stereo NeoPixel Ring VU Meter

Project showcase by ericBcreator

  • 115,935 views
  • 373 comments
  • 206 respects

NeoPixel SkateBoard

Project tutorial by Dante Roumega

  • 2,730 views
  • 2 comments
  • 10 respects
Add projectSign up / Login