I am working in a project where I need to call more than 1 functions actually 4 functions using a single millis()
Here is the code below.
unsigned long then = 0;
void loop(){
unsigned long now = millis();
if(now-then >=0){
Serial.println("Function 1 called");
}else if(now-then>=2000){
Serial.println("Function 2 called");
}else if(now-then>=4000){
Serial.println("Function 3 called");
}else if(now-then>=6000){
Serial.println("Function 4 called");
Serial.println("The end");
then = now;
}
}
All the functions above gets run successfully but not in a proper sequence.
The running sequence of the functions seem to be very improper and random.
The 'function 1' gets executed in a proper sequence and timing but rest of the others are making a messy output.
How can I fix it please?
Thanks.
2 Answers 2
The current structure with multiple if statements and on timestamp variable does only work, if you also check for millis()-then
being smaller than the next interval. Otherwise the first if statement will always be executed.
I think it gets easier, when you use only one if statement, but put the intervals in an array. In that if statement you can either use a switch
statement to execute the code for the corresponding interval, or use a function pointer. Somewhat like this (untested):
unsigned long then = 0;
unsigned long intervals[4] = {0, 2000, 4000, 6000};
int current_interval_index = 0;
...
void loop(){
unsigned long now = millis();
if(now-then >= intervals[current_interval_index]){
switch(current_interval_index){
case 0:
Serial.println("Function 1");
break;
case 1:
Serial.println("Function 2");
break;
case 2:
Serial.println("Function 3");
break;
case 3:
Serial.println("Function 4");
break;
}
then = now;
current_interval_index = (current_interval_index + 1) % 4; // increment index and wrap it back to zero, if it goes to 4
}
}
That way you can easily extent for more functions and the intervals are conveniently managed in an array. Note, that the intervals add up here. So function 4 executes after 2s+3s+6s = 11s.
-
Nah, my bad, missed the scope of the index update.SoreDakeNoKoto– SoreDakeNoKoto2021年05月04日 03:33:59 +00:00Commented May 4, 2021 at 3:33
your else
in that set of if
's is causing only a single if to be possible to be true at any one time, and once the now-then
line up, only the first one in the line-up will ever execute. remove the else
from your if block. treat each if as its own thing. i.e.
if(now-then >=0) { /* do thing 1*/ }
if(now-then >=1000) { /* do thing 2*/ }
if(now-then >=2000) { /* do thing 3*/ }
if(now-then >=3000) { /* do thing 4*/ }
that way, even if the conditions line up, all the blocks will be checked, and all the if
's that resolve true, will execute.
-
your code will result in sequence 1, 1, 2, 1, 2, 3, 1, 2, 3, 4jsotola– jsotola2021年05月02日 17:01:07 +00:00Commented May 2, 2021 at 17:01
-
You need a stamp for every
thing x
because you'll have to reset each of them to the current millis when thething
gets executed.Sim Son– Sim Son2021年05月02日 17:25:39 +00:00Commented May 2, 2021 at 17:25
else
? why only onethen
?