millis() range again...

Hello!

As i need to have the board running "endlessly" with some timed events happening every now and then, I try to use millis() for the timers. There of course comes the problem:

  1. The reference states that millis() would roll over after 9h 32m

  2. Some of the posts on the forum state that it would roll over after 55 days

  3. When I calculate the expected range of unsigned long int (4294967295) and translate it into days, I get about 49.7 days..

Now - could somebody make it eventually clear with an authoritative (at least well educated :-) statement about what is the highest possible value of millis() just before it rolls over?

Cordially,

silverdr

Silver Dream--

As of Arduino 0012, millis now rolls over at 0xFFFFFFFF. The reference is dated.

Mikal

As of Arduino 0012, millis now rolls over at 0xFFFFFFFF. The reference is dated.

Which converts to how many fortnights before roll-over? ;)

Lets see, 1 millisec is equal to 8.267196 X e-10 fortnights....times 0xFFFFFFFF..Oh wait I think the wife is calling me for dinner.....

Lefty

OK. Thank you. This means that it should take 49.71 days until roll over, unless the returned values are not really accurate milliseconds. How is that? How accurate are the results from millis()? Is it really so that it should roll over after 49.71 days but due to inaccuracy of the unit, the roll over happens after around 55 days (as posted few times here)?

Regards,

silverdr

Thanks for the humor retrolefty. ;)

Just what exactly does

"As of Arduino 0012, millis now rolls over at 0xFFFFFFFF."

mean in layperson's terms?

What is the number of millis(), in milliseconds, when millis() rolls over?

Arduino 0013, (20Mhz Atmega168)

http://arduino.cc/en/Reference/UnsignedLong

4,294,967,295 (2^32 - 1).

One of the important aspects of rolling over at the 32bit mark rather than some odd earlier time is that is no particular reason why rolling over should cause programs to fail, since the math to calculate times rolls over at the same spot. For instance, the way that delay() is implemented:

void delay(unsigned long ms)
{
      unsigned long start = millis();
      
      while (millis() - start <= ms)
            ;
}

Say you enter with mills() = 4294966296 (2^32 -1000) and want a delay of 2000.
So at 2^32 - 1 (0xFFFFFFFF), millis() - start will be 999 (good, and the loop continues.)
At 0 + 100 (after wraparound of millis), millis() - start will be 1100m (when you do 32
bit math), which is still exactly right, and the loop will continue until we get to millis() == 1000.

The problem with the OLD code was that the results of millis() would wrap around DIFFERENTLY than 32bit math, leading to such functions not behaving correctly after the wrap…

Thanks! Now I get it!