Variable affected by unrelated parts of program

Hi, my program behaves very weird. If I run the code below, the variable elapsedMillis changes its value even though it is not involved in any operation.

I spent the last hours cutting away everything that has no effect on this bug and ended up with the code below. Now if I even delete a Serial.print line, the bug goes away.

In this state "elapsedMillis" is just counting up. If I ad some other unrelated code its value occasionally jumps, too. I'm totally lost with this one. :face_with_spiral_eyes:

This is what the serial monitor looks like:

timerIsOn: 0
cmd: 0
currentMillis: 1073
startMillis: 0
elapsedMillis: 0
----------------------------------
timerIsOn: 0
cmd: 1
currentMillis: 1077
startMillis: 0
elapsedMillis: 0
----------------------------------
timerIsOn: 0
cmd: 0
currentMillis: 1087
startMillis: 0
elapsedMillis: 1087
----------------------------------
timerIsOn: 0
cmd: 1
currentMillis: 1096
startMillis: 0
elapsedMillis: 1087
----------------------------------

This is the code:

// LCD
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

float ovenTemp[2] = {0.0, 0.0};

void setup() {
  Serial.begin(115200);

  lcd.init();
  lcd.backlight();
}

void loop() {
  timer(0);
  timer(1);

  printTemp(ovenTemp[0], 2);
  printTemp(ovenTemp[1], 3);
}

void printTemp(float temp, byte line) {
  unsigned long currentMillis = 0;
  static unsigned long previousMillis[2] = {0, 0};
  char printTemp[6];
  static char previousPrintTemp[2][6] = {{""}, {""}};

  currentMillis = millis();

  if (currentMillis - previousMillis[line] > 1000) {
    previousMillis[line] = currentMillis;

    if (temp <= -50 || temp >= 400) {
    } else {
      dtostrf(temp, 5, 1, printTemp);
    }
  }
}

void timer(byte cmd) {
  unsigned long currentMillis = 0;
  static unsigned long startMillis = 0;
  static unsigned long elapsedMillis = 0;
  static bool timerIsOn = false;

  currentMillis = millis();
  Serial.print("timerIsOn: "); Serial.println(timerIsOn);
  Serial.print("cmd: "); Serial.println(cmd);

  Serial.print("currentMillis: "); Serial.println(currentMillis);
  Serial.print("startMillis: "); Serial.println(startMillis);
  Serial.print("elapsedMillis: "); Serial.println(elapsedMillis);

  if (timerIsOn) {
    Serial.println("if statement ran");
    elapsedMillis = currentMillis - startMillis;
  }
  Serial.println("----------------------------------");
}

This happens because another part of the program mistakenly overwrites the memory area where this variable is located. The most common reason for this is an array out of bounds, for example, an attempt to access an array element a[2] in array of two element.
Look to your code:

You call printTemp procedure with second parameter = 2 and 3, which then use as index for two-elements arrays:

1 Like

Thank you! This function is used to print a temperature to a line of the display. I forgot to update it when I changed from a 2-line to 4-line display. I changed the array to 4 elements (lines 0,1,2,3) and it works fine now. Is this correct?

Complete function for context:

void printTemp(float temp, byte line) {
  unsigned long currentMillis = 0;
  static unsigned long previousMillis[4] = {0, 0};
  char printTemp[6];
  static char previousPrintTemp[4][6] = {{""}, {""}}; //6 bytes are required to store 5 characters + terminating null

  currentMillis = millis();

  // print interval
  if (currentMillis - previousMillis[line] > 1000) {
    previousMillis[line] = currentMillis;

    // if temp is beyond specifications
    if (temp <= -50 || temp >= 400) {
      lcd.setCursor(13, line);
      lcd.print("  ERR");
    } else {
      // convert temp float to string
      dtostrf(temp, 5, 1, printTemp);

      // only print if value changed to prevent flicker
      if (strcmp(printTemp, previousPrintTemp[line]) != 0) {
        strcpy(previousPrintTemp[line], printTemp);

        // clear display
        lcd.setCursor(13, line);
        lcd.print("     ");

        // print value
        lcd.setCursor(13, line);
        lcd.print(printTemp);
      }
    }
  }
}

I don't see obvious errors

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.