It would normally be better programming practice to set a variable to millis() just once in a loop not to reduce the programming load but to ensure consistent timing based on the time that the value of millis() was read
Don't forget that the compiler is likely to optimise your code your code anyway
Is something in particular making you worry about the code ?
If you mean if retrieving an already loaded unsigned long value from "CurrentMillis" takes less time than the millis() call, I suppose it does. But it depends on how often you need that, if you compare a single istruction like:
if (millis() - StampMillis[9] >= 1000) {
with this single "if()":
CurrentMillis = millis();
if (CurrentMillis - StampMillis[9] >= 1000) {
the answer is obviously NO. If you mean repeately using CurrentMillis, updated once like this:
CurrentMillis = millis();
for (int i=0; i<50; ++i) {
if (CurrentMillis - StampMillis[i] >= 1000) {
..do something...
}
}
I guess the answer could be YES. But IDK the CPU time you save this way (and don't know how critical it is), you should try and see using some microseconds() measuring and comparing...
That was the approach that I was suggesting using one common value for currentMillis throughout each iteration of loop()
Of course, without knowing exactly what the code does in each function it is impossible to say whether it is the correct approach. For instance, if fn1() takes one millisecond to run then when fn2() runs currentMillis will be out of date
I normally use millis() directly rather than making a currentMillis variable, It's just simpler (at least at the "C++ level").
If you use currentMillis more than once, some time has passed and it may no longer be perfectly accurate. In some cases that could be OK, or it might even be desirable to hold currentMillis constant for a short period of time and in other cases you might want to have a more accurate value.
It would probably be even better to use a for loop to iterate through StampMillis, but as we don't know the actual application we can't tell. For all we know the conditions could be mutually exclusive and if/else might be more appropriate
I typically set up a frame rate, say 50 frames per second.
My loop, in the getting stuff done part, only visits the all the functions once every 20 ms.
They all run within the window, but some may be way off the mark, say 11 or 17 ms after the frame begins.
But I want all participants to be operating off the one true idea of now which was the frame beginning millis() reading. And as may have been mentioned, the frozen reading of inputs that inform the logic.
Trouble in this case is over-running the 20 ms allowance for getting everything done. That can be determined with a few lines of code in the loop() and used to raise an appropriate alarm.
The value returned by millis() is already stored in a private variable created by the core library code. I suspect the compiler optimises any millis() call to a simple load direct from that variable. Copying it to another variable and then using that variable won't help much.
You could shave a bit of time off by doing the calculations once when storing the start time, then only doing a simple comparison every time you check. It would save you one subtraction operation every time you check. For example:
stampMillisEnd[9] = millis()+delay9;
and then your check becomes:
if ( millis() >= stampMillisEnd[9] ) {
Depending on your hardware, that may save you as little as one clock cycle per check, or as many as seven or eight. It's not really a whole lot. If the timing of your code is that close to the limits of the hardware, you may want to consider stepping up to higher performance hardware rather than trying to save every possible processor cycle.
If your one second task never takes more than one second, there is no difference between
startMillis += interval;
and
startMillis = millis();
On the other hand, should your task over run the interval allowed, there is a difference, and therefor a decision to be made in the circumstances.
Adding the interval to will do make up calls on no schedule but as fast as it can until it catches up to real time.
Setting the new start time to millis() will result in no rapid firing, but possibly missed calls.
So at the end of a larger period of time with a few overruns, the adding method will report the same number of calls as if there were no overruns, whilst the millis() will call the function but never more frequently than once a second, and report at the end a number less than expected, reflecting of skipped calls.
It's easier to see in action, which may call for a wokwi when I am, well, not just now let us say.
No, no dispute, not disputational here. The key is: if your algo can overrun the time slice, you should know and decide what to do about it, instead of letting what happens happen.
I won't tell you why I know too much about this, let's just say I learned something that day and am lucky to have some hair left after doing.
Ykes...
First of all, I wonder why you start from "StampMillis[1]", missing the "StampMillis[0]" (array indexes start from zero!).
Second, if you have a "StampMillis" array, as it seems you make use of "StampMillis[12]" I hope you defined it for 13 elements.
Third, such program structure (apart from a bad indentation -please correct it by using Ctrl-T from Arduino IDE before posting it!-) IMHO needs a better approach to avoid "copies" of almost the same code, e.g. creating specific functions with parametric values.
Said that, I think replacing a single variable with a call to millis() will not have any visible or measurable improvement (and I don't think this kind of program could implement a time-critical mission requiring milliseconds precision).