millis(), how to detect overflow (after +/-50 days)?

A program uses the millis() function on a regular basis as a means to keep track of an output being set during a few hours. However, when the output is actually being tracked while the millis() overflows (after 50 days of consecutive running program) the consequence is that the amount of time this particular output is set is not known anymore.

How is this overflow issue addressed when the time from millis() is used to measure some specific action performed by the program?

For example: a valve is opened (and later closed) due to a specific digital input (say a low level sensor), and the amount of time this valve is opened is to be monitored so that in due time an alarm can be triggered. Now when the millis() overflow during a time when the valve is opened, how do you take that eventuality into account to make sure that the actual time that this valve is opened is never lost?

Have you done the arithmetic using unsigned longs?

Provided you don't try to measure times greater than 49 days, the rollover is not a problem, and even if you do want longer times, it is very simply handled.

As long as you're using unsigned long and this pattern, there's nothing to worry about:

if(millis()-startTime > interval)
  {
   ...
  }

It's come up in the forums many times before IIRC JohnWasser(?) did a particularly convincing investigation into it.

Also, you can use micros to prove it to yourself without having to wait 50 days :wink:

Edit: spelling

TolpuddleSartre:
Have you done the arithmetic using unsigned longs?

Provided you don't try to measure times greater than then 49 days, the rollover is not a problem, and even if you do want longer times, it is very simply handled.

I am not sure I understand: suppose the last milli is 9999, and the valve opens at 9990, and startTime = millis(); which will then be 9990. A few moments later millis() reverts back to 0 counting upwards.
If I set an alarm that depens on the time difference between millis() and startTime then I will never be able to set the alarm? No?

Just do the arithmetic for yourself, using unsigned variables.
Unsigned shorts will demonstrate the solution if you don't want to wait even 70 minutes for micros to rollover.

void setup ()
{
  Serial.begin (115200);
  unsigned int end  = 0x10; // after rollover
  unsigned int start = 0xfff0; // before rollover
  unsigned int diff   = end - start;

  Serial.println (diff); // prints 32.
}

void loop ()
{
}

When using subtraction on unsigned integers. the subtraction will automatically handle it.

millis() - startTime >= interval Lets try it using byte to make the math easier

10 - 245 >= 20 Millis() has just rolled over startTime was before rollover

if you start at 10 count back to 0 then 255 on down you will see that the answer is exactly 20.

subtraction will always give the right answer when using unsigned integers hence no problems with rollover.

Hutkikz:
When using subtraction on unsigned integers. the subtraction will automatically handle it.

millis() - startTime >= interval Lets try it using byte to make the math easier

10 - 245 >= 20 Millis() has just rolled over startTime was before rollover

if you start at 10 count back to 0 then 255 on down you will see that the answer is exactly 20.

subtraction will always give the right answer when using unsigned integers hence no problems with rollover.

GREAT!! Thank you all of you!!