Check in case millis() runs over on the 50th day.

Hey guys, I have a project I want to leave unattended for along period of time. I am using millis() to enact an event every 5 minutes. I want to make sure that when millis() rolls over I don’t accidentally get stuck and wait 49 days. Here’s my proposed code, obviously I don’t want to wait to see if it works, do you guys think it will work?

  // every minute check the water main page data
  if((millis() - waterCheckTime) > 300000 || (millis() - waterCheckTime) < 0){ //every 5 minutes or if the clock rolls over on the 50th day, perform the action immediatly 

  // do my action
  
  waterCheckTime = millis();
  }

waterCheckTime is a unsigned long defined earlier in the program.

Thanks for your inputs.

You don't need any extra checking for that. The first part of your if statement is sufficient. After rolling over you'll subtract a big number from a small number. It's UNSIGNED long so that math rolls over too and you get the right answer.

Since the variables are unsigned the second part doesn't do anything. The result cannot ever be negative in an unsigned math.

Delta_G: You don't need any extra checking for that. The first part of your if statement is sufficient. After rolling over you'll subtract a big number from a small number. It's UNSIGNED long so that math rolls over too and you get the right answer.

Since the variables are unsigned the second part doesn't do anything. The result cannot ever be negative in an unsigned math.

Here's my thoughts, and to make it simple lets say that millis() counts up in minutes where at 100 minutes it rolls over.

Worst Case: At 96 minutes I run my 5 minute check, current waterCheckTime is set to 96. 5 minutes later millis() is at 101 which has been rolled over to 1 minute. waterCheckTime is still 996.

1 - 96 = -95 which is not > than any positive number, this could go on forever....

If I would have coded it to have waterCheckTime be predicted (initialize it as millis() + 5 minutes), and then check when it's true, you would be correct in your assumption.

Sigh. And not representable in an unsigned variable, either.

Trust us, it works.

magruder13: and to make it simple lets say that millis() counts up in minutes where at 100 minutes it rolls over.

Alright, let's go with that.

magruder13: 1 - 96 = -95 which is not > than any positive number, this could go on forever....

But that's nonsense! ;) That's why you should use a unsigned variable type. Then 1 - 96 = 5!

So really, you have NO problem whatsoever if you check like timeNow - lastTime >= interval and you only use unsigned variables for timeNow and lastTime. No other checks required ;)

magruder13: 1 - 96 = -95 which is not > than any positive number, this could go on forever....

No, you don't understand. You use an UNSIGNED variable. It can never be negative. So the math rolls over at the same point. In your example where rollover is at 100, 1 - 96 would equal 5. Exactly the number of minutes that had passed. Subtraction is counting backwards. Start at 0 and count backwards by 96. Remember at 0 to go back to 100 instead of -1.

Delta_G: Remember at 0 to go back to 100 99 instead of -1.

;)

Yes. Of course.

KeithRB: Trust us, it works.

And is easy to test...

https://forum.arduino.cc/index.php?topic=258158.msg1856807#msg1856807