Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Troy's project
 
Share:
Notifications
Clear all

[Solved] Troy's project

19 Posts
2 Users
0 Reactions
8,066 Views
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2859
Topic starter  

To minimize lengthy code in the comments, I've moved Troy's project code here:

#include <EEPROM.h>
#include "FastLED.h"
#include "EnableInterrupt.h" // must use this for internal interrupts as pin 3 is the only external interrupt on pro trinket
#define NUM_LEDS 20
#define PIN 7
#define EFFECT_BUTTON 3
#define COLOR_BUTTON 4
volatile byte selectedEffect = 0;
volatile byte selectedColor = 0;
volatile bool effect_changed = false;
volatile bool color_changed = false;
CRGB leds[NUM_LEDS];
CRGB row1[NUM_LEDS]; // array used by colorWheel function
// Color (HEX Code) Array Position
// Green (0x00, 0xFF, 0x00) 0,1,2
// GreenCyan (0x00, OxFF, 0x7F) 3,4,5
// Cyan (0x00, 0xFF, 0xFF) 6,7,8
// BlueCyan (0x00, 0x7F, 0xFF) 9,10,11
// Blue (0x00, 0x00, 0xFF) 12,13,14
// BlueMagenta (0x7F, 0x00, 0xFF) 15,16,17
// Magenta (0xFF, 0x00, 0xFF) 18,19,20
// RedMagenta (0xFF, 0x00, 0x7F) 21,22,23
// Red (0xFF, 0x00, 0x00) 24,25,26
// Orange (0xFF, 0x7F, 0x00) 27,28,29
// Yellow (0xFF, 0xFF, 0x00) 30,31,32
// GreenYellow (0x7F, 0xFF, 0x00) 33,34,35
// White (0xFF, 0xFF, 0xFF) 36,37,38
uint32_t ColorArray[] = {0x00, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF, 0xFF};
byte Red = ColorArray[0];
byte Green = ColorArray[1];
byte Blue = ColorArray[2];
void setup()
{
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  pinMode (EFFECT_BUTTON, INPUT_PULLUP); // internal pull-up resistor
  pinMode (COLOR_BUTTON, INPUT_PULLUP);
  //attachInterrupt (digitalPinToInterrupt (EFFECT_BUTTON), changeEffect, CHANGE); // EFFECT_BUTTON pressed
  enableInterrupt(EFFECT_BUTTON, changeEffect, CHANGE); // EFFECT_BUTTON pressed
  enableInterrupt(COLOR_BUTTON, changeColor, CHANGE); // COLOR_BUTTON pressed
  LEDS.setBrightness(10);
  //Serial.begin(9600);
}
void loop() {
  EEPROM.get(0, selectedEffect);
  EEPROM.get(1, selectedColor);
  if (selectedEffect > 15) {
    selectedEffect = 0;
    EEPROM.put(0, 0);
  }
  if (selectedColor > 12) {
    selectedColor = 0;
    EEPROM.put(1, 0);
  }
  switch (selectedColor) {
    case 0: {
        // Green
        Red = ColorArray[0];
        Green = ColorArray[1];
        Blue = ColorArray[2];
        break;
      }
    case 1: {
        // GreenCyan
        Red = ColorArray[3];
        Green = ColorArray[4];
        Blue = ColorArray[5];
        break;
      }
    case 2: {
        // Cyan
        Red = ColorArray[6];
        Green = ColorArray[7];
        Blue = ColorArray[8];
        break;
      }
    case 3: {
        // BlueCyan
        Red = ColorArray[9];
        Green = ColorArray[10];
        Blue = ColorArray[11];
        break;
      }
    case 4: {
        // Blue
        Red = ColorArray[12];
        Green = ColorArray[13];
        Blue = ColorArray[14];
        break;
      }
    case 5: {
        // BlueMagenta
        Red = ColorArray[15];
        Green = ColorArray[16];
        Blue = ColorArray[17];
        break;
      }
    case 6: {
        // Magenta
        Red = ColorArray[18];
        Green = ColorArray[19];
        Blue = ColorArray[20];
        break;
      }
    case 7: {
        // RedMagenta
        Red = ColorArray[21];
        Green = ColorArray[22];
        Blue = ColorArray[23];
        break;
      }
    case 8: {
        // Red
        Red = ColorArray[24];
        Green = ColorArray[25];
        Blue = ColorArray[26];
        break;
      }
    case 9: {
        // Orange
        Red = ColorArray[27];
        Green = ColorArray[28];
        Blue = ColorArray[29];
        break;
      }
    case 10: {
        // Yellow
        Red = ColorArray[30];
        Green = ColorArray[31];
        Blue = ColorArray[32];
        break;
      }
    case 11: {
        // YellowGreen
        Red = ColorArray[33];
        Green = ColorArray[34];
        Blue = ColorArray[35];
        break;
      }
    case 12: {
        // White
        Red = ColorArray[36];
        Green = ColorArray[37];
        Blue = ColorArray[38];
      }
  }
  switch (selectedEffect) {
    case 0 : { // color change
        fill_solid(leds, NUM_LEDS, CRGB::Green);
        //fill_solid(leds, NUM_LEDS, Red, Green, Blue);
        FastLED.show();
        break;
      }
    case 1 : { // color change
        setColorWheelColors();
        colorWheel();
        break;
      }
    case 2 : { // color change
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(Red, Green, Blue, 25);
        colorWipe(Red, Green, Blue, 25);
        break;
      }
    case 3 : { // no color change
        // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
        meteorRain(0xff, 0xff, 0xff, 1, 80, true, 25);
        //meteorRain(Red, Green, Blue, 1, 80, true, 25);
        break;
      }
    case 4 : { // color change
        // NewKITT - Color (red, green, blue), eye size, speed delay, end pause
        NewKITT(Red, Green, Blue, 8, 10, 50);
        break;
      }
    case 5 : { // color change
        // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
        CylonBounce(Red, Green, Blue, 4, 10, 50);
        break;
      }
    case 6 : { // no color change
        // Running Lights - Color (red, green, blue), wave dealy
        RunningLights(0xff, 0x00, 0x00, 50); // red
        RunningLights(0xff, 0xff, 0xff, 50); // white
        RunningLights(0x00, 0x00, 0xff, 50); // blue
        break;
      }
    case 7 : { // color change
        // theatherChase - Color (red, green, blue), speed delay
        theaterChase(Red, Green, Blue, 50);
        break;
      }
    case 8 : { // no color change
        // theaterChaseRainbow - Speed delay
        //theaterChaseRainbow(50);
        break;
      }
    case 9 : { // no color change
        // Fire - Cooling rate, Sparking rate, speed delay
        Fire(55, 120, 15);
        break;
      }
    case 10 : { // no color change
        // FadeInOut - Color (red, green, blue)
        FadeInOut(0xff, 0x00, 0x00); // red
        FadeInOut(0xff, 0xff, 0xff); // green
        FadeInOut(0x00, 0x00, 0xff); // blue
        break;
      }
    case 11 : { // color change
        // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
        Strobe(Red, Green, Blue, 10, 50, 1000);
        break;
      }
    case 12 : { // color change
        // Sparkle - Color (red, green, blue), speed delay
        Sparkle(Red, Green, Blue, 0);
        break;
      }
    case 13 : { // color change
        // Twinkle - Color (red, green, blue), count, speed delay, only one twinkle (true/false)
        Twinkle(Red, Green, Blue, 10, 100, false);
        break;
      }
    case 14 : { // no color change
        // TwinkleRandom - twinkle count, speed delay, only one (true/false)
        TwinkleRandom(20, 100, false);
        break;
      }
    case 15 : { // no color change
        // rainbowCycle - speed delay
        rainbowCycle(20);
        break;
      }
  }
}
void changeEffect() {
  if (digitalRead (EFFECT_BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect);
    asm volatile (" jmp 0");
  }
}
void changeColor() {
  if (digitalRead (COLOR_BUTTON) == HIGH) {
    selectedColor++;
    EEPROM.put(1, selectedColor);
    asm volatile (" jmp 0");
  }
}
// *************************
// ** LEDEffect Functions **
// *************************
void setColorWheelColors() {
  row1[0] = CRGB::Red;
  row1[1] = CRGB::Red;
  row1[2] = CRGB::Red;
  row1[3] = CRGB::Black;
  row1[4] = CRGB::Black;
  row1[5] = CRGB::Black;
  row1[6] = CRGB::Black;
  row1[7] = CRGB::Black;
  row1[8] = CRGB::Black;
  row1[9] = CRGB::Black;
  row1[10] = CRGB::Black;
  row1[11] = CRGB::Black;
  row1[12] = CRGB::Red;
  row1[13] = CRGB::Red;
  row1[14] = CRGB::Red;
  row1[15] = CRGB::Black;
  row1[16] = CRGB::Black;
  row1[17] = CRGB::Black;
  row1[18] = CRGB::Black;
  row1[19] = CRGB::Black;
  row1[20] = CRGB::Black;
}
void colorWheel() {
  for (int j = 0; j < NUM_LEDS; j++) {
    assignTo(j);
    FastLED.show();
    delay(50);
  }
}
//used by colorWheel
void assignTo(int j) {
  int i;
  for (i = 0; i < NUM_LEDS; i++)
  {
    leds = row1[(i + j) % NUM_LEDS];
  }
}
void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for (uint16_t i = 0; i < NUM_LEDS; i++) {
    setPixel(i, red, green, blue);
    showStrip();
    delay(SpeedDelay);
  }
}
void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
  setAll(0, 0, 0);
  for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {
    // fade brightness all LEDs one step
    for (int j = 0; j < NUM_LEDS; j++) {
      if ( (!meteorRandomDecay) || (random(10) > 5) ) {
        fadeToBlack(j, meteorTrailDecay );
      }
    }
    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
        setPixel(i - j, red, green, blue);
      }
    }
    showStrip();
    delay(SpeedDelay);
  }
}
// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  uint32_t oldColor;
  uint8_t r, g, b;
  int value;
  oldColor = strip.getPixelColor(ledNo);
  r = (oldColor & 0x00ff0000UL) >> 16;
  g = (oldColor & 0x0000ff00UL) >> 8;
  b = (oldColor & 0x000000ffUL);
  r = (r <= 10) ? 0 : (int) r - (r * fadeValue / 256);
  g = (g <= 10) ? 0 : (int) g - (g * fadeValue / 256);
  b = (b <= 10) ? 0 : (int) b - (b * fadeValue / 256);
  strip.setPixelColor(ledNo, r, g, b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}
void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
}
// used by NewKITT
void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = ((NUM_LEDS - EyeSize) / 2); i >= 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    setPixel(NUM_LEDS - i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS - i - j, red, green, blue);
    }
    setPixel(NUM_LEDS - i - EyeSize - 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i <= ((NUM_LEDS - EyeSize) / 2); i++) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    setPixel(NUM_LEDS - i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS - i - j, red, green, blue);
    }
    setPixel(NUM_LEDS - i - EyeSize - 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
  for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position = 0;
  for (int i = 0; i < NUM_LEDS * 2; i++)
  {
    Position++; // = 0; //Position + Rate;
    for (int i = 0; i < NUM_LEDS; i++) {
      // sine wave, 3 offset waves make a rainbow!
      //float level = sin(i+Position) * 127 + 128;
      //setPixel(i,level,0,0);
      //float level = sin(i+Position) * 127 + 128;
      setPixel(i, ((sin(i + Position) * 127 + 128) / 255)*red,
               ((sin(i + Position) * 127 + 128) / 255)*green,
               ((sin(i + Position) * 127 + 128) / 255)*blue);
    }
    showStrip();
    delay(WaveDelay);
  }
}
void theaterChase(byte red, byte green, byte blue, int SpeedDelay) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, red, green, blue); //turn every third pixel on
      }
      showStrip();
      delay(SpeedDelay);
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, 0, 0, 0); //turn every third pixel off
      }
    }
  }
}
void theaterChaseRainbow(int SpeedDelay) {
  byte *c;
  for (int j = 0; j < 256; j++) { // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        c = Wheel( (i + j) % 255);
        setPixel(i + q, *c, *(c + 1), *(c + 2)); //turn every third pixel on
      }
      showStrip();
      delay(SpeedDelay);
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, 0, 0, 0); //turn every third pixel off
      }
    }
  }
}
// used by rainbowCycle and theaterChaseRainbow
byte * Wheel(byte WheelPos) {
  static byte c[3];
  if (WheelPos < 85) {
    c[0] = WheelPos * 3;
    c[1] = 255 - WheelPos * 3;
    c[2] = 0;
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    c[0] = 255 - WheelPos * 3;
    c[1] = 0;
    c[2] = WheelPos * 3;
  } else {
    WheelPos -= 170;
    c[0] = 0;
    c[1] = WheelPos * 3;
    c[2] = 255 - WheelPos * 3;
  }
  return c;
}
void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;
  // Step 1. Cool down every cell a little
  for ( int i = 0; i < NUM_LEDS; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
    if (cooldown > heat) {
      heat = 0;
    } else {
      heat = heat - cooldown;
    }
  }
  // Step 2. Heat from each cell drifts 'up' and diffuses a little
  for ( int k = NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
  // Step 3. Randomly ignite new 'sparks' near the bottom
  if ( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160, 255);
    //heat[y] = random(160,255);
  }
  // Step 4. Convert heat to LED colors
  for ( int j = 0; j < NUM_LEDS; j++) {
    setPixelHeatColor(j, heat[j] );
  }
  showStrip();
  delay(SpeedDelay);
}
//used by fire
void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature / 255.0) * 191);
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
  // figure out which third of the spectrum we're in:
  if ( t192 > 0x80) { // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if ( t192 > 0x40 ) { // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else { // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}
void FadeInOut(byte red, byte green, byte blue) {
  float r, g, b;
  for (int k = 0; k < 256; k = k + 1) {
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    setAll(r, g, b);
    showStrip();
  }
  for (int k = 255; k >= 0; k = k - 2) {
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    setAll(r, g, b);
    showStrip();
  }
}
void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause) {
  for (int j = 0; j < StrobeCount; j++) {
    setAll(red, green, blue);
    showStrip();
    delay(FlashDelay);
    setAll(0, 0, 0);
    showStrip();
    delay(FlashDelay);
  }
  delay(EndPause);
}
void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel, red, green, blue);
  showStrip();
  delay(SpeedDelay);
  setPixel(Pixel, 0, 0, 0);
}
void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0, 0, 0);
  for (int i = 0; i < Count; i++) {
    setPixel(random(NUM_LEDS), red, green, blue);
    showStrip();
    delay(SpeedDelay);
    if (OnlyOne) {
      setAll(0, 0, 0);
    }
  }
  delay(SpeedDelay);
}
void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0, 0, 0);
  for (int i = 0; i < Count; i++) {
    setPixel(random(NUM_LEDS), random(0, 255), random(0, 255), random(0, 255));
    showStrip();
    delay(SpeedDelay);
    if (OnlyOne) {
      setAll(0, 0, 0);
    }
  }
  delay(SpeedDelay);
}
void rainbowCycle(int SpeedDelay) {
  byte *c;
  uint16_t i, j;
  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < NUM_LEDS; i++) {
      c = Wheel(((i * 256 / NUM_LEDS) + j) & 255);
      setPixel(i, *c, *(c + 1), *(c + 2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}
// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************
// Apply LED color changes
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  FastLED.show();
#endif
}
// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
#endif
}
// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

Ok so I've ran into a strange issue. It has to do with the common functions section at the bottom of the code I believe. I'm hoping you can help me figure this out. Several functions don't work with the code, even though I've changed nothing about them except to set the colors equal to my Red, Green, and Blue variables. For example, the colorWipe function will only run once, so it'll light up the whole strip and then stop. Here is my code of the call:

    case 2  : { // color change
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(Red, Green, Blue, 25);
        colorWipe(Red, Green, Blue, 25);
        break;
      }

 and here is the function in the code:

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for (uint16_t i = 0; i < NUM_LEDS; i++) {
    setPixel(i, red, green, blue);
    showStrip();
    delay(SpeedDelay);
  }
}

If you'll notice, the "(byte red, byte green, byte blue, int SpeedDelay)" section have the red, green, and blue variables in lowercase, which match the variables in the common function section, such as the setPixels function. Yet I call them using Red, Green, Blue. If I change the call of the function back to the original it works

    case 2 : {
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(0x00, 0xff, 0x00, 50);
        colorWipe(0x00, 0x00, 0x00, 50);

which leads me to believe that something is conflicting with the following code:

void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
#endif
}

or another one of the common functions. I'm at a loss for how to make this work. Other functions such as the fire function complete freeze the program, and it doesn't appear to even reset, and none of the other buttons work either. Any ideas on how to resolve this???

Here is the current code:

#include <EEPROM.h>
#include "FastLED.h"
#include "EnableInterrupt.h" // must use this for internal interrupts
#define NUM_LEDS 20
#define PIN 7
#define EFFECT_BUTTON 3
#define COLOR_BUTTON 4
#define BRIGHTNESS_BUTTON 5
volatile byte selectedEffect = 0;
volatile byte selectedColor = 0;
volatile byte selectedBrightness = 0;
CRGB leds[NUM_LEDS];
CRGB row1[NUM_LEDS]; // array used by colorWheel function
// Color (HEX Code) Array Position
// Green (0x00, 0xFF, 0x00) 0,1,2
// GreenCyan (0x00, OxFF, 0x7F) 3,4,5
// Cyan (0x00, 0xFF, 0xFF) 6,7,8
// BlueCyan (0x00, 0x7F, 0xFF) 9,10,11
// Blue (0x00, 0x00, 0xFF) 12,13,14
// BlueMagenta (0x7F, 0x00, 0xFF) 15,16,17
// Magenta (0xFF, 0x00, 0xFF) 18,19,20
// RedMagenta (0xFF, 0x00, 0x7F) 21,22,23
// Red (0xFF, 0x00, 0x00) 24,25,26
// Orange (0xFF, 0x7F, 0x00) 27,28,29
// Yellow (0xFF, 0xFF, 0x00) 30,31,32
// GreenYellow (0x7F, 0xFF, 0x00) 33,34,35
// White (0xFF, 0xFF, 0xFF) 36,37,38
uint32_t ColorArray[] = {0x00, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF, 0xFF};
byte Red = ColorArray[0];
byte Green = ColorArray[1];
byte Blue = ColorArray[2];
void setup() {
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  pinMode (EFFECT_BUTTON, INPUT_PULLUP); // internal pull-up resistor
  pinMode (COLOR_BUTTON, INPUT_PULLUP);
  pinMode (BRIGHTNESS_BUTTON, INPUT_PULLUP);
  enableInterrupt(EFFECT_BUTTON, changeEffect, CHANGE); // EFFECT_BUTTON pressed
  enableInterrupt(COLOR_BUTTON, changeColor, CHANGE); // COLOR_BUTTON pressed
  enableInterrupt(BRIGHTNESS_BUTTON, changeBrightness, CHANGE); // BRIGHTNESS_BUTTON pressed
}
void loop() {
  EEPROM.get(0, selectedEffect);
  EEPROM.get(1, selectedColor);
  EEPROM.get(2, selectedBrightness);
  if (selectedEffect > 14) {
    selectedEffect = 0;
    EEPROM.put(0, 0);
  }
  if (selectedColor > 12) {
    selectedColor = 0;
    EEPROM.put(1, 0);
  }
  if (selectedBrightness > 4) {
    selectedBrightness = 0;
    EEPROM.put(2, 0);
  }
  switch (selectedBrightness) {
    case 0: {
        LEDS.setBrightness(10);
        break;
      }
    case 1: {
        LEDS.setBrightness(25);
        break;
      }
    case 2: {
        LEDS.setBrightness(50);
        break;
      }
    case 3: {
        LEDS.setBrightness(100);
        break;
      }
    case 4: {
        LEDS.setBrightness(150);
        break;
      }
  }
  switch (selectedColor) {
    case 0: {
        // Green
        Red = ColorArray[0];
        Green = ColorArray[1];
        Blue = ColorArray[2];
        break;
      }
    case 1: {
        // GreenCyan
        Red = ColorArray[3];
        Green = ColorArray[4];
        Blue = ColorArray[5];
        break;
      }
    case 2: {
        // Cyan
        Red = ColorArray[6];
        Green = ColorArray[7];
        Blue = ColorArray[8];
        break;
      }
    case 3: {
        // BlueCyan
        Red = ColorArray[9];
        Green = ColorArray[10];
        Blue = ColorArray[11];
        break;
      }

    case 4: {
        // Blue
        Red = ColorArray[12];
        Green = ColorArray[13];
        Blue = ColorArray[14];
        break;
      }
    case 5: {
        // BlueMagenta
        Red = ColorArray[15];
        Green = ColorArray[16];
        Blue = ColorArray[17];
        break;
      }
    case 6: {
        // Magenta
        Red = ColorArray[18];
        Green = ColorArray[19];
        Blue = ColorArray[20];
        break;
      }
    case 7: {
        // RedMagenta
        Red = ColorArray[21];
        Green = ColorArray[22];
        Blue = ColorArray[23];
        break;
      }
    case 8: {
        // Red
        Red = ColorArray[24];
        Green = ColorArray[25];
        Blue = ColorArray[26];
        break;
      }
    case 9: {
        // Orange
        Red = ColorArray[27];
        Green = ColorArray[28];
        Blue = ColorArray[29];
        break;
      }
    case 10: {
        // Yellow
        Red = ColorArray[30];
        Green = ColorArray[31];
        Blue = ColorArray[32];
        break;
      }
    case 11: {
        // YellowGreen
        Red = ColorArray[33];
        Green = ColorArray[34];
        Blue = ColorArray[35];
        break;
      }
    case 12: {
        // White
        Red = ColorArray[36];
        Green = ColorArray[37];
        Blue = ColorArray[38];
      }
  }
  switch (selectedEffect) {
    case 0 : { // color change
        fill_solid( leds, NUM_LEDS, CRGB(Red, Green, Blue) );
        FastLED.show();
        break;
      }
    case 1 : { // color change
        setColorWheelColors(Red, Green, Blue);
        // speed delay
        colorWheel(50);
        break;
      }
    case 2 : { // color change
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(Red, Green, Blue, 25);
        colorWipe(Red, Green, Blue, 25);
        break;
      }
    case 3 : { // no color change
        // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
        meteorRain(0xff, 0xff, 0xff, 1, 80, true, 25);
        //meteorRain(Red, Green, Blue, 1, 80, true, 25);
        break;
      }
    case 4 : { // color change
        // NewKITT - Color (red, green, blue), eye size, speed delay, end pause
        NewKITT(Red, Green, Blue, 8, 10, 50);
        break;
      }
    case 5 : { // color change
        // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
        CylonBounce(Red, Green, Blue, 4, 10, 50);
        break;
      }
    case 6 : { // no color change
        // Running Lights - Color (red, green, blue), wave dealy
        RunningLights(0xff, 0x00, 0x00, 50); // red
        RunningLights(0xff, 0xff, 0xff, 50); // white
        RunningLights(0x00, 0x00, 0xff, 50); // blue
        break;
      }
    case 7 : { // color change
        // theatherChase - Color (red, green, blue), speed delay
        theaterChase(Red, Green, Blue, 50);
        break;
      }
    case 8 : { // no color change
        // Fire - Cooling rate, Sparking rate, speed delay
        Fire(55, 120, 15);
        break;
      }
    case 9 : { // no color change
        // FadeInOut - Color (red, green, blue)
        FadeInOut(0xff, 0x00, 0x00); // red
        FadeInOut(0xff, 0xff, 0xff); // green
        FadeInOut(0x00, 0x00, 0xff); // blue
        break;
      }
    case 10 : { // color change
        // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
        Strobe(Red, Green, Blue, 10, 50, 1000);
        break;
      }
    case 11 : { // color change
        // Sparkle - Color (red, green, blue), speed delay
        Sparkle(Red, Green, Blue, 0);
        break;
      }
    case 12 : { // color change
        // Twinkle - Color (red, green, blue), count, speed delay, only one twinkle (true/false)
        Twinkle(Red, Green, Blue, 10, 100, false);
        break;
      }
    case 13 : { // no color change
        // TwinkleRandom - twinkle count, speed delay, only one (true/false)
        TwinkleRandom(20, 100, false);
        break;
      }
    case 14 : { // no color change
        // rainbowCycle - speed delay
        rainbowCycle(20);
        break;
      }
  }
}
void changeEffect() {
  if (digitalRead (EFFECT_BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect);
    asm volatile (" jmp 0");
  }
}
void changeColor() {
  if (digitalRead (COLOR_BUTTON) == HIGH) {
    selectedColor++;
    EEPROM.put(1, selectedColor);
    asm volatile (" jmp 0");
  }
}
void changeBrightness() {
  if (digitalRead (BRIGHTNESS_BUTTON) == HIGH) {
    selectedBrightness++;
    EEPROM.put(2, selectedBrightness);
    asm volatile (" jmp 0");
  }
}
// *************************
// ** LEDEffect Functions **
// *************************
void setColorWheelColors(byte red, byte green, byte blue) {
  row1[0] = CRGB(Red, Green, Blue);
  row1[1] = CRGB(Red, Green, Blue);
  row1[2] = CRGB(Red, Green, Blue);
  row1[3] = CRGB::Black;
  row1[4] = CRGB::Black;
  row1[5] = CRGB::Black;
  row1[6] = CRGB::Black;
  row1[7] = CRGB::Black;
  row1[8] = CRGB::Black;
  row1[9] = CRGB::Black;
  row1[10] = CRGB::Black;
  row1[11] = CRGB::Black;
  row1[12] = CRGB(Red, Green, Blue);
  row1[13] = CRGB(Red, Green, Blue);
  row1[14] = CRGB(Red, Green, Blue);
  row1[15] = CRGB::Black;
  row1[16] = CRGB::Black;
  row1[17] = CRGB::Black;
  row1[18] = CRGB::Black;
  row1[19] = CRGB::Black;
  row1[20] = CRGB::Black;
}
void colorWheel(int SpeedDelay) {
  for (int j = 0; j < NUM_LEDS; j++) {
    assignTo(j);
    FastLED.show();
    delay(SpeedDelay);
  }
}
//used by colorWheel
void assignTo(int j) {
  int i;
  for (i = 0; i < NUM_LEDS; i++)
  {
    leds = row1[(i + j) % NUM_LEDS];
  }
}
void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for (uint16_t i = 0; i < NUM_LEDS; i++) {
    setPixel(i, red, green, blue);
    showStrip();
    delay(SpeedDelay);
  }
}
void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
  setAll(0, 0, 0);
  for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {

    // fade brightness all LEDs one step
    for (int j = 0; j < NUM_LEDS; j++) {
      if ( (!meteorRandomDecay) || (random(10) > 5) ) {
        fadeToBlack(j, meteorTrailDecay );
      }
    }
    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
        setPixel(i - j, red, green, blue);
      }
    }
    showStrip();
    delay(SpeedDelay);
  }
}
// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  uint32_t oldColor;
  uint8_t r, g, b;
  int value;
  oldColor = strip.getPixelColor(ledNo);
  r = (oldColor & 0x00ff0000UL) >> 16;
  g = (oldColor & 0x0000ff00UL) >> 8;
  b = (oldColor & 0x000000ffUL);
  r = (r <= 10) ? 0 : (int) r - (r * fadeValue / 256);
  g = (g <= 10) ? 0 : (int) g - (g * fadeValue / 256);
  b = (b <= 10) ? 0 : (int) b - (b * fadeValue / 256);
  strip.setPixelColor(ledNo, r, g, b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}
void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
}
// used by NewKITT
void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = ((NUM_LEDS - EyeSize) / 2); i >= 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    setPixel(NUM_LEDS - i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS - i - j, red, green, blue);
    }
    setPixel(NUM_LEDS - i - EyeSize - 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i <= ((NUM_LEDS - EyeSize) / 2); i++) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    setPixel(NUM_LEDS - i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS - i - j, red, green, blue);
    }
    setPixel(NUM_LEDS - i - EyeSize - 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
  for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, red / 10, green / 10, blue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, red, green, blue);
    }
    setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position = 0;
  for (int i = 0; i < NUM_LEDS * 2; i++)
  {
    Position++; // = 0; //Position + Rate;
    for (int i = 0; i < NUM_LEDS; i++) {
      // sine wave, 3 offset waves make a rainbow!
      //float level = sin(i+Position) * 127 + 128;
      //setPixel(i,level,0,0);
      //float level = sin(i+Position) * 127 + 128;
      setPixel(i, ((sin(i + Position) * 127 + 128) / 255)*red,
               ((sin(i + Position) * 127 + 128) / 255)*green,
               ((sin(i + Position) * 127 + 128) / 255)*blue);
    }
    showStrip();
    delay(WaveDelay);
  }
}
void theaterChase(byte red, byte green, byte blue, int SpeedDelay) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, red, green, blue); //turn every third pixel on
      }
      showStrip();
      delay(SpeedDelay);
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, 0, 0, 0); //turn every third pixel off
      }
    }
  }
}
void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;
  // Step 1. Cool down every cell a little
  for ( int i = 0; i < NUM_LEDS; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
    if (cooldown > heat) {
      heat = 0;
    } else {
      heat = heat - cooldown;
    }
  }
  // Step 2. Heat from each cell drifts 'up' and diffuses a little
  for ( int k = NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
  // Step 3. Randomly ignite new 'sparks' near the bottom
  if ( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160, 255);
    //heat[y] = random(160,255);
  }
  // Step 4. Convert heat to LED colors
  for ( int j = 0; j < NUM_LEDS; j++) {
    setPixelHeatColor(j, heat[j] );
  }
  showStrip();
  delay(SpeedDelay);
}
//used by fire
void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature / 255.0) * 191);
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
  // figure out which third of the spectrum we're in:
  if ( t192 > 0x80) { // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if ( t192 > 0x40 ) { // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else { // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}
void FadeInOut(byte red, byte green, byte blue) {
  float r, g, b;
  for (int k = 0; k < 256; k = k + 1) {
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    setAll(r, g, b);
    showStrip();
  }
  for (int k = 255; k >= 0; k = k - 2) {
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    setAll(r, g, b);
    showStrip();
  }
}
void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause) {
  for (int j = 0; j < StrobeCount; j++) {
    setAll(red, green, blue);
    showStrip();
    delay(FlashDelay);
    setAll(0, 0, 0);
    showStrip();
    delay(FlashDelay);
  }
  delay(EndPause);
}
void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel, red, green, blue);
  showStrip();
  delay(SpeedDelay);
  setPixel(Pixel, 0, 0, 0);
}
void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0, 0, 0);
  for (int i = 0; i < Count; i++) {
    setPixel(random(NUM_LEDS), red, green, blue);
    showStrip();
    delay(SpeedDelay);
    if (OnlyOne) {
      setAll(0, 0, 0);
    }
  }
  delay(SpeedDelay);
}
void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0, 0, 0);
  for (int i = 0; i < Count; i++) {
    setPixel(random(NUM_LEDS), random(0, 255), random(0, 255), random(0, 255));
    showStrip();
    delay(SpeedDelay);
    if (OnlyOne) {
      setAll(0, 0, 0);
    }
  }
  delay(SpeedDelay);
}
void rainbowCycle(int SpeedDelay) {
  byte *c;
  uint16_t i, j;
  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < NUM_LEDS; i++) {
      c = Wheel(((i * 256 / NUM_LEDS) + j) & 255);
      setPixel(i, *c, *(c + 1), *(c + 2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}
// used by rainbowCycle
byte * Wheel(byte WheelPos) {
  static byte c[3];
  if (WheelPos < 85) {
    c[0] = WheelPos * 3;
    c[1] = 255 - WheelPos * 3;
    c[2] = 0;
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    c[0] = 255 - WheelPos * 3;
    c[1] = 0;
    c[2] = WheelPos * 3;
  } else {
    WheelPos -= 170;
    c[0] = 0;
    c[1] = WheelPos * 3;
    c[2] = 255 - WheelPos * 3;
  }
  return c;
}
// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************
// Apply LED color changes
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  FastLED.show();
#endif
}
// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
#endif
}
// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2859
Topic starter  

Hi Troy,

it's a lot of code and text to work through 

  • First observation; what model Arduino are you using? If it's a Uno (most common), then this wouldn't work properly;
#define EFFECT_BUTTON 3
#define COLOR_BUTTON 4

and should probably be

#define EFFECT_BUTTON 2
#define COLOR_BUTTON 3

The Uno only has pin 2 and 3 for interrupts available. Unless of course you're using another model else.

  • Second point, I see you using an unsigned 32 bit integer for your colors array - this should probably be byte.

When using the 32 bit integer, you actually have 4 bytes per number, where you only intend to have 1 byte.

byte ColorArray[] = {0x00, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF, 0xFF};
byte Red = ColorArray[0];
byte Green = ColorArray[1];
byte Blue = ColorArray[2];

Assigning the initial colors, I'd move to "setup()". Your method may work, I just think it's cleaner this way. So;

byte Red = ColorArray[0];
byte Green = ColorArray[1];
byte Blue = ColorArray[2];
void setup() {
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
... // etc

becomes

  byte Red;
  byte Green;
  byte Blue;
void setup() {
  Red = ColorArray[0];
  Green = ColorArray[1];
  Blue = ColorArray[2];
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
... // etc

  • Third point; Global vs Local variables
See also: Variable Scope.
Personally I like to make a better distinction between global variables and local variables.
So the red, green, blue variables in the functions are local variables, and only used and seen in that particular function.
There is no connection with same named variables outside of the function.
Your Red, Green, Blue are global variables, and known anywhere in the sketch, unless a function defines its own local Red, Green, Blue - then these local variables will dominate.
For this reason, I like using different names for those global variables, for example gRed, globalRed or selectedRed.
This makes code easier to read and will avoid confusion.
Note : Since the common functions in my code are working properly in all other scenarios, I think it's safe to assume (unless you modified them) that they will work. I do not mean to say that my code is perfect, but it has been working for others.

  • Reading the EEPROM

This could be an improvement over my own code! 

Reading your code (and my own), I just realized that reading the EEPROM value may also be done at the end of the "setup()" function, since pressing a button interrupts the program, sets the EEPROM and the fully resets the Arduino. Meaning: setup() will be called again.

so

  EEPROM.get(0, selectedEffect);
  EEPROM.get(1, selectedColor);
  if (selectedEffect > 15) {
    selectedEffect = 0;
    EEPROM.put(0, 0);
  }
  if (selectedColor > 12) {
    selectedColor = 0;
    EEPROM.put(1, 0);
  }

could maybe be moved out of the beginning of "loop()" to the end of "setup()". I'm not sure if there was a specific reason why I placed it in the loop(). Worth a test!

Just a start ... maybe you'd like to play with this and let me know your findings 


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

I'm using a metro mini to test the code. However this is what i'm talking about when I say i'm using internal interrupts. I should be saying pin change interrupts.

I've been playing with the code today and made your suggested changes where I could. I'm not able to put the Red, Green, Blue variables in the setup function, it throws an error saying that the those variables in the code below haven't been declared in the scope. 
It appears I wasn't being thorough before when I added the color change code. I had been up all night and wasn't properly checking to make sure all the functions would working properly, which is why I didn't notice the issue until much later when I THOUGHT I had the project done. After removing both the color change and brightness code your functions worked as expected. As soon as the color change code things start to get weird. Reading the serial port shows some interesting things happening. It seems the EEPROM.get or EEPROM.put is whipping out the values for the selectedColor and selectedBrightness variables, but only once the selectedEffect value is equal to 1  the other issue though is that for whatever reason SEVERAL of the functions don't work properly with the introduction of the new code. I can't for the life of me understand how it would affect them though. 
I'll keep debugging but do you have any idea what could be going on? Why would the colorWipe function for example stop looping because of the color change code??? It doesn't make any sense. 

   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

To add to this, I thought I should mention that some of the functions completely freeze the program, in that the leds will freeze in place and the button clicks do nothing. I thought the asm volatile (" jmp 0"); FORCED the board to rebot?


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

It appears what is breaking the code is 

enableInterrupt(COLOR_BUTTON, changeColor, CHANGE); // COLOR_BUTTON pressed

even if I have both buttons set to pins 2 and 3, it doesn't matter. The functions stop working as they should from this one line. Even when I remove the #include "EnableInterrupt.h" library and use the following code from your project

attachInterrupt (digitalPinToInterrupt (COLOR_BUTTON), changeEffect, CHANGE); // pressed

it still causes the functions/code to break. It would appear i'm unable to even add a section interrupt.... 


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

Ok so after playing with this today I was able to find a solution (sort of). For whatever reason some of the functions in your all in one code just refuse to work with the additional interrupts. What I did was remove the offending functions and keep the ones that work. At the moment I've got 11 effects. I'm going to try and add a few more eventually. However I was able to figure out a way around the EEPROM.put wiping my values. I think it has to do with the fact that .put removes values that are different, and for whatever reason it doesn't want to respect the address of each variable. So I simply changed the code at the startup to EEPROM.write.

if (selectedEffect > 11) {    selectedEffect = 0;    EEPROM.write(0, 0);  }  if (selectedColor > 12) {    selectedColor = 0;    EEPROM.write(1, 0);  }  if (selectedBrightness > 4) {    selectedBrightness = 0;    EEPROM.write(2, 0);  }
I understand the reasoning behind using .get and .put is to reduce the read/write operations and extend the life of each address on the EEPROM. However I believe in this case its a mute point because these values in the code above are only written when their out of range and in any case they would be written regardless of using .put or .write, except now it doesn't clear previous values! Some of the functions that refused to work were colorWipe, RunningLights, theaterChase, and theaterChaseRainbow, I also excluded a few effects before the start of this project so I'm unsure if they would work or not.

   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

Ok so after playing with this today I was able to find a solution (sort of). For whatever reason some of the functions in your all in one code just refuse to work with the additional interrupts. What I did was remove the offending functions and keep the ones that work. At the moment I've got 11 effects. I'm going to try and add a few more eventually. However I was able to figure out a way around the EEPROM.put wiping my values. I think it has to do with the fact that .put removes values that are different, and for whatever reason it doesn't want to respect the address of each variable. So I simply changed the code at the startup to EEPROM.write.

if (selectedEffect > 11) { selectedEffect = 0; EEPROM.write(0, 0); } if (selectedColor > 12) { selectedColor = 0; EEPROM.write(1, 0); } if (selectedBrightness > 4) { selectedBrightness = 0; EEPROM.write(2, 0); }

I understand the reasoning behind using .get and .put is to reduce the read/write operations and extend the life of each address on the EEPROM. However I believe in this case its a mute point because these values in the code above are only written when their out of range and in any case they would be written regardless of using .put or .write, except now it doesn't clear previous values! Some of the functions that refused to work were colorWipe, RunningLights, theaterChase, and theaterChaseRainbow, I also excluded a few effects before the start of this project so I'm unsure if they would work or not.


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2859
Topic starter  
  • EEPROM values

I'll have to spend more time reading all the details you just posted, but one thing I noticed is that you made your byte variables volatile ...?

volatile byte selectedEffect = 0;
volatile byte selectedColor = 0;
volatile bool effect_changed = false;
volatile bool color_changed = false;

I'm not sure if this had a good reason, but it effectively will force a byte to become 2 bytes.
I just read something in the attachInterrupt documentation, so I assume this is where you read this as well.
Since we do not change the variable only in that function, I don't think we need to define it as volatile..

If I understand the volatile documentation correctly, this means that when you write to the EEPROM, you'll write 2 bytes instead of just one.

This can result in one of 2 problems;

1) the 2nd byte overwrites the next EEPROM slot
2) only one of two bytes is stored, and it may or may not be the insignificant one of the 2 bytes.

EEPROM only reads/writes 1 byte.
I haven't had enough coffee yet, so I may be swapping the values. But as an example, say you want to store the value "1", in two bytes this is 00 01. Storing this in a one byte slot, could later read as 00 or 01. So you can't rely on that going well. 

So ... either not use volatile, or jump by 2 bytes when writing/reading values.
Eg. EEPROM.write(0, 0) for effect, EEPROM.write(2, 0) for brightness, EEPROM.write(4, 0) for color (like you did in your last post).

I'd change those 4 lines to:

byte selectedEffect = 0;
byte selectedColor = 0;
bool effect_changed = false;
bool color_changed = false;

  • Failing functions: colorWipe, RunningLights, theaterChase, and theaterChaseRainbow

Oh that's interesting. Let's look at colorWipe.
This is probably the simplest function in the list;

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for(uint16_t i=0; i<NUM_LEDS; i++) {
      setPixel(i, red, green, blue);
      showStrip();
      delay(SpeedDelay);
  }
}

It is a little confusing that a simple function like that fails. 
Glancing over this article, you could try adding before "#include <FastLED.h> ";

#define FASTLED_ALLOW_INTERRUPTS 0

I'm not sure if this will have consequences ... I still need more coffee 


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

I changed my variables from volatile byte to byte but it didn't change how the EEPROM.put was overwriting the values. I had tried changing the addresses as well and still the same result. Forwhatever reason EEPROM.write seems to be the only thing that works.

I made the suggested changes using  
#define FASTLED_ALLOW_INTERRUPTS 0
before the FastLED library but it didn't change anything. colorWipe still refuses to loop, it only plays once and then the LEDs just sit there full lit....very strange indeed 

   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

Ok so here is the weird thing, colorWipe works when I change the call from 

case 12 : {
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(gRed, gGreen, gBlue, 50);
        colorWipe(gRed, gGreen, gBlue, 50);
        break;
      }

to

case 12 : {
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(0x00, 0xff, 0x00, 50);
        colorWipe(0x00, 0x00, 0x00, 50);
        break;
      }

I didn't change the function within the program, so the first call works, here is the function within my code that has it working: 

void colorWipe(byte gRed, byte gGreen, byte gBlue, int SpeedDelay) {
  for (uint16_t i = 0; i < NUM_LEDS; i++) {
    setPixel(i, gRed, gGreen, gBlue);
    showStrip();
    delay(SpeedDelay);
  }

So whatever is causing these functions to fail has to do with the function calls rather then the functions themselves, which would make sense given I haven't changed the functions. However I can't seem to understand the conflict regardless. The other functions work fine....  


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

Actually I think I just figured it out, I didn't realize that the second call of the function is turning the leds off!!!

colorWipe(0x00, 0x00, 0x00, 50);

so if I leave that line alone then the function works. I'm going to work on debugging the other two functions knowing what I know now, however they were acting different since they were freezing the program or causing the buttons to be unresponsive. I haven't tested those functions or the  #define FASTLED_ALLOW_INTERRUPTS 0 with those functions yet so maybe there is still hope! 


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

I've been working on debugging theaterChase and i'm completely confused by the function. Regardless of how I call the function it still presents weird behavior. I tried all of the previously mentioned things but its not consistent on how it acts, which is rather odd. I think something in the function is conflicting with the code. Sometimes it will switch between cases, but usually it freezes on the part of the function that lights up every third led. However color changes will work with it, so if I load up the program while selectedEffect equals its case it will run and I can change colors. It breaks down on trying to switch between functions. Sometimes it would work if I pressed the button several times very fast but again, I can't get it to act consistently     


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2859
Topic starter  

Just something I just noticed, not necessarily cause of any problems you're experiencing;
Maybe you overlooked the definition of the "ColorArray". I know I did 
You've assigned it a uint32_t type, where it should be byte.

uint32_t ColorArray[] = {0x00, ... 0xFF}; // should be: BYTE
byte Red = ColorArray[0];

Maybe this was a leftover of earlier attempts where you wanted to store an color set (RGB = 32bit) as one value, versus separate red, green and blue (each a byte).
Since you assigned it an array of an integer type, the byte (for example 0x00) will be stored as a 32 bit integer (0x00000000).
Pulling an element as a byte, (byte Red = ColorArray[0];) will pull only the first byte of the 4 bytes you've stored.

Since the function theaterChase() is relatively "simple", I can't come up with scenarios where this is going sideways. Something else is interfering.
The odd part is that other, equally "simple" functions appear unaffected.

Another observation;  I don't know where "CRGB row1[NUM_LEDS]; // array used by colorWheel function" came from ...
Is it a leftover from debugging? I'm not sure there is a need for it.

If I'd be debugging this code (I don't have my Arduino and LED strips handy), then I'd start by going back to the original code.
Sometimes it's good to start over (I do this quite often hahah).
Test if that works OK.

Then add the saving of selectedColor - you could even make a sketch that just toggles the EEPROM values, without any LED functions, just to see and follow what is happening there. Testing functions in small sketches, just for that specific function, is the way to go when things become complex or unexplainable things happen ...


   
ReplyQuote
(@troy89)
Active Member
Joined: 6 years ago
Posts: 13
 

The “CRGB row1[NUM_LEDS]; // array used by colorWheel function” is used in the following code 

void setColorWheelColors(byte gRed, byte gGreen, byte gBlue) {
  row1[0] = CRGB(gRed, gGreen, gBlue);
  row1[1] = CRGB(gRed, gGreen, gBlue);
  row1[2] = CRGB(gRed, gGreen, gBlue);
  row1[3] = CRGB::Black;
  row1[4] = CRGB::Black;
  row1[5] = CRGB::Black;
  row1[6] = CRGB::Black;
  row1[7] = CRGB::Black;
  row1[8] = CRGB::Black;
  row1[9] = CRGB::Black;
  row1[10] = CRGB::Black;
  row1[11] = CRGB::Black;
  row1[12] = CRGB(gRed, gGreen, gBlue);
  row1[13] = CRGB(gRed, gGreen, gBlue);
  row1[14] = CRGB(gRed, gGreen, gBlue);
  row1[15] = CRGB::Black;
  row1[16] = CRGB::Black;
  row1[17] = CRGB::Black;
  row1[18] = CRGB::Black;
  row1[19] = CRGB::Black;
  row1[20] = CRGB::Black;
}

I believe you're looking at older code. Here is my current working version as I've made that ColorArray change.

Here is my working code:

#include <EEPROM.h>
#include "FastLED.h"
#include "EnableInterrupt.h" // must use this for internal interrupts
#define NUM_LEDS 20
#define PIN 6
#define EFFECT_BUTTON 3
#define COLOR_BUTTON 4
#define BRIGHTNESS_BUTTON 5
CRGB leds[NUM_LEDS];
CRGB row1[NUM_LEDS]; // array used by colorWheel function
// Color (HEX Code) Array Position
// gGreen (0x00, 0xFF, 0x00) 0,1,2
// gGreenCyan (0x00, OxFF, 0x7F) 3,4,5
// Cyan (0x00, 0xFF, 0xFF) 6,7,8
// gBlueCyan (0x00, 0x7F, 0xFF) 9,10,11
// gBlue (0x00, 0x00, 0xFF) 12,13,14
// gBlueMagenta (0x7F, 0x00, 0xFF) 15,16,17
// Magenta (0xFF, 0x00, 0xFF) 18,19,20
// gRedMagenta (0xFF, 0x00, 0x7F) 21,22,23
// gRed (0xFF, 0x00, 0x00) 24,25,26
// Orange (0xFF, 0x7F, 0x00) 27,28,29
// Yellow (0xFF, 0xFF, 0x00) 30,31,32
// gGreenYellow (0x7F, 0xFF, 0x00) 33,34,35
// White (0xFF, 0xFF, 0xFF) 36,37,38
byte ColorArray[] = {0x00, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF, 0xFF};
byte gRed = ColorArray[0];
byte gGreen = ColorArray[1];
byte gBlue = ColorArray[2];
byte selectedEffect = 0;
byte selectedColor = 0;
byte selectedBrightness = 0;
void setup() {
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  pinMode (EFFECT_BUTTON, INPUT_PULLUP); // internal pull-up resistor
  pinMode (COLOR_BUTTON, INPUT_PULLUP);
  pinMode (BRIGHTNESS_BUTTON, INPUT_PULLUP);
  enableInterrupt(EFFECT_BUTTON, changeEffect, CHANGE); // EFFECT_BUTTON pressed
  enableInterrupt(COLOR_BUTTON, changeColor, CHANGE); // COLOR_BUTTON pressed
  enableInterrupt(BRIGHTNESS_BUTTON, changeBrightness, CHANGE); // BRIGHTNESS_BUTTON pressed
  EEPROM.get(0, selectedEffect);
  EEPROM.get(1, selectedColor);
  EEPROM.get(2, selectedBrightness);
  if (selectedEffect > 12) {
    selectedEffect = 0;
    EEPROM.write(0, 0);
  }
  if (selectedColor > 12) {
    selectedColor = 0;
    EEPROM.write(1, 0);
  }
  if (selectedBrightness > 4) {
    selectedBrightness = 0;
    EEPROM.write(2, 0);
  }
}
void loop() {
  switch (selectedBrightness) {
    case 0: {
        LEDS.setBrightness(10);
        break;
      }
    case 1: {
        LEDS.setBrightness(25);
        break;
      }
    case 2: {
        LEDS.setBrightness(50);
        break;
      }
    case 3: {
        LEDS.setBrightness(100);
        break;
      }
    case 4: {
        LEDS.setBrightness(150);
        break;
      }
  }
  switch (selectedColor) {
    case 0: {
        // gGreen
        gRed = ColorArray[0];
        gGreen = ColorArray[1];
        gBlue = ColorArray[2];
        break;
      }
    case 1: {
        // gGreenCyan
        gRed = ColorArray[3];
        gGreen = ColorArray[4];
        gBlue = ColorArray[5];
        break;
      }
    case 2: {
        // Cyan
        gRed = ColorArray[6];
        gGreen = ColorArray[7];
        gBlue = ColorArray[8];
        break;
      }
    case 3: {
        // gBlueCyan
        gRed = ColorArray[9];
        gGreen = ColorArray[10];
        gBlue = ColorArray[11];
        break;
      }
    case 4: {
        // gBlue
        gRed = ColorArray[12];
        gGreen = ColorArray[13];
        gBlue = ColorArray[14];
        break;
      }
    case 5: {
        // gBlueMagenta
        gRed = ColorArray[15];
        gGreen = ColorArray[16];
        gBlue = ColorArray[17];
        break;
      }
    case 6: {
        // Magenta
        gRed = ColorArray[18];
        gGreen = ColorArray[19];
        gBlue = ColorArray[20];
        break;
      }
    case 7: {
        // gRedMagenta
        gRed = ColorArray[21];
        gGreen = ColorArray[22];
        gBlue = ColorArray[23];
        break;
      }
    case 8: {
        // gRed
        gRed = ColorArray[24];
        gGreen = ColorArray[25];
        gBlue = ColorArray[26];
        break;
      }
    case 9: {
        // Orange
        gRed = ColorArray[27];
        gGreen = ColorArray[28];
        gBlue = ColorArray[29];
        break;
      }
    case 10: {
        // Yellow
        gRed = ColorArray[30];
        gGreen = ColorArray[31];
        gBlue = ColorArray[32];
        break;
      }
    case 11: {
        // YellowgGreen
        gRed = ColorArray[33];
        gGreen = ColorArray[34];
        gBlue = ColorArray[35];
        break;
      }
    case 12: {
        // White
        gRed = ColorArray[36];
        gGreen = ColorArray[37];
        gBlue = ColorArray[38];
      }
  }
  switch (selectedEffect) {
    case 0 : { // color change
        fill_solid( leds, NUM_LEDS, CRGB(gRed, gGreen, gBlue) );
        FastLED.show();
        break;
      }
    case 1 : { // color change
        setColorWheelColors(gRed, gGreen, gBlue);
        // speed delay
        colorWheel(50);
        break;
      }
    case 2 : {
        // colorWipe - Color (red, green, blue), speed delay
        colorWipe(gRed, gGreen, gBlue, 35);
        colorWipe(0x00, 0x00, 0x00, 35); //turn leds off
        break;
      }
    case 3 : { // color change
        // CylonBounce - Color (gRed, gGreen, gBlue), eye size, speed delay, end pause
        CylonBounce(gRed, gGreen, gBlue, 3, 20, 0);
        break;
      }
    case 4 : { // color change
        // NewKITT - Color (gRed, gGreen, gBlue), eye size, speed delay, end pause
        NewKITT(gRed, gGreen, gBlue, 3, 20, 50);
        break;
      }
    case 5 : { // no color change
        // meteorRain - Color (gRed, gGreen, gBlue), meteor size, trail decay, random trail decay (true/false), speed delay
        meteorRain(0xff, 0xff, 0xff, 1, 80, true, 25);
        //meteorRain(gRed, gGreen, gBlue, 1, 80, true, 25);
        break;
      }
    case 6 : { // no color change
        // Fire - Cooling rate, Sparking rate, speed delay 55,120,15
        Fire(55, 120, 25);
        break;
      }
    case 7 : { // no color change
        // FadeInOut - Color (Red, Green, Blue)
        FadeInOut(0x00, 0x00, 0xFF); // Blue
        FadeInOut(0xFF, 0x7F, 0x00); // Orange
        FadeInOut(0x00, 0xFF, 0x00); // Green
        break;
      }
    case 8 : { // color change
        // Strobe - Color (gRed, gGreen, gBlue), number of flashes, flash speed, end pause
        Strobe(gRed, gGreen, gBlue, 10, 50, 750);
        break;
      }
    case 9 : { // color change
        // Sparkle - Color (gRed, gGreen, gBlue), speed delay
        Sparkle(gRed, gGreen, gBlue, 0);
        break;
      }
    case 10 : { // color change
        // Twinkle - Color (gRed, gGreen, gBlue), count, speed delay, only one twinkle (true/false)
        Twinkle(gRed, gGreen, gBlue, 10, 100, false);
        break;
      }
    case 11 : { // no color change
        // TwinkleRandom - twinkle count, speed delay, only one (true/false)
        TwinkleRandom(20, 100, false);
        break;
      }
    case 12 : { // no color change
        // rainbowCycle - speed delay
        rainbowCycle(20);
        break;
      }
  }
}
void changeEffect() {
  if (digitalRead (EFFECT_BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect);
    asm volatile (" jmp 0");
  }
}
void changeColor() {
  if (digitalRead (COLOR_BUTTON) == HIGH) {
    selectedColor++;
    EEPROM.put(1, selectedColor);
    asm volatile (" jmp 0");
  }
}
void changeBrightness() {
  if (digitalRead (BRIGHTNESS_BUTTON) == HIGH) {
    selectedBrightness++;
    EEPROM.put(2, selectedBrightness);
    asm volatile (" jmp 0");
  }
}
// *************************
// ** LEDEffect Functions **
// *************************
void setColorWheelColors(byte gRed, byte gGreen, byte gBlue) {
  row1[0] = CRGB(gRed, gGreen, gBlue);
  row1[1] = CRGB(gRed, gGreen, gBlue);
  row1[2] = CRGB(gRed, gGreen, gBlue);
  row1[3] = CRGB::Black;
  row1[4] = CRGB::Black;
  row1[5] = CRGB::Black;
  row1[6] = CRGB::Black;
  row1[7] = CRGB::Black;
  row1[8] = CRGB::Black;
  row1[9] = CRGB::Black;
  row1[10] = CRGB::Black;
  row1[11] = CRGB::Black;
  row1[12] = CRGB(gRed, gGreen, gBlue);
  row1[13] = CRGB(gRed, gGreen, gBlue);
  row1[14] = CRGB(gRed, gGreen, gBlue);
  row1[15] = CRGB::Black;
  row1[16] = CRGB::Black;
  row1[17] = CRGB::Black;
  row1[18] = CRGB::Black;
  row1[19] = CRGB::Black;
  row1[20] = CRGB::Black;
}
void colorWheel(int SpeedDelay) {
  for (int j = 0; j < NUM_LEDS; j++) {
    assignTo(j);
    //FastLED.show();
    showStrip();
    delay(SpeedDelay);
  }
}
//used by colorWheel
void assignTo(int j) {
  int i;
  for (i = 0; i < NUM_LEDS; i++)
  {
    leds = row1[(i + j) % NUM_LEDS];
  }
}
void colorWipe(byte gRed, byte gGreen, byte gBlue, int SpeedDelay) {
  for (uint16_t i = 0; i < NUM_LEDS; i++) {
    setPixel(i, gRed, gGreen, gBlue);
    showStrip();
    delay(SpeedDelay);
  }
}
void meteorRain(byte gRed, byte gGreen, byte gBlue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
  setAll(0, 0, 0);
  for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {

    // fade brightness all LEDs one step
    for (int j = 0; j < NUM_LEDS; j++) {
      if ( (!meteorRandomDecay) || (random(10) > 5) ) {
        fadeToBlack(j, meteorTrailDecay );
      }
    }
    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
        setPixel(i - j, gRed, gGreen, gBlue);
      }
    }
    showStrip();
    delay(SpeedDelay);
  }
}
// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  uint32_t oldColor;
  uint8_t R, G, B;
  int value;
  oldColor = strip.getPixelColor(ledNo);
  R = (oldColor & 0x00ff0000UL) >> 16;
  G = (oldColor & 0x0000ff00UL) >> 8;
  B = (oldColor & 0x000000ffUL);
  R = (R <= 10) ? 0 : (int) R - (R * fadeValue / 256);
  G = (G <= 10) ? 0 : (int) G - (G * fadeValue / 256);
  B = (B <= 10) ? 0 : (int) B - (B * fadeValue / 256);
  strip.setPixelColor(ledNo, R, G, B);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}
void NewKITT(byte gRed, byte gGreen, byte gBlue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  RightToLeft(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  RightToLeft(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(gRed, gGreen, gBlue, EyeSize, SpeedDelay, ReturnDelay);
}
// used by NewKITT
void CenterToOutside(byte gRed, byte gGreen, byte gBlue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = ((NUM_LEDS - EyeSize) / 2); i >= 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, gRed, gGreen, gBlue);
    }
    setPixel(i + EyeSize + 1, gRed / 10, gGreen / 10, gBlue / 10);
    setPixel(NUM_LEDS - i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS - i - j, gRed, gGreen, gBlue);
    }
    setPixel(NUM_LEDS - i - EyeSize - 1, gRed / 10, gGreen / 10, gBlue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void OutsideToCenter(byte gRed, byte gGreen, byte gBlue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i <= ((NUM_LEDS - EyeSize) / 2); i++) {
    setAll(0, 0, 0);
    setPixel(i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, gRed, gGreen, gBlue);
    }
    setPixel(i + EyeSize + 1, gRed / 10, gGreen / 10, gBlue / 10);
    setPixel(NUM_LEDS - i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS - i - j, gRed, gGreen, gBlue);
    }
    setPixel(NUM_LEDS - i - EyeSize - 1, gRed / 10, gGreen / 10, gBlue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void LeftToRight(byte gRed, byte gGreen, byte gBlue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
    setAll(0, 0, 0);
    setPixel(i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, gRed, gGreen, gBlue);
    }
    setPixel(i + EyeSize + 1, gRed / 10, gGreen / 10, gBlue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
// used by NewKITT
void RightToLeft(byte gRed, byte gGreen, byte gBlue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, gRed, gGreen, gBlue);
    }
    setPixel(i + EyeSize + 1, gRed / 10, gGreen / 10, gBlue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
void CylonBounce(byte gRed, byte gGreen, byte gBlue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
    setAll(0, 0, 0);
    setPixel(i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, gRed, gGreen, gBlue);
    }
    setPixel(i + EyeSize + 1, gRed / 10, gGreen / 10, gBlue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
  for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
    setAll(0, 0, 0);
    setPixel(i, gRed / 10, gGreen / 10, gBlue / 10);
    for (int j = 1; j <= EyeSize; j++) {
      setPixel(i + j, gRed, gGreen, gBlue);
    }
    setPixel(i + EyeSize + 1, gRed / 10, gGreen / 10, gBlue / 10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}
void RunningLights(byte gRed, byte gGreen, byte gBlue, int WaveDelay) {
  int Position = 0;
  for (int i = 0; i < NUM_LEDS * 2; i++)
  {
    Position++; // = 0; //Position + Rate;
    for (int i = 0; i < NUM_LEDS; i++) {
      // sine wave, 3 offset waves make a rainbow!
      //float level = sin(i+Position) * 127 + 128;
      //setPixel(i,level,0,0);
      //float level = sin(i+Position) * 127 + 128;
      setPixel(i, ((sin(i + Position) * 127 + 128) / 255)*gRed,
               ((sin(i + Position) * 127 + 128) / 255)*gGreen,
               ((sin(i + Position) * 127 + 128) / 255)*gBlue);
    }
    showStrip();
    delay(WaveDelay);
  }
}
void theaterChase(byte gRed, byte gGreen, byte gBlue, int SpeedDelay) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, gRed, gGreen, gBlue); //turn every third pixel on
      }
      showStrip();
      delay(SpeedDelay);
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, 0, 0, 0); //turn every third pixel off
      }
    }
  }
}
void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;
  // Step 1. Cool down every cell a little
  for ( int i = 0; i < NUM_LEDS; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
    if (cooldown > heat) {
      heat = 0;
    } else {
      heat = heat - cooldown;
    }
  }
  // Step 2. Heat from each cell drifts 'up' and diffuses a little
  for ( int k = NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
  // Step 3. Randomly ignite new 'sparks' near the bottom
  if ( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160, 255);
    //heat[y] = random(160,255);
  }
  // Step 4. Convert heat to LED colors
  for ( int j = 0; j < NUM_LEDS; j++) {
    setPixelHeatColor(j, heat[j] );
  }
  showStrip();
  delay(SpeedDelay);
}
//used by fire
void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature / 255.0) * 191);
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
  // figure out which third of the spectrum we're in:
  if ( t192 > 0x80) { // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if ( t192 > 0x40 ) { // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else { // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}
void FadeInOut(byte gRed, byte gGreen, byte gBlue) {
  float R, G, B;
  for (int k = 0; k < 256; k = k + 1) {
    R = (k / 256.0) * gRed;
    G = (k / 256.0) * gGreen;
    B = (k / 256.0) * gBlue;
    setAll(R, G, B);
    showStrip();
  }
  for (int k = 255; k >= 0; k = k - 2) {
    R = (k / 256.0) * gRed;
    G = (k / 256.0) * gGreen;
    B = (k / 256.0) * gBlue;
    setAll(R, G, B);
    showStrip();
  }
}
void Strobe(byte gRed, byte gGreen, byte gBlue, int StrobeCount, int FlashDelay, int EndPause) {
  for (int j = 0; j < StrobeCount; j++) {
    setAll(gRed, gGreen, gBlue);
    showStrip();
    delay(FlashDelay);
    setAll(0, 0, 0);
    showStrip();
    delay(FlashDelay);
  }
  delay(EndPause);
}
void Sparkle(byte gRed, byte gGreen, byte gBlue, int SpeedDelay) {
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel, gRed, gGreen, gBlue);
  showStrip();
  delay(SpeedDelay);
  setPixel(Pixel, 0, 0, 0);
}
void Twinkle(byte gRed, byte gGreen, byte gBlue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0, 0, 0);
  for (int i = 0; i < Count; i++) {
    setPixel(random(NUM_LEDS), gRed, gGreen, gBlue);
    showStrip();
    delay(SpeedDelay);
    if (OnlyOne) {
      setAll(0, 0, 0);
    }
  }
  delay(SpeedDelay);
}
void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0, 0, 0);
  for (int i = 0; i < Count; i++) {
    setPixel(random(NUM_LEDS), random(0, 255), random(0, 255), random(0, 255));
    showStrip();
    delay(SpeedDelay);
    if (OnlyOne) {
      setAll(0, 0, 0);
    }
  }
  delay(SpeedDelay);
}
void rainbowCycle(int SpeedDelay) {
  byte *c;
  uint16_t i, j;
  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < NUM_LEDS; i++) {
      c = Wheel(((i * 256 / NUM_LEDS) + j) & 255);
      setPixel(i, *c, *(c + 1), *(c + 2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}
// used by rainbowCycle
byte * Wheel(byte WheelPos) {
  static byte c[3];
  if (WheelPos < 85) {
    c[0] = WheelPos * 3;
    c[1] = 255 - WheelPos * 3;
    c[2] = 0;
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    c[0] = 255 - WheelPos * 3;
    c[1] = 0;
    c[2] = WheelPos * 3;
  } else {
    WheelPos -= 170;
    c[0] = 0;
    c[1] = WheelPos * 3;
    c[2] = 255 - WheelPos * 3;
  }
  return c;
}



// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************
// Apply LED color changes
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  FastLED.show();
#endif
}
// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
#endif
}
// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}


   
ReplyQuote
Page 1 / 2
Share: