MATERIALS
WS2812B Addressable LED ​​​​​​​
Green Cast Matte Metallic® - Antique Gold Metallic Acrylic 12x20" 
Green Cast Nacre® - Mother of Pearl Silver Acrylic 12x24 
ARDUINO CODE:
//GET OUR LIBRARIES
#include <FastLED.h>
#include <OneButton.h>

//DEFINE OUR WHAT IS CONNECTED TO OUR PINES
#define LED_PIN_CENTER     4 //CENTER
#define LED_PIN_A          2 //SIDE A
#define LED_PIN_B          7 //SIDE B
#define BTN_PIN            14  //BUTTON

//DEFINE HOW MANY LEDS EACH STRIP HAS
#define NUM_LEDS_CENTER    139 //NUMBER LEDS CENTER
#define NUM_LEDS_SIDE_A     56 //NUMBER LEDS SIDE
#define NUM_LEDS_SIDE_B     56 //NUMBER LEDS SIDE

//DEFINE SETTINGS FOR SUB LOOPS
#define COOLING  55
#define SPARKING 120

// Define the array of leds, This is what we will use to turn on a specific strand of LEDs
CRGB ledsC[NUM_LEDS_CENTER];
CRGB ledsA[NUM_LEDS_SIDE_A];
CRGB ledsB[NUM_LEDS_SIDE_B];


//Global Variables that can be used in any function
unsigned long interval=25; // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.
unsigned long interval_b = 100; // the time we need to wait Part 2

uint8_t patternCounter = 0;
uint8_t minBright = 20;
uint8_t maxBright = 80;
bool gReverseDirection = false;

//MORE GLOBAL VARIABLES FOR SUB LOOPS
int numColors = 1;
int ra = 60;
int rb = 0;
int dir = 0;
int dirb = 0;
int dirc = 0;
int la = 0;
int sat = 0;

// Push button connected between pin 14 and GND (no resistor required) Defining our Push Button
OneButton btn = OneButton(BTN_PIN, true, true);

void setup() {

  //Initializing our LEDs
  FastLED.addLeds<WS2812, LED_PIN_CENTER, GRB>(ledsC, NUM_LEDS_CENTER);
  FastLED.addLeds<WS2812, LED_PIN_A, GRB>(ledsA, NUM_LEDS_SIDE_A);
  FastLED.addLeds<WS2812, LED_PIN_B, GRB>(ledsB, NUM_LEDS_SIDE_B);
  //Set our inital LED Brightness
  FastLED.setBrightness(50);
  //Serial.begin(9600);
  //One Button lets us tell the program what to do when the button is clicked, so it will Run - nextPattern
  btn.attachClick(nextPattern);
  //This gives us time will testing to upload a new sketch to the board in case it gets stuck, Can take this out once code is finalized
  delay(5000);

}

//MAIN LOOP
void loop() {

  //SWITCH & CASE - controls the flow of programs by allowing programmers to specify different code that should be executed in various conditions
  //BREAK - keyword exits the switch statement, and is typically used at the end of each case. Without a break statement, the switch statement will
  //continue executing the following expressions ("falling-through") until a break, or the end of the switch statement is reached.
  switch (patternCounter) {
    case 0:
      solidColor();      
      break;
    case 1:
      rainbowBeat();
      break;
    case 2:
      redAlertB();
      break;
    case 3:
      fire();
      break;
    case 4:
      juggle();
      break;
    case 5:
      movingDots();
      break;
    case 6:
      redAlert();
      break;
    case 7:
      redgold();
      break;
    case 8:
      gradientChangeSlow();
      break;
    case 9:
      gradientChangeFast();
      break;
  }

  //NOTICE FastLED.show is here, and not in our Sub Loops
  FastLED.show();
  btn.tick();
}

void nextPattern() {
  //This changes what Case we are on
  patternCounter = (patternCounter + 1) % 10;           // Change the number after the % to the number of patterns you have
  FastLED.clear (); //Clears our current LEDs
}

//------- Put your patterns below -------//

void solidColor() {

   //TO Change the Speed Change the 5000
   float breath = (exp(sin(millis()/5000.0*PI)) - 0.36787944)*108.0;
   //Map Breath Value from above to 0-255, then get the GLOBAL minBright & maxBright Variable
   breath = map(breath, 0, 255, minBright, maxBright);
   FastLED.setBrightness(breath);

   fill_solid(ledsC, NUM_LEDS_CENTER, CRGB::SlateGray);
   fill_solid(ledsA, NUM_LEDS_SIDE_A, CRGB::Gold);
   fill_solid(ledsB, NUM_LEDS_SIDE_B, CRGB::Gold);
   
}

void rainbowBeat() {

  uint16_t beatA = beatsin16(30, 0, 255);
  uint16_t beatB = beatsin16(20, 0, 255);
  fill_rainbow(ledsC, NUM_LEDS_CENTER, (beatA+beatB)/2, 8);  // Initial Hue - Delta HUE - How fast to advance the led
  fill_rainbow(ledsA, NUM_LEDS_SIDE_A, (beatA+beatB)/2, 8);
  fill_rainbow(ledsB, NUM_LEDS_SIDE_B, (beatA+beatB)/2, 8);
}

void redAlertB() {

    unsigned long currentMillis = millis();
   
    if ((unsigned long)(currentMillis - previousMillis) >= interval) {

        //LEFT SIDE OF CENTER
        ledsC[ra]  = CRGB(255,0,0);
        if (dir == 0){
          ra ++;
            if (ra == 140){
              dir  = 1;
              }
        }
        else if (dir == 1){
          ra --;
            if (ra == 60){
              dir = 0;
            }
        }
        //RIGHT SIDE OF CENTER
        ledsC[rb] = CRGB(255,0,0);
        if (dirb == 0){
          rb ++;
            if (rb == 60){
              dirb  = 1;
              }
        }
        else if (dirb == 1){
          rb --;
            if (rb == 0){
              dirb = 0;
            }
        }


        ledsA[la] = CRGB(255,0,0);
        ledsB[la] = CRGB(255,0,0);
        if (dirc == 0){
          la ++;
            if (la == NUM_LEDS_SIDE_A){
              dirc  = 1;
              }
        }
        else if (dirc == 1){
          la --;
            if (la == 0){
              dirc = 0;
            }
        }
       
       

        fadeToBlackBy(ledsC, NUM_LEDS_CENTER, 8);
        fadeToBlackBy(ledsA, NUM_LEDS_SIDE_A, 15);
        fadeToBlackBy(ledsB, NUM_LEDS_SIDE_B, 15);
        previousMillis = millis();
     
  }
}

void fire()  {
// Array of temperature readings at each simulation cell
  static byte heat[NUM_LEDS_CENTER];

  // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS_CENTER; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS_CENTER) + 2));
    }

    for( int i = 0; i < NUM_LEDS_SIDE_A; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS_SIDE_A) + 2));
    }


    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= NUM_LEDS_CENTER - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
    }

    for( int k= NUM_LEDS_SIDE_A - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
    }    

    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int y = random8(7);
      heat[y] = qadd8( heat[y], random8(160,255) );
    }

    // Step 4.  Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS_CENTER; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS_CENTER-1) - j;
      } else {
        pixelnumber = j;
      }
      ledsC[pixelnumber] = color;
    }

    // Step 4.  SIDE A
    for( int j = 0; j < NUM_LEDS_SIDE_A; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS_SIDE_A-1) - j;
      } else {
        pixelnumber = j;
      }
      ledsA[pixelnumber] = color;
    }

    // Step 4.  SIDE B
    for( int j = 0; j < NUM_LEDS_SIDE_B; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS_SIDE_B-1) - j;
      } else {
        pixelnumber = j;
      }
      ledsB[pixelnumber] = color;
    }    
}

void juggle() {
  fadeToBlackBy( ledsC, NUM_LEDS_CENTER, 20);
  fadeToBlackBy( ledsA, NUM_LEDS_SIDE_A, 20);
  fadeToBlackBy( ledsB, NUM_LEDS_SIDE_B, 20);
  uint8_t dothue = 0;
  for( int i = 0; i < 8; i++) {
    ledsC[beatsin16( i+7, 0, NUM_LEDS_CENTER-1 )] |= CHSV(dothue, 200, 255);
    ledsA[beatsin16( i+7, 0, NUM_LEDS_SIDE_A-1 )] |= CHSV(dothue, 200, 255);
    ledsB[beatsin16( i+7, 0, NUM_LEDS_SIDE_B-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

void movingDots() {

//       beatsin16( BPM, uint16_t low, uint16_t high) returns a 16-bit value
//                    that rises and falls in a sine wave, 'BPM' times per
//                    minute, between the values of 'low' and 'high'.

  //CENTER
  uint16_t posBeat  = beatsin16(30, 0, NUM_LEDS_CENTER - 1, 0, 0);
  uint16_t posBeat2 = beatsin16(60, 0, NUM_LEDS_CENTER - 1, 0, 0);

  uint16_t posBeat3 = beatsin16(30, 0, NUM_LEDS_CENTER - 1, 0, 32767);
  uint16_t posBeat4 = beatsin16(60, 0, NUM_LEDS_CENTER - 1, 0, 32767);

  //SIDES A & B
  uint16_t posBeat5  = beatsin16(30, 0, NUM_LEDS_SIDE_A - 1, 0, 0);
  uint16_t posBeat6  = beatsin16(60, 0, NUM_LEDS_SIDE_B - 1, 0, 0);

  uint16_t posBeat7 = beatsin16(30, 0, NUM_LEDS_SIDE_A - 1, 0, 32767);
  uint16_t posBeat8 = beatsin16(60, 0, NUM_LEDS_SIDE_B - 1, 0, 32767);  

  // Wave for LED color
  uint8_t colBeat  = beatsin8(45, 0, 255, 0, 0);

  //HUE SATURATION VALUE (Brightness)

  ledsC[(posBeat + posBeat2) / 2]  = CHSV(colBeat, 255, 255);
  ledsC[(posBeat3 + posBeat4) / 2]  = CHSV(colBeat, 255, 255);

  ledsA[(posBeat5 + posBeat6) / 2]  = CHSV(colBeat, 255, 255);
  ledsA[(posBeat7 + posBeat8) / 2]  = CHSV(colBeat, 255, 255);

  ledsB[(posBeat5 + posBeat6) / 2]  = CHSV(colBeat, 255, 255);
  ledsB[(posBeat7 + posBeat8) / 2]  = CHSV(colBeat, 255, 255);

  //Turn Off Lights by fadeing

  fadeToBlackBy(ledsC, NUM_LEDS_CENTER, 10);
  fadeToBlackBy(ledsA, NUM_LEDS_SIDE_A, 10);
  fadeToBlackBy(ledsB, NUM_LEDS_SIDE_B, 10);
}

void redAlert() {

  FastLED.setBrightness(50);

  //(BEATS per min, FIRST LED, LAST LED, TIMEBASE, PHASE OFFSET)
  //beatsin16 generates a 16-bit sine wave at a given BPM, that oscillates within a given range
  //So we are generating this SinWave between 60 & 139 on our LED Strip for the Center part
  uint16_t sinBeatA   = beatsin16(15, 60, 139, 0, 21845);
  uint8_t sinBeatAA   = beatsin8(15, 60, 139, 0, 0);

  uint16_t sinBeatB   = beatsin16(30, 0, 60, 0, 21845);
  uint8_t sinBeatBB   = beatsin8(15, 0, 60, 0, 0);


  uint16_t sinBeatL   = beatsin16(15, 0, 28, 0, 21845);
  uint8_t sinBeatLL   = beatsin8(15, 0, 28, 0, 0);

  uint16_t sinBeatM   = beatsin16(15, 28, 56, 0, 21845);
  uint8_t sinBeatMM   = beatsin8(15, 28, 56, 0, 0);  


  ledsC[sinBeatA]  = CRGB(255,0,0);
  ledsC[sinBeatB]  = CRGB(255,0,0);
  ledsC[sinBeatAA]  = CRGB(255,0,0);
  ledsC[sinBeatBB]  = CRGB(255,0,0);

  ledsA[sinBeatL]  = CRGB(255,0,0);
  ledsA[sinBeatLL]  = CRGB(255,0,0);
  ledsA[sinBeatM]  = CRGB(255,0,0);
  ledsA[sinBeatMM]  = CRGB(255,0,0);  

  ledsB[sinBeatL]  = CRGB(255,0,0);
  ledsB[sinBeatLL]  = CRGB(255,0,0);
  ledsB[sinBeatM]  = CRGB(255,0,0);
  ledsB[sinBeatMM]  = CRGB(255,0,0);    

  fadeToBlackBy(ledsC, NUM_LEDS_CENTER, 5);
  fadeToBlackBy(ledsA, NUM_LEDS_CENTER, 10);
  fadeToBlackBy(ledsB, NUM_LEDS_CENTER, 10);

}


void redgold() {

  uint16_t sinBeat   = beatsin16(30, 0, NUM_LEDS_CENTER - 1, 0, 0);
  uint16_t sinBeat2  = beatsin16(30, 0, NUM_LEDS_CENTER - 1, 0, 21845);
  uint16_t sinBeat3  = beatsin16(30, 0, NUM_LEDS_CENTER - 1, 0, 43690);

  uint16_t sinBeat4  = beatsin16(30, 0, NUM_LEDS_SIDE_A - 1, 0, 0);
  uint16_t sinBeat5  = beatsin16(30, 0, NUM_LEDS_SIDE_A - 1, 0, 21845);
  uint16_t sinBeat6  = beatsin16(30, 0, NUM_LEDS_SIDE_A - 1, 0, 43690);


  ledsC[sinBeat]   = CRGB::Red;
  ledsC[sinBeat2]  = CRGB::DarkRed;
  ledsC[sinBeat3]  = CRGB::Maroon;


  ledsA[sinBeat4]  = CRGB::DarkGoldenrod;
  ledsA[sinBeat5]  = CRGB::Goldenrod;
  ledsA[sinBeat6]  = CRGB::Gold;  

  ledsB[sinBeat4]  = CRGB::DarkGoldenrod;
  ledsB[sinBeat5]  = CRGB::Goldenrod;
  ledsB[sinBeat6]  = CRGB::Gold;


  fadeToBlackBy(ledsC, NUM_LEDS_CENTER, 6);
  fadeToBlackBy(ledsA, NUM_LEDS_SIDE_A, 6);
  fadeToBlackBy(ledsB, NUM_LEDS_SIDE_A, 6);  
}

void gradientChangeSlow() {
  uint8_t starthue_c = beatsin8(4, 0, 255);
  uint8_t endhue_c = beatsin8(8, 255, 255);

  uint8_t starthue_ab = beatsin8(2, 0, 255);
  uint8_t endhue_ab = beatsin8(4, 255, 255);

  unsigned long currentMillis = millis();
   
  if ((unsigned long)(currentMillis - previousMillis) >= interval_b) {

      fill_gradient(ledsC,NUM_LEDS_CENTER,CHSV(starthue_c, 255, 255),CHSV(endhue_c, starthue_c, 255),FORWARD_HUES);
      fill_gradient(ledsA,NUM_LEDS_SIDE_A,CHSV(starthue_ab, 255, 255),CHSV(endhue_ab, starthue_ab, 255),FORWARD_HUES);
      fill_gradient(ledsB,NUM_LEDS_SIDE_B,CHSV(starthue_ab, 255, 255),CHSV(endhue_ab, starthue_ab, 255),FORWARD_HUES);
     
  }
}

void gradientChangeFast() {
  uint8_t starthue_c = beatsin8(32, 0, 255);
  uint8_t endhue_c = beatsin8(32, 255, 0);

  unsigned long currentMillis = millis();
   
  if ((unsigned long)(currentMillis - previousMillis) >= interval_b) {

      fill_gradient(ledsC,NUM_LEDS_CENTER,CHSV(starthue_c, 255, 255),CHSV(endhue_c, starthue_c, 255),FORWARD_HUES);
      fill_gradient(ledsA,NUM_LEDS_SIDE_A,CHSV(starthue_c, 255, 255),CHSV(endhue_c, starthue_c, 255),FORWARD_HUES);
      fill_gradient(ledsB,NUM_LEDS_SIDE_B,CHSV(starthue_c, 255, 255),CHSV(endhue_c, starthue_c, 255),FORWARD_HUES);
     
  }
}

You may also like

Back to Top