Trying to add a delay into Millis that is used by multiple processes

Hi all. First time posting so i hope I get the etiquette right, please point out if i don’t!

Basically I have very limited programming knowledge (basic VBA, HTML, CSS etc, so i’m still trying to get my head around the whole “loop” aspect!) and because of that i tend to think i can do much more than i can, but honestly i thought this would be relatively simple. And unfortunately, yes i am one of these people who finds a code on the internet and hacks it to bits, but i am intending learning from the ground up after this mini project as it annoys me that i can’t get simple things to work.

I am building a simple animatronic fish that i want to run through pre-programmed actions, basically the fins to flap constantly and slowly, eyes to blink every 5-10 seconds, eyes to move left and right every 5-20 seconds, and the mouth to open and close slightly every x seconds (not decided on this yet).

So i have 4 servos controlling that, and i’m trying to get the code to run it for me. Hardware wise i literally am just running one servo at a time to get each sequence working before i sort out the proper wiring, but i’m just going to power the servos separately to the arduino (nano clone). Currently the servo is wired direct to the arduino for ease.

I found a code which slows down the servo movements and i have it all set up to move the servos at the speed i want, the distance i want, but what i need to do now is put in a delay for certain actions to only run once every x seconds while others run constantly.

#include <Servo.h> 

class Sweeper
{
  Servo servo;              // the servo
  int pos;              // current servo position 
  int increment;        // increment to move for each interval
  int  updateInterval;      // interval between updates
  unsigned long lastUpdate; // last update of position
 
public: 
  Sweeper(int interval)
  {
    updateInterval = interval;
    increment = 1;
  }
  
  void Attach(int pin)
  {
    servo.attach(pin);
  }
  
  void Detach()
  {
    servo.detach();
  }
  
/*  void Updatefins(int limit)
  {
    if((millis() - lastUpdate) > (updateInterval))  // time to update
    {
      lastUpdate = millis();
      pos += increment;
      servo.write(pos);
     // Serial.println(pos);
      if ((pos >= limit) || (pos <= 0)) // end of sweep
      {
        // reverse direction
        increment = -increment;
      }
    }
  }*/


void Updatelids(int limit)
  {
    if((millis() - lastUpdate) > (updateInterval + lidswait))  // time to update
    {
      int lidswait = 0;
      lastUpdate = millis();
      pos += increment;
      servo.write(pos);
     // Serial.println(pos);
      if ((pos >= limit) || (pos <= 0)) // end of sweep
      {
        // reverse direction
        increment = -increment;
      }
      if (pos == 0)
      {
        Serial.println("lids");
        int lidswait = 10000;
      }
    }
  }
};

Sweeper fins(50);
Sweeper lids(0);
Sweeper eyes(0);
Sweeper mouth(0);

void setup() 
{ 
  Serial.begin(9600);
  //fins.Attach(9);
  lids.Attach(9);
  //eyes.Attach(9);
  //mouth.Attach(9);
 int lidswait = 0;
} 

void loop() 
{ 
  //fins.Updatefins(90);
  lids.Updatelids(90);
  //eyes.Updateeyes(90);
  //mouth.Updatemouth(90);
}

There are another 2 sections which i have removed for ease, but these are just copies of the first commented out section (updatefins) which i have left in there so you can see what works. basically the Updatelids section i added in an int lidswait = 10000; when the servo position reaches 0, and this happens, but when i add lidswait to the updateinterval, it doesn’t seem to add in a delay.

So what i expect to happen is:
Updatelids > move servo to 90
Updatelids > move servo to 0 > set lidswait to 10000
Updatelids > still within 10000 ms of last movement
after 10s
Updatelids > greater than 1000ms of last movement > set lidswait to 0 > move servo to 90
and continue

I’m either missing something in the sequence which actually resets updatelids to 0 immediately after setting it to 10000, or i’m not referencing it correctly. any help?

Thanks in advance all!

Edit: I should clarify the “used by multiple processes”, you will see from the code that the 4 processes i want (fins, eyes, lids and mouth) all use the same lastupdate and updateinterval which ideally i’d like to keep, purely to make it easier to play with

The code cannot work, because "lidswait" is redeclared every time you set it's value and when is is used in the "if" statement, it is out of scope. "lidswait" should be declared as a class variable/member.

      if (pos >= limit)
         increment = -abs(increment);

      if (pos <= 0) // end of sweep
         increment = abs(increment);

      if (pos == 0)
      {
        Serial.println("lids");
        int lidswait = 10000;
      }

probably more safe

yuebeifong: if (pos == 0)       {         Serial.println("lids");         int lidswait = 10000;       }

probably more safe

Which bug do you spot here?

Danois90: The code cannot work, because "lidswait" is redeclared every time you set it's value and when is is used in the "if" statement, it is out of scope. "lidswait" should be declared as a class variable/member.

It's always the simple things with me! so having just looked it up, i moved the int lidswait = 0 to just under the include servo.h and now it works! i could have sworn that i had already tried this but i think that might have been because i had "int" infront of it each time, is that right?

Also, thank you!

jimskio: It's always the simple things with me! so having just looked it up, i moved the int lidswait = 0 to just under the include servo.h and now it works! i could have sworn that i had already tried this but i think that might have been because i had "int" infront of it each time, is that right?

Also, thank you!

That is not the right place for it to be either. What you have done is to declare "lidswait" as a global variable which will be shared by all instances of "Sweeper". What you want is to give each instance of "Sweeper" its own copy of "lidswait" by declaring it in the same section as "pos", "increment" and so on. This will ensure that one instance of "Sweeper" does not affect all other instances.

Danois90: That is not the right place for it to be either. What you have done is to declare "lidswait" as a global variable which will be shared by all instances of "Sweeper". What you want is to give each instance of "Sweeper" its own copy of "lidswait" by declaring it in the same section as "pos", "increment" and so on. This will ensure that one instance of "Sweeper" does not affect all other instances.

Thanks, I think I know what you mean as i initially tried that before, i just wasn't sure if i could reference that particular sweeper when i wanted to change it. I think i'll finish it off the way i currently have it since it seems to work (i will be using a different "wait" variable for each servo) and then when i know i have something that works, albeit essy, i can then look at making it more streamlined. Thanks for your help, i'm sure i'll be back again in the not too distant future!