Howl with rage if you like! Future time stamps do make the logic more straightforward. Here I've just created a millis() like function that uses 'unsigned long long' type to postpone overflow. Please only post admiration and awe. No criticism. Just kidding.
/*
overflow-safe Blink without Delay
2022-12-17 Aarg on Arduino forum
Adapted from:
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
*/
// introduce a millis() replacement safeMillis()
// allows future time stamps by postponing overflow
// until the restaurant at the end of the universe closes
typedef unsigned long long millis_t;
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN;// the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
millis_t nextMillis = 1000; // will store next time LED should be updated
// constants won't change:
const long interval = 1000; // interval at which to blink (milliseconds)
// This free running counter function won't overflow anytime soon.
millis_t safeMillis() {
static millis_t safeCounter = 0;
static unsigned long nextMillis = 0;
while (millis() - nextMillis > 0) {
nextMillis++;
safeCounter++;
}
return safeCounter;
}
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
millis_t currentMillis = safeMillis();
// check to see if it's time to blink the LED; that is, if the current time
// has passed the future time stamp
if (currentMillis > nextMillis ) {
// set the next time you will blink the LED
nextMillis = currentMillis + interval;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
No. The chances are actually strongly in favour, since most of the time a millisecond has not elapsed since the last check. A check is performed each time through loop().
What if someone wants to measure the time between button presses, and that time can be a year. If the safeMillis() is called when the button is pressed, then the result is wrong because safeMillis() has not been updated enough.
Why has safeMillis() not been updated enough? It's called each time through loop().
By the way, this is an advantage I didn't mention. Unlike millis(), safeMillis() has no effective maximum interval measurement length. So it can time years, decades etc.
No. It's perfectly well defined, as long as it is called unconditionally from loop(). That is why I used 'while' instead of 'if'. In some case where significant time elapses before the function is called again, the 'while' loop will run repeatedly and the time stamp is incremented until it is fully up to date.
That will happen any time the function is called, so it is guaranteed to be up to date, any time you request the time.
If you don't call it, it will lose sync, but that doesn't matter because in that case you are not asking it for the time.
Besides that, while using millis() or safeMillis() timing, any code that prevents the loop from executing at speed, is a bad programming practice and you deserve what you get if you do it.