Multiple Servos on different loops

Hello,

I am trying to code my Uno R3 to run six servos on separate loops. None of the loops are the same and require pauses at different intervals for different lengths of time. so

ServoOne operates on LoopOne
ServoTWo operates on LoopTwo and so on. Can someone help me figure out this coding? I can provide the individual loops in needed.

Examples of the sequences would be helpful.

There are two basic ways to do a timed sequence:

  • delay()
  • state machine

The delay() method is quick and easy... for a single sequence where your sketch has NOTHING else to do.

For two or more independent sequences you will need to use the 'state machine' method. For each sequence there is one variable that keeps track of the current state (which step of the sequence you are at) and the only thing you do in a state is determine if it is time to move to a different state. If nothing of interest has happened (could be a button press, or a time reached) you return to the caller to let it give the next state machine a chance to do something. Since the processor is very fast compared to a human it appears that all of the sequences are happening at once.

OP your thread was “hi-jacked” by one Roxy_Roxy, and the mods rightly split it since although similar in nature, the problems are not identical.

So you might like to read my posts which started here but are now here.

slamb3:
I am trying to code my Uno R3 to run six servos on separate loops

Have a look at how the code is organized in Several Things at a Time (which includes 1 servo and could easily be extended for more).

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

The code below, while not necessarily addressing OP’s needs (I’m not really sure what “None of the loops are the same and require pauses at different intervals for different lengths of time” means :wink: ) shows how a number of servos can be managed delay()-lessly with the servo details held in arrays.

The details just need to be entered between the lines marked VVVVV and ^^^^^. Each array holds a particular detail for every servo, so for example:

const byte myServoPins[] = {8, 9};

… means there’s a servo on pin 8 and another on pin 9.

This:

const byte myServoMaxPos[] = {170, 130};

… says that the first servo (myServos[0]) only ever goes as high as 170 degrees and the second (myServos[1]) reverses at 130 degrees.

To prove there is no blocking, the built in led blinks delay()-lessly.

To add more servos, just add more details in the arrays. Make sure if you have say 4 pins, all the other arrays have 4 items as well, 1 per servo. It uses sizeof(myServoPins) to figure out how many servos there are for doing the servo.attach()'s and in the later for loops.

All the servos are controlled from one function, which is called every time through loop(). Each time the function is called, it for() loops through the servos, and using the idea used in blink without delay moves the current servo one increment, or not, depending on of its interval has expired. It’s the technique used by Robin2 linked earlier, just set up for many servos in the arrays.

// delay()-less servo sweep with the servos in array and arrays for the variables (pin, speed etc)
// array of structs would be better .... maybe one day
// bwod on built in led
// 18 nov 2019
#include <Servo.h>

//these are the variables for a servo:
// pin, current position, position at which to attach, minimum allowed position,
//    maximum allowed position, timing interval, position increment per step, previous millis
//set the values below this line VVVVVVV
const byte myServoPins[] = {8, 9};
byte myServoPos[] = {0, 0}; //leave 0 0
const byte myServoAttPos[] = {90, 90}; //probably leave 90 90
const byte myServoMinPos[] = {10, 50};
const byte myServoMaxPos[] = {170, 130};
const byte myServoInterval[] = {100, 10}; //larger numbers are slower, 250 hardly notice, 10 is quick
int myServoIncrement[] = { -1, -1}; //probably leave -1 -1, it starts off "going down" from the attach pos
unsigned long myServoPrevMillis[] = {0, 0}; //leave 0 0 
//set the values above this line ^^^^^^

const byte numberOfServos = sizeof(myServoPins)/sizeof(myServoPins[0]);
Servo myServos[numberOfServos];

//the pulse led
int pulseLedInterval = 500;
unsigned long previousMillisPulse;
bool pulseState = false;

void setup()
{
  Serial.begin(9600);
  Serial.println(".... servos array ....");
  Serial.print("Compiler: ");
  Serial.print(__VERSION__);
  Serial.print(", Arduino IDE: ");
  Serial.println(ARDUINO);
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  // print each servo's parameters
  Serial.print("There are "); Serial.print(numberOfServos); Serial.println(" servos");
  for (byte i = 0; i < numberOfServos; i++)
  {
    Serial.print("Servo: "); Serial.print(i);
    Serial.print(", Pin: "); Serial.println(myServoPins[i]);
    Serial.print("  Current: "); Serial.print(myServoPos[i]);
    Serial.print(", Attach: "); Serial.print(myServoAttPos[i]);
    Serial.print(", Min: "); Serial.print(myServoMinPos[i]);
    Serial.print(", Max: "); Serial.println(myServoMaxPos[i]);
    Serial.print("  Interval: "); Serial.print(myServoInterval[i]);
    Serial.print(", Increment: "); Serial.print(myServoIncrement[i]);
    Serial.print(", Prev millis: "); Serial.println(myServoPrevMillis[i]);
  }

  //attach the servos
  for (byte i = 0; i < numberOfServos; i++)
  {
    Serial.print("Attaching servo "); Serial.print(i);
    Serial.print(" to pin "); Serial.print(myServoPins[i]);
    Serial.print(" at position "); Serial.println(myServoAttPos[i]);
    myServoPos[i] = myServoAttPos[i];
    myServos[i].write(myServoPos[i]);
    myServos[i].attach(myServoPins[i]);
  }

  //initialise pulse led
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, pulseState);
  delay(1000);

} //setup

void loop()
{
  doPulse();
  doServos();
} //loop

void doPulse()
{
  if (millis() - previousMillisPulse >= pulseLedInterval)
  {
    previousMillisPulse = millis();
    pulseState = !pulseState;
    digitalWrite(LED_BUILTIN, pulseState);
  }
} //doPulse

void doServos()
{
  for (byte i = 0; i < numberOfServos; i++)
  {
    if (millis() - myServoPrevMillis[i] >= myServoInterval[i]) //time to move?
    {
      myServoPrevMillis[i] = millis();

      if ((myServoPos[i] <= myServoMinPos[i]) || (myServoPos[i] >= myServoMaxPos[i]))
      {
        myServoIncrement[i] = -1 * myServoIncrement[i]; //change direction at limits
      }

      myServos[i].write(myServoPos[i]); //move the servo
      myServoPos[i] = myServoPos[i] + myServoIncrement[i]; //increment ready for next time
    }//millis if
  } //for over the servos
} //doServos