Worried about millis() timer overflow?

Introduction

You need to worry about this if your arduino is going to be powered for more than 49 days, if not below are good practices to follow when using millis() function that avoid overflow.

If you do things right, you don’t have to worry about millis() overflow. The trick is to handle overflow.

What is millis() function?

millis() function return the time in millisecond since arduino was powered up. Sometimes also refered as arduino time in forums. this function returns unsigned long integer which is a 32 bit number which can hold up  0 to 4,294,967,295 (2^32 – 1). The maximum number will reach after 49.710 days (2^32/1000/60/60/24) after it will roll back to zero. Nothing really happens when this timer rolls over, the processor doesn’t reset not lock up, the timer will still keep on ticking just like it was before overflow. You might be tempted to reset the millis() timer so things are more in your control, well you can but there is no reason to do so, you might break some libraries. If you are making a clock it is not recommended to use this function for time keeping, rather use RTC unless you want to set time every time when power cycles which defeats the purpose of a clock.

Lets look at bad way of using millis() function

Directly comparing two time stamps

Now above will always be true, but not if during the delay the millis() overflows.

Other method is to compare duration.

Example of Adding(Not recommended)

This will work most of the time, but not when overflow occurs, lets say millis() overflows in 30 seconds, the condition will become true and instead of waiting 60 seconds, it will stop waiting as soon as timer overflows.

Using Subtraction(Recommended)

The above code will work every time even if the timer overflows, the reason is because of how binary arithmetic works.

Now if you want to test your code at millis() overflow either wait 49 days which you probably won’t or use below code can be used to set the millis timer with a high value so it will overflow in couple of seconds.

This code is purely for testing purpose only.

Sketch for testing millis() overflow

Same technique should be used for micros() function which records microsecond since arduino was powered. It wraps around rather quickly in 71.58 minutes.

Resources:

http://www.gammon.com.au/millis

http://playground.arduino.cc/Code/TimingRollover

http://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover

Featured Photo credit:http://www.freepik.com/free-vector/time-and-clocks-icons_761530.htm

  • Paul Wilson

    Thanks, I’ve read this technique in a few places. However, it looks to me like it just shifts the problem from high values of millis() to low values of millis().

    For example:
    startTime = 3; //e.g. triggered after one or more millis roll-overs, or if debouncing a sensor.
    interval = 10;
    currentTime = 7; // currentTime = mills();

    The actual gap in this example is 4ms, so the event shouldn’t trigger, but if we use:

    if(currentTime – interval >= startTime) {/*do something*/}

    the ‘if’ statement is true, since (currentTime – interval) is negative, which wraps to a big positive number.

    Am I missing something?

    • Hi Paul, I believe, your if statement is not correct. it should be if(currentTime – startTime >= interval) {/*do something*/}

      • Paul Wilson

        Many thanks, silly mistake on my part.