Integer not getting intended value

I have a problem with my code. What I try to do is to control a displays backlight and shut it down if it has been on for a long enough time.

My test code is below. It isn’t beautiful or smart, I wrote it so I can debug it easily everywhere because at first I didn’t find the problem.

#include <LiquidCrystal.h>

// Pin setup
int lcdbl = 11;

// Init lcd
LiquidCrystal lcd(10, 9, 8, 7, 6, 5);

// Variables
//String inputString = "";        // Serial input data
//boolean stringComplete = false; // Serial complete
int dto = 0;  // Keep track of display time
int maxdto = 5000; // Max disp time on

// Setup
void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
  Serial.begin(9600);
  pinMode(lcdbl, OUTPUT);
  digitalWrite(lcdbl, HIGH);
//  inputString.reserve(200);
}

String chkserial() {
  String inputString = "";
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
  }
  return inputString;
  inputString = "";
}

String wds(String dat) {
  String ret = "";
  if (dat == "C:1;") {
    ret = "lcd on";
  }
  if (dat == "C:2;") {
    ret = "lcd off";
  }
  return ret;
}

int lcd_on() {
  lcd.setCursor(0, 0);
  lcd.print("Hello           ");
  lcd.setCursor(0, 1);
  lcd.print("World!          ");
  digitalWrite(lcdbl, LOW);
  return millis();
}

int lcd_off() {
  lcd.setCursor(0, 0);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
  digitalWrite(lcdbl, HIGH);
  return 0;
}
    

void loop() {
  String a = wds(chkserial());
  if (a == "lcd on") {
    Serial.println(a);
    lcd_on();
    dto = millis();
  }
  if (a == "lcd off") {
    Serial.println(a);
    dto = lcd_off();
  }
  if (millis() - dto > maxdto) {
    Serial.print("Turning off lcd\n");
    Serial.print(dto);
    Serial.print("\n");
    Serial.print(millis());
    Serial.print("\n\n");
    dto = lcd_off();
  }
  delay(5000);
}

My idea is basically the following:
If the lcd on string is received, turn the lcd on and put the time into dto. If the lcd of string is received or the lcd has been on long enough (5 sec for now), turn the lcd off.
Instead, it works differently.

First time I send the lcd on string, the lcd turns on and I receive the lcd on -string.
The auto turn off works, saying dto is 5039 and time now 15039. That’s OK.
Next auto off says dto is 0 and time now 20052 which is also okay.
If I turn the lcd back on it works, and it also turns it off (dto 30092, time now 40092).
After that it gets wierd. If I turn the lcd on it flickers and stays off. On the terminal I receive: dto = -15406 and time now 50131.

What have I done wrong? How can the dto variable, which always gets set to millis() when the display is turned on, jump to a negative random value instead of millis() ?
It doesn’t get better later. If I try to turn the display on again, it just flickers and get a random value to dto.

lcd on
Turning off lcd
5039
15039

lcd on
Turning off lcd
20065
30066

lcd on
Turning off lcd
-30445
35092

lcd on
Turning off lcd
-25418
40118

Turning off lcd
0
45131

Time related variables should always be unsigned long, not int.

PaulS: Time related variables should always be unsigned long, not int.

The movie producer from Back To the Future is on the other line. ;)

Lefty

dto = -15406 means the first bit got set and instead of being a bigger number, for certain types of variable, that bit is the sign , not another power of two

Have a look here and here for instance.

PaulS beat me to it.... as he says, you need to go for huuuuuuuuuge numbers with no sign, like unsigned long.

Thank you!