variable changing unexpectedly in program, except if adding a Serial.println()

Hi all,

I have quite a bit of experience with Arduinos, but I’ve ran into an issue which I can’t resolve…

I am using an Arduino Mega2560 (official).

I wrote a program where each of the buttons correspond to a section of an RGB LED strip; if a button is pushed then the corresponding section of the LED strip will turn green. Idea is to push all buttons, and then someting could happen.

Since it was difficult to hold all 24 buttons (this is for kids :-)), I decided to define an offset value (in the setup() function), so if buttons were pushed less than x seconds ago (=offset value), the button program would still consider this button as pushed.
And this is where the issue started…

The value of startknop[1] gets changed to 16711680 (always the same value), unless I am adding a Serial.println()…

I presume the issue is coming from the variable

unsigned long startknop[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

maybe I am short on memory?? (although when compiling it says Global Variable 8% of dynamic memory.

Code is below:

#include "FastLED.h"
#define NUM_LEDS_PER_STRIP 64//100
// 64 LEDs, te verdelen over 24 knoppen, dus LED per 2: LED 0 - 48  en per 3: LED 49 - 64
#define UIT_LEDSIGNAAL 9
CRGB leds[NUM_LEDS_PER_STRIP];
uint8_t InKnop[24] = {22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 23, 25, 27, 29, 31, 33, 35, 37};
bool Ingedrukt[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned long startknop[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int count = 0;
int correct_teller_knoppen;
bool correct = false;
bool gedrukt = false;  // moet false zijn
uint8_t minimum_aantal_knoppen = 23;
int offset = 0; // time in ms
int setuptime = 10000; //set-up time during the setup() function during which the offset value will be defined
unsigned long starttijd = 0;

void setup() {
  Serial.begin(9600);
  FastLED.addLeds<NEOPIXEL, UIT_LEDSIGNAAL>(leds, NUM_LEDS_PER_STRIP);
  for (int i = 0; i < 24; i++) {
    pinMode(InKnop[i], INPUT_PULLUP);
  }
  // make all LEDs white
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
    leds[i].r = 255;  // RED
    leds[i].g = 255; // BLUE
    leds[i].b = 255;  // GREEN
  }
  FastLED.show();
  // read input using buttons to define the off-set
  starttijd = millis();
  correct_teller_knoppen = 0;
  while (millis() - starttijd < setuptime) {
    for (int j = 0; j < 24; j++) { // lees de knoppen in
      if (Ingedrukt[j] == 0) {
        if (digitalRead(InKnop[j]) == 0) {
          Ingedrukt[j] = 1;
          Serial.println(j);
        }
      }
    }
  }
  for (int j = 0; j < 24; j++) { // lees de knoppen in
    if (Ingedrukt[j] == 1) {
      correct_teller_knoppen++;
      Ingedrukt[j] = 0;
    }
  }
  offset = correct_teller_knoppen * 1000; //omzetten in ms
  for (int j = 0; j < correct_teller_knoppen; j++) { // lees de knoppen in
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
      leds[i].r = 0;  // RED
      leds[i].g = 0; // BLUE
      leds[i].b = 0;  // GREEN
    }
    FastLED.show();
    delay(500);
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
      leds[i].r = 100;  // RED
      leds[i].g = 100; // BLUE
      leds[i].b = 100;  // GREEN
    }
    FastLED.show();

    delay(500);
  }
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
    leds[i].r = 0;  // RED
    leds[i].g = 0; // BLUE
    leds[i].b = 0;  // GREEN
  }
  FastLED.show();
  delay(5000);
}

void loop() {
  Serial.println();
  Serial.println("start of loop()");
  correct_teller_knoppen = 0;
  //Serial.println("step 1 check in program");
  //Serial.print("1. startknop[1]:"); Serial.println(startknop[0]);  // THIS IS THE LINE: if UNCOMMENTED, THE VALUE OF startknop[1] DOES NOT CHANGE...
  // read the buttons
  for (int j = 0; j < 24; j++) { // lees de knoppen in
    if (digitalRead(InKnop[j]) == 0) {
      Ingedrukt[j] = 1;
      Serial.print("millis: "); Serial.println(millis());
      startknop[j] = millis();
      Serial.print("startknop[j]:"); Serial.println(startknop[j]);
      correct_teller_knoppen++;
      gedrukt = true;
    }
    if (digitalRead(InKnop[j]) == 1) {
      //below if function only for testing purposes
      if (j == 0) {
        Serial.println("first button NOT pushed");
        Serial.print("millis: "); Serial.println(millis());
        Serial.print("startknop[j]:"); Serial.println(startknop[j]);
      }
      if (millis() - startknop[j] < offset) {
        Ingedrukt[j] = 1;
        correct_teller_knoppen++;
      }
      else {
        Ingedrukt[j] = 0;
      }
    }
  }
  Serial.println("step 2 check in program");
  Serial.print("2. startknop[1]:"); Serial.println(startknop[0]);

  // check if all buttons where pushed
  if (gedrukt == true && correct_teller_knoppen == minimum_aantal_knoppen) {
    //alle toetsen ingedrukt - HOERA!
    hoera();
  }
  // set the right LEDsegments to GREEN
  else if (gedrukt == true && correct_teller_knoppen < minimum_aantal_knoppen) {
    // bepaald aantal toetsten ingedrukt, maar niet allemaal
    for (int j = 0; j < 25; j++) {
      if (Ingedrukt[j] == 1) {
        if (j < 16) {
          leds[3 * j].r = 0; // RED
          leds[3 * j].g = 0; // BLUE
          leds[3 * j].b = 255; // GREEN
          leds[3 * j + 1].r = 0; // RED
          leds[3 * j + 1].g = 0; // BLUE
          leds[3 * j + 1].b = 255; // GREEN
          leds[3 * j + 2].r = 0; // RED
          leds[3 * j + 2].g = 0; // BLUE
          leds[3 * j + 2].b = 255; // GREEN
        }
        if (j >= 16) {
          leds[3 * 16 + 2 * (j - 16)].r = 0; // RED
          leds[3 * 16 + 2 * (j - 16)].g = 0; // BLUE
          leds[3 * 16 + 2 * (j - 16)].b = 255; // GREEN
          leds[3 * 16 + 2 * (j - 16) + 1].r = 0; // RED
          leds[3 * 16 + 2 * (j - 16) + 1].g = 0; // BLUE
          leds[3 * 16 + 2 * (j - 16) + 1].b = 255; // GREEN
        }
      }
      if (Ingedrukt[j] == 0) {
        if (j < 16) {
          leds[3 * j].r = 0; // RED
          leds[3 * j].g = 0; // BLUE
          leds[3 * j].b = 0; // GREEN
          leds[3 * j + 1].r = 0; // RED
          leds[3 * j + 1].g = 0; // BLUE
          leds[3 * j + 1].b = 0; // GREEN
          leds[3 * j + 2].r = 0; // RED
          leds[3 * j + 2].g = 0; // BLUE
          leds[3 * j + 2].b = 0; // GREEN
        }
        if (j >= 16) {
          leds[3 * 16 + 2 * (j - 16)].r = 0; // RED
          leds[3 * 16 + 2 * (j - 16)].g = 0; // BLUE
          leds[3 * 16 + 2 * (j - 16)].b = 0; // GREEN
          leds[3 * 16 + 2 * (j - 16) + 1].r = 0; // RED
          leds[3 * 16 + 2 * (j - 16) + 1].g = 0; // BLUE
          leds[3 * 16 + 2 * (j - 16) + 1].b = 0; // GREEN
        }
      }
    }
    FastLED.show();
    gedrukt = false;
  }
  // set the LEDS to RED if no buttons were pushed
  else {
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
      leds[i].r = count;  // RED
      leds[i].g = 0; // BLUE
      leds[i].b = 0;  // GREEN
    }
    FastLED.show();
    delay(2);
  }
  count = count + 1;
  if (count == 255) {
    count = 0;
  }
}

void hoera() {
 // do something
}

and below is output I’m getting from my Serial monitor:
start of loop()
millis: 20149
startknop[j]:20156
step 2 check in program
2. startknop[1]:20156
start of loop()
first button NOT pushed
millis: 20281
startknop[j]:16711680
step 2 check in program
2. startknop[1]:16711680
start of loop()
first button NOT pushed
millis: 20420
startknop[j]:16711680
step 2 check in program
2. startknop[1]:16711680

Now, when I uncomment the lines (line 4 and 5 in the loop()), the script does what it should do, and value of startknop[1] does not change:

Serial.println("step 1 check in program");
Serial.print("1. startknop[1]:"); Serial.println(startknop[0]);  // THIS IS THE LINE: if UNCOMMENTED, THE VALUE OF startknop[1] DOES NOT CHANGE...

I get get the following output on the Serial monitor:
start of loop()
step 1 check in program
1. startknop[1]:19869
millis: 20017
startknop[j]:20024
step 2 check in program
2. startknop[1]:20024
start of loop()
step 1 check in program
1. startknop[1]:20024
first button NOT pushed
millis: 20200
startknop[j]:20024
step 2 check in program
2. startknop[1]:20024

Any thoughts on what I’m doing wrong here? Many thanks!

for (int j = 0; j < 25; j++) {Why 25 suddenly?

men, correct! And this is indeed resolving the issue.

But tell me, how come this is causing the described issue? I can understand this the 25th count is causing issues with the memory, but how come adding or removing the Serial.print line is resulting in differente behavior?

if (j >= 16) {
          leds[3 * 16 + 2 * (j - 16)].r = 0; // RED
          leds[3 * 16 + 2 * (j - 16)].g = 0; // BLUE
          leds[3 * 16 + 2 * (j - 16)].b = 255; // GREEN
          leds[3 * 16 + 2 * (j - 16) + 1].r = 0; // RED
          leds[3 * 16 + 2 * (j - 16) + 1].g = 0; // BLUE
          leds[3 * 16 + 2 * (j - 16) + 1].b = 255; // GREEN
}

Do the math. What happens when j == 24?

Once you start writing to memory that you don't own, you (deservedly) get unpredictable results.