Start a function before the previous function has finished

Hi I am after a way to start a function then wait a set amount of time (delay) then start the next function before the first one is finished.
However as I understand the normal way the code works is it would start the function complete that function then wait the delay amount then start and finish the next function.
Is there a way to accomplish this?
The functions I want to do this to is
RightWingFoward();
delay(StagerDelayVal);
LeftWingFoward();
So it would start the function RightWingFoward() then wait the delay(StagerDelayVal) then start the function LeftWingFoward() even if the function RightWingFoward() has not finished.
in the code below.
p.s. The functions do not have to stay as functions I only did this as they will be used around 6 times each once the program is finished.
Not sure if there is a way to do this but any help would be greatly appreciated.

 #include <Servo.h>
 
 boolean FirstTime;
 //Variables
 int WingFoldRightRead=0;
int WingFoldLeftRead=0;

 //Analog inputs
 int FoldSpeed=0;
 int FoldSpeedVal=0;
 
 int StagerDelay=1;
 int StagerDelayVal=0;
 
 
//Digital inputs/outputs (0 and 1 not able to be used as servo controls)
int Gear=2;      //Set Gear to pin2
int GearVal=0;

int AUX3=3;      //Set AUX3 to pin3
int AUX3Val=0;

int LeftRev=4;  //Set LeftRev to pin 4
int LeftRevVal=HIGH;

int RightRev=5;  //Set RightRev to pin 5
int RightRevVal=HIGH;

int LockRev=6;   //Set LockRev to pin 6
int LockRevVal=HIGH;

int StagerEnable=7;  //Set StagerEnable to pin 7
int StagerEnableVal=HIGH;

//Counters
int Timer=0;   //Used as a 5 sec timer in loop
int WingFoldCount=0;  //Wing fold counter

//Servos used
Servo WingFoldLeft;  //Create a servo object
Servo WingFoldRight; //Create a servo object
Servo WingFoldLock;  //Create a servo object

void setup(){
  FirstTime=true;
   
pinMode(StagerDelay, INPUT);
pinMode(FoldSpeed, INPUT);
pinMode(AUX3, INPUT);
pinMode(Gear, INPUT);
pinMode(LeftRev, INPUT);
pinMode(RightRev, INPUT);
pinMode(LockRev, INPUT);
pinMode(StagerEnable, INPUT);

WingFoldRight.attach(4); //Attach Right wing fold servo
WingFoldRight.write(10);


WingFoldLock.attach(5);  //Attach wing lock servo
WingFoldLock.write(10);

WingFoldLeft.attach(6);  //Attach left wing fold servo
WingFoldLeft.write(10);
}
 
 void loop(){
  GearVal=pulseIn(Gear, HIGH, 25000);      //Read RX Gear position
  AUX3Val=pulseIn(AUX3, HIGH, 25000);      //Read RX AUX3 position
  
  StagerDelayVal=analogRead(StagerDelay);  //Read the value for the stager delay
  StagerDelayVal=map(StagerDelayVal,0,1023,0,5);  //Scales input from Analog pin 0 to a value to be used as a time for the stager delay
  
  FoldSpeedVal=analogRead(FoldSpeed);      //Read the value for the folding speed
  FoldSpeedVal=map(FoldSpeedVal,0,1023,0,100);    //Scales input from 1 to 100, Change value of 100 to change speed, Increase 100 to decrease speed and decrease 100 to increase speed.

   Timer++;
  delay(500);   //Set timer to 5 sec
  if(Timer>10){
    Timer=0;
    WingFoldCount=0;
  }
  if(AUX3Val>1700&&GearVal<1500) {
   if(FirstTime){              //Only allows wingfoldcount to go up by 1 
     WingFoldCount++;
     FirstTime=false;
   }
  Timer=0;
}
else (FirstTime=true);          //Reset flag

//Set servo read values
LockRevVal=digitalRead(LockRev);
RightRevVal=digitalRead(RightRev);
LeftRevVal=digitalRead(LeftRev);

if(RightRevVal==LOW&&LeftRevVal==LOW&&StagerEnableVal==HIGH){    //Both left and right wings foward and stager Enabled  Right wing, Stager, Left wing
RightWingFoward();
delay(StagerDelayVal);
LeftWingFoward();
 }
 }
 
 //Functions
 void RightWingFoward(){                            //Fold right wing with servo in normail direction
   int WingFoldRightRead=WingFoldRight.read();
       while(WingFoldRightRead<180){             //Runs servo in foward direction
       delay(FoldSpeedVal);                            //Runs servo from 0 to 180 deg at a speed of 5 deg for every FoldSpeedVal
       WingFoldRight.write(WingFoldRightRead+5);
     }}
     
 void LeftWingFoward(){                            //Fold left wing with servo in normail direction
   int WingFoldLeftRead=WingFoldLeft.read();
       while(WingFoldLeftRead<180){              //Runs servo in Foward direction 
       delay(FoldSpeedVal);                           //Runs servo from 0 to 180 deg at a speed of 5 deg for every FoldSpeedVal
       WingFoldLeft.write(WingFoldLeftRead+5);
     }}

Hi I am after a way to start a function then wait a set amount of time (delay) then start the next function before the first one is finished.

Then, do not use delay(). Read, understand, and embrace the blink without delay example.

Thank you
I thought though that the program would run through all of the RightWingFoward() function before is went on to do the delay (now using milli) then run through the LeftWingFoward() function. Is this not the case? Meaning that it would in fact start the RightWingFoward() function then go onto the delay(milli) then the LeftWingFoward() even though the RightWingFoward() function has not finished?

   Timer++;
  delay(500);   //Set timer to 5 sec

This does not set the timer to 5 seconds. It delays (not doing anything else) for 0.5 seconds.

else (FirstTime=true);          //Reset flag

The round brackets are confusing here. Use curly brackets, please.

 int WingFoldRightRead=WingFoldRight.read();
       while(WingFoldRightRead<180){             //Runs servo in foward direction
       delay(FoldSpeedVal);                            //Runs servo from 0 to 180 deg at a speed of 5 deg for every FoldSpeedVal
       WingFoldRight.write(WingFoldRightRead+5);
     }}

How will WingFoldRightRead change inside that loop?

Timer++;

delay(500);  //Set timer to 5 sec



This does not set the timer to 5 seconds. It delays (not doing anything else) for 0.5 seconds.

Allong with the two lines of code below it it does set a delay for 5 seconds.

 if(Timer>10)
 Timer=0;

Not technically a timer but does what I need here as it has to be reset to 0 depending on other conditions, being reasonably new to arduino I do not know of any other way to achieve this.

int WingFoldRightRead=WingFoldRight.read();

while(WingFoldRightRead<180){            //Runs servo in foward direction
      delay(FoldSpeedVal);                            //Runs servo from 0 to 180 deg at a speed of 5 deg for every FoldSpeedVal
      WingFoldRight.write(WingFoldRightRead+5);
    }}




How will WingFoldRightRead change inside that loop?

Not quiet sure what you mean here (only a newbie). Do I need to include

int WingFoldRightRead;
Servo WingFoldRight; //Create a servo object

in this function as well? or use something other than void as the returntype?

It's nothing to do with the return type, it's to do with the fact that "WingFoldRightRead" is never assigned a new value in the while loop, potentially making this an infinite loop.

It's nothing to do with the return type, it's to do with the fact that "WingFoldRightRead" is never assigned a new value in the while loop, potentially making this an infinite loop.

So something like this?

 void RightWingFoward(){ 
      int WingFoldRightRead=WingFoldRight.read();
       while(WingFoldRightRead<180){             //Runs servo in foward direction
       delay(FoldSpeedVal);                            //Runs servo from 0 to 180 deg at a speed of 5 deg for every FoldSpeedVal
       WingFoldRight.write(WingFoldRightRead+5);
         WingFoldRightRead=WingFoldRight.read();
     }}

Something like that, yes, but without the delay, which probably means that the explicit "while" disappears entirely.

And without the two closing braces on the same line.

Why without the delay? as that is part of what I am using to set the delay between writes and thus setting the speed of rotation of the servo. Or are you suggesting to use the millis() method instead of the delay() method.
Yes will fix the two closing brackets.

Why without the delay?

Because using "delay" will stop you being able to do more than one thing at once, which is what I understood the title of this thread to be about.

Ah ok then sorry as I said still still new here.
How does this look?
Still trying to get my head around this way of doing a "delay".

variables declared outside void setup and void loop

long SpeedDelay=FoldSpeedVal;          //A value of 0 to 100 milliseconds [interval]
 long PreviousRightFowardMillis=0;     //Used to save the last time WingFoldRight was read 
 unsigned long CurrentMillis=millis(); //Milliseconds from start of program

And then the function

 //Fold right wing with servo in normal direction
 void RightWingFoward(){                                          //Runs servo in foward direction    
   int WingFoldRightRead=WingFoldRight.read();                    //Reads location of right wing servo
       while(WingFoldRightRead<180){ 
         //Runs servo from 0 to 180 deg at a speed of 5 deg for every FoldSpeedVal
         if(CurrentMillis-PreviousRightFowardMillis>SpeedDelay){  //Should replace [delay(FoldSpeedVal);] 
         PreviousRightFowardMillis=CurrentMillis;                 //Save the time last time WingFoldRight was read                            
       WingFoldRight.write(WingFoldRightRead+5);
         WingFoldRightRead=WingFoldRight.read();                  //Reads position of servo after being moved
     }
   }
 }

grantastley:

Timer++;

delay(500);   //Set timer to 5 sec



This does not set the timer to 5 seconds. It delays (not doing anything else) for 0.5 seconds.

Allong with the two lines of code below it it does set a delay for 5 seconds.

In what way?

   Timer++;
  delay(500);   //Set timer to 5 sec
  if(Timer>10){
    Timer=0;
    WingFoldCount=0;
  }

In what way?

this is a timer on the whole loop so to say
Each time the program goes through the loop the Timer gets incremented by 1 Timer++; then there is a delay of 0.5 seconds delay(500) once the timer is greater than 10 (10*.5=5 seconds) it is reset to 0

if(Timer>10){
    Timer=0;

What this does is only allow 5 seconds (roughly does not need to be 100% accurate as it takes time do go through the rest of the code) for the rest of the code to with "timed" limits to work.

Run the sketch below the count is reset roughly every 5 seconds and updated every 0.5 seconds

int Count=0;
void setup(){
    Serial.begin(9600);
}
void loop(){
Serial.print("Count = ");
  Serial.println(Count);
Count++;
  delay(500);
  if(Count>10){
    Count=0;
  }
}

However now I know that there is a better way to do this using millis() I will try adapt it to work with that method.
That is if I have the millis() method right in my last post above? Other wise I will have to do more research on that method.

No, while is a blocking statement, so don't use while loops. Also, fix your horrid indenting. The Arduino IDE has an auto format tool that I recommend taking full advantage of.

Sounds like you want co-operative multithreading. I implemented this kind of lib while ago for PC but the code is platform agnostic and should be portable to Arduino as well. It can be useful for this kind of scripting. The problem is that you can't call delay() or such because it blocks the execution, but have to implement delays in different manner which allow other pieces of code to execute meanwhile. The basic gist is that you need to implement delay (and other yielding ops) in non-blocking way and jump back where you yield last time in the next loop to check if you should continue execution. You probably don't need this kind of generic solution, but that's essentially the problem you try to solve.

If you want your sketch to control multiple things simultaneously then the best way to implement it IMO is to design your sketch to be non-blocking. This means making widespread but relatively simple changes to the structure of your original, blocking, code. Instead of writing code so that it stops and waits for something to happen (time to pass, input events to occur) you write code that tests whether something has happened and handles it when it happens. The blink without delay example sketch provides a trivial example of this approach, but you can use the approach for anything that you need to do in your sketch, for example handling input/output pins, receiving serial port data, receiving network data, driving display devices and servos and so on.

When you design your code to be non-blocking you can implement your solution with lots of simple isolated pieces of code that have minimal dependency on each other and don't require a complicated framework to enable them to run concurrently.

That will work for about 60 days, until millis() rolls over. I've written a simple function that I think should return the correct number of elapsed milliseconds even when millis() rolls over.

Can someone put another pairs of eyes on this and see if this handles the rollover correctly?

unsigned long
elapsedTime (unsigned long ticks)
{
// ticks is the time we're checking
  unsigned long tnow;
  tnow = millis ();
  if (tnow < ticks)
    // we've rolled the clock
    return (0xffffffffu - ticks) + tnow;
  else
    return tnow - ticks;
}

cptdondo:
That will work for about 60 days, until millis() rolls over.

What will work?

The code in the link I provided always works. This general idea:

if ( (millis () - startTime) >= wantedInterval) ...

That handles rollover correctly.

(edit) You have to use unsigned long for startTime.

cptdondo:
That will work for about 60 days, until millis() rolls over.

It's actually about 49.7 days until it rolls over. Of course, just because it rolls over, doesn't mean it stops working.