Flashing LEDs, and mills() rollover

Hi all.

I use millis() in many places to help me flash LEDs and so on, like the "heartbeat" LED, as in:

if ((millis() - counter) > 1000) { //flash on board LED on/off slowly ("heartbeat"):
counter = millis();
digitalWrite (heartbeat,!(digitalRead(heartbeat)));
}

Of course when millis() rolls over after, what, 5 weeks? that causes potential problems.

I avoid this the brute force inelegant way, by writing a reset function and using that to reset the machine every week:

if (millis() > 604800000) { //reset after a week (to recalibrate filter and avoid millis rollover)
resetFunc();
}

Question: Is this an acceptable way to do it? If I solve it some other way I bet I'll get it wrong somewhere, seeing as how often I use millis(). But perhaps I am wrong and there are better methods?

Luckily, it doesn't cause any issues if the data type of counter is the same as the return type of millis() (unsigned long). Subtraction of unsigned integers is defined modulo 2n.

Let's say counter = 0xFFFFFFFF, then one millisecond later the value of millis() overflows to zero. The difference 0x00000000 - 0xFFFFFFFF = 1 mod 0x100000000, so it still gives you the elapsed number of milliseconds, regardless of overflow.

1 Like

Since it is calculated with unsigned long, it works fine unless you have twice or more rollovers.
In other words, you can ignore the rollover unless you try to use a timer that exceeds about 49 days.

The timer basically works by subtracting the "last recorded time" from the "current time"

Record 10,000(0x00002710) and when 5000 has passed and 15,000(0x00003A98)
0x00003A98 - 0x00002710 = 0x00001388 = 5000

Record 4,294,963,200(0xFFFFF000) and when 5000 has passed and 904(0x00000388)
Note: Overflow is occurring.
0x00000388 - 0xFFFFF000 = 0x00001388 = 5000

No problem.

2 Likes

Aha! OK: it is indeed the same type, unsigned long.

So if the counter rolls over to zero, zero minus that huge number (huge minus 1000, say) is still a positive number? I am trying to see the exact consequences.

And I think you have just taught me how to write this type of text - use reverse quotes. :slight_smile:

Exactly. I added an example to my first message.

1 Like

Values declared "unsigned" are absolutely never interpreted as negative numbers.

Hi @michaelwillems

FIY
milis_time

RV mineirin

1 Like

absolutely, haha, I see what you did there.

a7

1 Like