Page 1 of 1

Troy's project

Troy's project

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.
Examples: "MacOS X - Your question", "MS Word - Your Tip or Trick".

Please note that switching to another language when reading a post will not work!
Posts will not have a translated counterpart.




RSS Feed

Home Forums Hardware Arduino Troy's project

This topic contains 17 replies, has 2 voices, and was last updated by  hans 2 months ago.

Viewing 15 posts - 1 through 15 (of 18 total)
  • Author
    Posts
  • 12004

    hans
    Keymaster

    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[i] = 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[i]) {
          heat[i] = 0;
        } else {
          heat[i] = heat[i] - 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();
    }
    12009

    troy89
    Participant

    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[i] = 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[i]) {
          heat[i] = 0;
        } else {
          heat[i] = heat[i] - 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();
    }

    12011

    hans
    Keymaster

    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 

    12015

    troy89
    Participant

    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. 
    12017

    troy89
    Participant

    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?

    12019

    troy89
    Participant

    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…. 

    12021

    troy89
    Participant

    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.
    • This reply was modified 2 months ago by  troy89.
    • This reply was modified 2 months ago by  troy89.
    • This reply was modified 2 months ago by  troy89.
    • This reply was modified 2 months ago by  troy89.
    Attachments:
    12032

    hans
    Keymaster
    • 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 

    12034

    troy89
    Participant

    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 
    12036

    troy89
    Participant

    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….  

    12038

    troy89
    Participant

    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! 

    12040

    troy89
    Participant

    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     

    12042

    hans
    Keymaster

    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 …

    12044

    troy89
    Participant

    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[i] = 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[i]) {
          heat[i] = 0;
        } else {
          heat[i] = heat[i] - 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();
    }

    12046

    troy89
    Participant

    Actually that’s what I did when I first started debugging these issues. The issues with the functions started as soon as I enabled a second interrupt button, and it didn’t matter whether they were both external interrupts or pin change interrupts. I tried posting about this on the arduino forum as well but the people there aren’t nearly as helpful as you are. Someone even asked if this code was joke code and that it was badly designed because I had interrupt buttons….all they seemed to do is reference ‘blink without delay’ or nitpick at the code design rather than actually answer any of my questions. 

    At this point I’m resigned to the fact that whatever is causing these issues is something that is above me. I’ll keep attempting to debug but now I’m working on the physical aspect of this project which is PCB prototyping and circuit board design. I’m going to attempt to add some additional functions at a later date but for now this is the final version. I don’t know if I ever mentioned but this code is for an ‘infinity goggle’ project that I think you’ll find very cool/interesting. Once I get my prototype complete I’ll be sure to share the finished result!

Viewing 15 posts - 1 through 15 (of 18 total)



You must be logged in to reply to this topic.