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

You are wrong, it can easily be used in any direction
Your words prove that you don't understand the code

same direction 0 => 150 and 0 => 80

opposite 0 => 150 and 80 => 0

 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, 80 -Pos*pos4);
 HCPCA9685.Servo(4, 80- Pos*pos4);
 HCPCA9685.Servo(7, 80- Pos*pos4);
 HCPCA9685.Servo(10, 80- Pos*pos4);
 delay(10);
 }
1 Like

no this isn't the problem

#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=pos2 ; Pos< pos3; Pos++)
   {
 HCPCA9685.Servo(9, Pos);
 delay(10);
 }

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

here are two for loops. what is your offer for this?

Exactly the same as in your first message. Are you expecting that the forum will provide solution for your EVERY task?

Try to do at least something yourself. Your case is no different from the example by @kolaha , as I demonstrated to you in the #22

Don't think of your problem as two for loops that you want to do at the same time. Instead think of it as two motions that each make a step in opposite directions at the same time.

Then look at the math in this one for loop:

1 Like

Yes!
Exactly the same as solution, provided by @kolaha
@alija22 problem is that our help is of no use to him - he did not understand the first answer, but simply thoughtlessly copied it. Now, in the next problem, barely more variable names have changed - and thatā€™s it, he canā€™t solve anything and is again at a dead end.
Thatā€™s why I donā€™t want to give him a ready-made answer again - let him try to figure it out himself.

1 Like

here's a sim that uses tables describing the servos and sets of positions. the tables can easily be expanded without changing any logic. the positions may drive servos in opposite directions

driveServo () determines the servo that needs to move the most and then determines the # of iterations and the step (angle) for each servo.

servoSet() simply prints the sero position to move to and needs to be updated with the pcs9685 sub-function to drive the servo


char t [90];

// -----------------------------------------------------------------------------
struct Servo {
    byte        Pin;
    const char *desc;

    int         pos;
    int         delta;
    int         step;
}
servo [] = {
    { 6, "s6" },
    { 7, "s7" },
    { 8, "s8" },
    { 9, "s9" },
};
const int Nservo = sizeof(servo)/sizeof(Servo);

// -------------------------------------
struct Pos {
    int         posServo [Nservo];
    const char *desc;
}
pos [] {
    {{   0,   0,   0,   0}, "zero" },
    {{  10,  60, 110, 180}, "delta" },
    {{ 180, 180, 180, 180}, "max" },
};
const int Npos = sizeof(pos)/sizeof(Pos);

// -----------------------------------------------------------------------------
void
servoSet (
    int pos )
{
    sprintf (t, " %s: %3d", __func__, pos);
    Serial.print (t);
}

// -----------------------------------------------------------------------------
int MaxStep = 10;

// -------------------------------------
void
driveServo (
    int idx)
{
    sprintf (t, "%s: idx %d", __func__, idx);
    Serial.println (t);

    int maxDelta = 0;
    Pos *p = & pos [idx];
    for (unsigned s = 0; s < Nservo; s++)  {
        servo [s].delta = p->posServo [s] - servo [s].pos;
        maxDelta = max (maxDelta, abs(servo [s].delta));
    }

    sprintf (t, " %s: maxDelta %d", __func__, maxDelta);
    Serial.println (t);

    int nStep = maxDelta / MaxStep;
    if (0 == nStep)
        return;

    for (unsigned s = 0; s < Nservo; s++)  {
        servo [s].step = (int) ( servo [s].delta / nStep);
        sprintf (t,
            "   %s: delta %4d, pos %4d, target %4d, step %4d", "drServo",
            servo [s].delta, servo [s].pos, p->posServo [s], servo [s].step);
        Serial.println (t);
    }


    sprintf (t, " %s: nStep %d", __func__, nStep);
    Serial.println (t);

    for (int n = 0; n < nStep -1; n++) {
        for (unsigned s = 0; s < Nservo; s++)
            servoSet (servo [s].pos += servo [s].step);
        Serial.println ();
    }

    for (unsigned s = 0; s < Nservo; s++)
        servoSet (servo [s].pos = p->posServo [s]);
    Serial.println ();
}

// -----------------------------------------------------------------------------
int idx = 0;
void loop ()
{
    driveServo (idx);

    if (Npos <= ++idx)
        idx = 0;
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);
}

1 Like

yeah, @alija22's math is wrong, no subtraction from 80...

make your two loops functions then call them from loop();

Maybe so, but the idea is good--command some servos to move in the opposite direction as trh first set.

Maybe a better way to do the math would be to think about computing the positions for both sets based on the count in the for loop. This advice is good:

yeah, the map function does make things easier, I personally use plain math to do it, for example: uint8_t brightness = 255-darkness;

1 Like

i think you don't understand the problem and you insist on your wrong words

If so, I hardly could offer solution to you.
Good luck to your project.

1: they can only turn by 80Ā° like that.
2: I'd put parentheses around the calculations,
like this:

 HCPCA9685.Servo(5, Pos);
 HCPCA9685.Servo(8, Pos);
 HCPCA9685.Servo(11, Pos);
 HCPCA9685.Servo(1, 80 - (Pos*pos4));
 HCPCA9685.Servo(4, 80 - (Pos*pos4));
 HCPCA9685.Servo(7, 80 - (Pos*pos4));
 HCPCA9685.Servo(10, 80 - (Pos*pos4));

Are you saying that these two lines will give different results?

yup, it'll now calculate Pos*pos4 before subtracting from 80, rather then subtracting Pos from 80 then multiplying that by pos4.

Please read something about priority of operations.
With or without parentheses, multiplication is done first.

2 Likes

If you don't believe it, just run the example

int x = 80 - 20*4;
int y = 80 - (20*4);
Serial.println(x);
Serial.println(y);
1 Like

yeah, sorry, I forgot about PEMDAS.

1 Like