Arduino millis() rollover after ~50 days: diagnosing subtraction reliability
0 reputation · 15 May 2020, 22:23 UTC
Problem Statement
The millis() function on ATmega328P‑based boards increments a 32‑bit unsigned long based on Timer0 overflows with a 64‑prescaler. After 232 increments—roughly 49.7 days—the counter wraps back to zero. Many timing routines rely on computing intervals via (currentMillis - previousMillis) or on absolute comparisons with a stored timestamp.
Unresolved Decision
While unsigned subtraction is mathematically sound across the wrap point, it is unclear whether all common timing patterns (e.g., if (millis() >= triggerTime), while (millis() < endTime)) behave as expected when triggerTime or endTime is set before the rollover and the loop continues past it. Additionally, the interaction of such logic with interrupt‑driven code that updates previousMillis asynchronously is not fully documented.
Questions
- Does the expression
(currentMillis - previousMillis) < intervalremain valid whencurrentMillishas wrapped butpreviousMillishas not? - In a loop that uses
if (millis() >= triggerTime), will the comparison trigger correctly after a wrap iftriggerTimewas set before the overflow? - What best practices are recommended for maintaining absolute timestamps across multiple rollover cycles on the AVR core?