arduinoarduino-unofastled

Issue with FastLED and a simple counter


Okay, I'm having one baffling issue with this code. The counter pushCounterz (named with a z only to rule out a conflicting variable) will start with the correct counter (1 or 0 or whichever) and one of a few things will happen when the button is pushed:

  1. does nothing
  2. correctly toggles the LED but the counter malfunctions in 1 of 2 ways
    1. counter will jump to -255 then on 2nd press resets to 1 and flips with each press between 1 and -255
    2. counter will not increment
    3. counter and/or LED will randomly increment w/o touching anything.
    #include <FastLED.h>
    #define AnalogIn A0
    #define SwIn 2
    #define LED_Out 12
    #define NUM_LEDS 100
    int pushCounterz = 0;
    int buttonState;
    int lastButtonState;   // the previous reading from the input pin
    int ledPin = 13;
    int ledState = HIGH; 

    CRGB leds[NUM_LEDS];

    void setup() {
      // put your setup code here, to run once:
      FastLED.addLeds<WS2812, LED_Out, GRB>(leds, NUM_LEDS);
      //pinMode(SwIn, INPUT);
      pinMode(LED_Out, OUTPUT);
      pinMode(ledPin, OUTPUT);
      //Turn Off strip
      for (int i = 0; i <= NUM_LEDS; i++) {
        leds[i] = CRGB ( 255, 0, 0 );
        FastLED.show();
      }
        digitalWrite(ledPin, ledState);
        Serial.begin(115200);
        Serial.println(pushCounterz);
        lastButtonState = digitalRead(SwIn); // Set the button state to the startup state 
    }

    void loop() {

      buttonState = digitalRead(SwIn);

   if (buttonState == LOW && buttonState != lastButtonState) {
    ledState = !ledState;
   }
   if (buttonState == LOW && buttonState != lastButtonState) {
        if (pushCounterz > 3) {
          Serial.println("Reset to 0: ");
          pushCounterz = 0;
        } else {
          pushCounterz = pushCounterz + 1;
          Serial.println("Incerment");
        }
        Serial.println(pushCounterz);
        switch (pushCounterz) {
          case 0:
            for (int i = 0; i <= NUM_LEDS; i++) {
              leds[i] = CRGB (255, 0, 0);
            }
            break;
          case 1:
            for (int i = 0; i <= NUM_LEDS; i++) {
              leds[i] = CRGB ( 0, 255, 0);
             }
             break;
          case 2:
            for (int i = 0; i <= NUM_LEDS; i++) {
               leds[i] = CRGB ( 0, 0, 255);
             }
            break;
          case 3:
           // theaterChaseRainbow(1,50);
            break;
          default:
           for (int i = 0; i <= NUM_LEDS; i++) {
             leds[i] = CRGB ( 0, 0, 0);
           }
           break;
        }
      }
    FastLED.show();
    digitalWrite(ledPin, ledState);
    lastButtonState = buttonState;
    }

However if I disable the switch code block, everything works flawlessly. I'm suspecting this is a bug in the FastLED library, however I wanted to ask here since I'm decently new to Arduino programming.

EDIT: Code above fixed one issue with the button. I had changed the circuit to be HIGH and drop LOW, however didn't change the code. HOWEVER the state remains inconsistent, sometimes working and sometimes flipping between 1 and -255 (more-so the latter). Summary of change:

void setup() {
...
  lastButtonState = digitalRead(SwIn); // Set the button state to the startup state 
}

  */
  buttonState = digitalRead(SwIn);

  if (buttonState == LOW && buttonState != lastButtonState) {
    ledState = !ledState;
  }
  if (buttonState == LOW && buttonState != lastButtonState) {

EDIT: Serial output to show current craziness (with notes) after above edit:

0 <- initial startup correct
Incerment <- button push
1 <- correct increment
Incerment <- 2nd button push
-255 <- 1 + 1 does NOT equal -255
Incerment <- 3rd button push
1 <- ??? Assuming -255 +1 = 1?
Incerment
-255

Solution

  • With

    for (int i = 0; i <= NUM_LEDS; i++)
    

    you are using the index 100, which is the 101th element of the array.

    This is undefined behavior, which in your case causes trouble with pushCounterz.

    Fix all your for loops that iterate through leds, by changing the <= operator with <.

    for (int i = 0; i < NUM_LEDS; i++)