When comparing the value of millis() numerous times per loop(), are there reasons for/against storing it in a variable once at the top of loop(), v.s. calling millis() each time?
The most basic example code "Blink Without Delay" is written as such:
void loop() {
//...
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// Do stuff
}
}
I don't really she why the example code above bothers storing millis() in a variable "currentMillis" at all. (I realize that in such a simple program, there would be no noticeable difference.)
I imagine that if I use a variable, the longer the duration of loop(), and the further down my use of the "currentMillis" variable, the more deviated the stored value will be.
I'm wondering the other ramifications of either method as well.
Does calling millis() directly hog resources of any sort? If not, I imagine it would be better to not use a variable, so as to get a more accurate time value and save a bit of memory.
1 Answer 1
The primary downside to calling a function each time is that it may take more CPU cycles to complete the overall loop. The difference in CPU cycles, if any, depends on the actual implementation of the function and how the compiler optimises the call. For low-CPU sketches, this difference is probably unnoticeable.
Generally speaking, it is good programming practice to avoid calling a function more times than is necessary. Really the function should be called directly only if you have reasons to believe, based on desired timing and procedure order, that using the same return value in multiple places could create problems. In the example sketch given, there would be almost no functional difference between using a variable or calling the function inline.
Another advantage to using a variable is that you can give it a name that makes the code clearer to understand. In the example given, the relationship between currentMillis
and previousMillis
is very clear. In the case where a function returns a more complex object, such as a class or structure instance, using a variable (of the appropriate type) can be really useful since this would allow multiple members of the returned data to be accessed without calling the function multiple times. In fact, even in the given example, the function would have to be called twice since currentMillis
appears twice in the loop.
As far as memory goes, an unsigned long uses very little.
if (millis() > interval) do_something; a_function_that_takes_10ms(); if (millis() > interval) do_something_else;
I'd like the do_something_else to be executed always after do_something. If I store the millis value, this is correct, otherwise who knows..