I want two for-loops to run at the same time

I want two for-loops to run at the same time, but it's not possible. Can anyone help me? this is my code

#include "HCPCA9685.h"
 
/* I2C slave address for the device/module. For the HCMODU0097 the default I2C address
 
is 0x40 */
 
#define  I2CAdd 0x40
int pos1=0;
int pos2=100;
int pos3=200; 


int pos4=0;
int pos5=150;
/* Create an instance of the library */
 
HCPCA9685 HCPCA9685(I2CAdd);
 
void setup()

{




  /* Initialise the library and set it to 'servo mode' */
 
HCPCA9685.Init(SERVO_MODE);
 
  /* Wake the device up */
 
HCPCA9685.Sleep(false);
 
  unsigned int Pos;

  HCPCA9685.Servo(2, 0);
  HCPCA9685.Servo(5, 0);
  HCPCA9685.Servo(8, 0);
  HCPCA9685.Servo(11, 0);

 HCPCA9685.Servo(1, 0);
 HCPCA9685.Servo(4, 0);
 HCPCA9685.Servo(7, 0);
 HCPCA9685.Servo(10, 0);



  HCPCA9685.Servo(0, 100);
  HCPCA9685.Servo(3, 100);
  HCPCA9685.Servo(6, 100);
  HCPCA9685.Servo(9, 100);

  for(Pos = 0; Pos< 150; Pos++)
   {
 HCPCA9685.Servo(2, Pos);
 HCPCA9685.Servo(5, Pos);
 HCPCA9685.Servo(8, Pos);
 HCPCA9685.Servo(11, Pos);
 delay(10);
 }
 
  for(Pos = 0; Pos< 80; Pos++)
   {
 HCPCA9685.Servo(1, Pos);
 HCPCA9685.Servo(4, Pos);
 HCPCA9685.Servo(7, Pos);
 HCPCA9685.Servo(10, Pos);
 delay(10);
 }









    
// #
//    for(Pos = pos3; Pos>pos2; Pos-- && Pos = pos1; Pos<pos2; Pos++)
//    {
//  HCPCA9685.Servo(0, Pos);
//  HCPCA9685.Servo(3, Pos);
//    }





}
 
void loop()
 
{
 

Your two loops has a different duration, so it can't be run at the exact same time. Be more specific in explanation of your needs.

As your topic does not relate directly to the installation or operation of the IDE it has been moved to the Programming Questions category of the forum

Are you trying to get two servos to run in opposite directions at the same time ?

for loop #1 takes roughly 150x10ms = 1.5s
for loop #2 takes roughly 80x10ms = 0.8s

do you want the servos to end up at their final position at the same time or it's OK for the second loop to end early ?

if the latter is OK, then you can just merge both loops and test if Pos has reached 80

for(Pos = 0; Pos< 150; Pos++)   {
  HCPCA9685.Servo(2, Pos);
  HCPCA9685.Servo(5, Pos);
  HCPCA9685.Servo(8, Pos);
  HCPCA9685.Servo(11, Pos);

  if (Pos < 80) {
   HCPCA9685.Servo(1, Pos);
   HCPCA9685.Servo(4, Pos);
   HCPCA9685.Servo(7, Pos);
   HCPCA9685.Servo(10, Pos);
 }
 delay(10);
}

if you want both of them to arrive at the same time, you could use millis() and the map() function to calculate positions over time

here is an example on how to do this linear interpolation

struct Timing {
  const char * name;
  int startPos;
  int endPos;
  int currentPos;
};

Timing servoTimings[] = {
  {"servo1", 0, 149, 0},
  {"servo2", 0, 79, 0}
};
const byte count = sizeof servoTimings / sizeof * servoTimings;

const unsigned long duration = 1500;
unsigned long startTime;

void setup() {
  Serial.begin(115200);
  for (auto & st : servoTimings) st.currentPos = st.startPos;
  startTime = millis();
}

void loop() {
  if (millis() - startTime <= duration) {
    for (auto & st : servoTimings) {
      int newPos = map(millis() - startTime, 0, duration, st.startPos, st.endPos);
      if (st.currentPos != newPos) {
        st.currentPos = newPos;
        Serial.print(st.name); Serial.write('\t'); Serial.println(newPos);
      }
    }
  } else {
    Serial.println("Done");
    while (true) yield(); // dies here
  }
}

Work through these pages. The solution you're after is about the fifth page in, but it's really worth the time working through and understanding what's going on.

#include "HCPCA9685.h"
/* I2C slave address for the device/module. For the HCMODU0097 the default I2C address is 0x40 */

#define  I2CAdd 0x40
const int pos1 = 0;
const int pos2 = 100;
const int pos3 = 200;
const float pos4 = 80.0 / 150.0;
const int pos5 = 150;
/* Create an instance of the library */

HCPCA9685 HCPCA9685(I2CAdd);

void setup() {
  /* Initialise the library and set it to 'servo mode' */
  HCPCA9685.Init(SERVO_MODE);
  /* Wake the device up */
  HCPCA9685.Sleep(false);
  int Pos;

  HCPCA9685.Servo(2, pos1);
  HCPCA9685.Servo(5, pos1);
  HCPCA9685.Servo(8, pos1);
  HCPCA9685.Servo(11, pos1);

  HCPCA9685.Servo(1, pos1);
  HCPCA9685.Servo(4, pos1);
  HCPCA9685.Servo(7, pos1);
  HCPCA9685.Servo(10, pos1);

  HCPCA9685.Servo(0, pos2);
  HCPCA9685.Servo(3, pos2);
  HCPCA9685.Servo(6, pos2);
  HCPCA9685.Servo(9, pos2);

  for (Pos = pos1; Pos < pos5; Pos++)
  {
    HCPCA9685.Servo(2, Pos);
    HCPCA9685.Servo(5, Pos);
    HCPCA9685.Servo(8, Pos);
    HCPCA9685.Servo(11, Pos);
    HCPCA9685.Servo(1, Pos * pos4);
    HCPCA9685.Servo(4, Pos * pos4);
    HCPCA9685.Servo(7, Pos * pos4);
    HCPCA9685.Servo(10, Pos * pos4);
    delay(10);
  }
}

void loop() {}

can you post this lib? where you got it?

1 Like

yes bro

thank you.its OK for the second loop to end early.

thanks

1 Like

thank you kolaha. my problem was solved with your code.

To move two servos in opposite directions you only need a single for loop

For example, if the range of movement is 180 then the for loop would run from 0 to 180. You would write the for loop value to one servo and 180 minus the for loop value to the other

As you have changed the code in your original post I will leave it to you to work out the appropriate value for the for loop for the angles that you require

1 Like

Are you understand the solution? If you will experience the similar problem in the future, would you able to adapt the code?

yes of course

thank you ukhelibob

Is there a solution for two For loops in opposite directions? I want both loops to work at the same time.

#include "HCPCA9685.h"
 
/* I2C slave address for the device/module. For the HCMODU0097 the default I2C address
 
is 0x40 */
 
#define  I2CAdd 0x40
int pos1=0;
int pos2=100;
int pos3=200; 
int pos5=150;
const float pos4=80.0/pos5;

/* Create an instance of the library */
 
HCPCA9685 HCPCA9685(I2CAdd);
 
void setup()

{
  /* Initialise the library and set it to 'servo mode' */
 
HCPCA9685.Init(SERVO_MODE);
 
  /* Wake the device up */
 
HCPCA9685.Sleep(false);
 
  unsigned int Pos;

  HCPCA9685.Servo(2, pos1);
  HCPCA9685.Servo(5, pos1);
  HCPCA9685.Servo(8, pos1);
  HCPCA9685.Servo(11, pos1);

 HCPCA9685.Servo(1, pos1);
 HCPCA9685.Servo(4, pos1);
 HCPCA9685.Servo(7, pos1);
 HCPCA9685.Servo(10, pos1);

  HCPCA9685.Servo(0, pos2);
  HCPCA9685.Servo(3, pos2);
  HCPCA9685.Servo(6, pos2);
  HCPCA9685.Servo(9, pos2);

  for(Pos = pos1; Pos< pos5; Pos++)
   {
 HCPCA9685.Servo(2, Pos);
 HCPCA9685.Servo(5, Pos);
 HCPCA9685.Servo(8, Pos);
 HCPCA9685.Servo(11, Pos);
 HCPCA9685.Servo(1, Pos*pos4);
 HCPCA9685.Servo(4, Pos*pos4);
 HCPCA9685.Servo(7, Pos*pos4);
 HCPCA9685.Servo(10, Pos*pos4);
 delay(10);
 }
 #


  for(Pos=pos2 ; Pos< pos3; Pos++)
   {
 HCPCA9685.Servo(9, Pos);
 delay(10);
 }

  for(Pos=pos2 ; Pos> pos1; Pos--)
   {
 HCPCA9685.Servo(3, Pos);
 delay(10); 
   }

is the long term goal to move more than one sero to a various positons, either direction?

yes. i want to move to servos in to opposite directions at the same time

@alija22
You said that you understood @kolaha's solution? :slight_smile: Where does this question come from then?
In which direction to move the servos - same way or in opposite - does not matter if you understand the principle

Taking an interpolation approach with the map function would basically do the math for you

3 Likes

no the directions are important. kolaha's solution can't be used in opposite direction.