1

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.

asked May 2, 2021 at 10:23
3
  • 1
    How do you want the functions to be called in order? Like "1,2,3,4 ... 1,2,3,4" or like "1...1,2...1,2,3...1,2,3,4...1...1,2..."? Commented May 2, 2021 at 11:01
  • 1
    Like '1234' order Commented May 2, 2021 at 11:03
  • why with else? why only one then? Commented May 2, 2021 at 13:54

2 Answers 2

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.

answered May 2, 2021 at 11:26
1
  • Nah, my bad, missed the scope of the index update. Commented May 4, 2021 at 3:33
0

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.

answered May 2, 2021 at 10:26
2
  • your code will result in sequence 1, 1, 2, 1, 2, 3, 1, 2, 3, 4 Commented 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 the thing gets executed. Commented May 2, 2021 at 17:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.