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()
{
b707
July 8, 2024, 11:45am
2
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 ?
J-M-L
July 8, 2024, 12:03pm
4
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.
Once you have mastered the basic blinking leds, simple sensors and buzzing motors, itβs time to move on to bigger and better projects. That usually involves combining bits and pieces of simpler sketches and trying to make them work together. The...
kolaha
July 8, 2024, 12:38pm
6
#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
thank you.its OK for the second loop to end early.
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
b707
July 8, 2024, 3:19pm
12
Are you understand the solution? If you will experience the similar problem in the future, would you able to adapt the code?
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);
}
gcjr
July 8, 2024, 4:55pm
16
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
b707
July 8, 2024, 5:28pm
18
@alija22
You said that you understood @kolaha 's solution? 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
J-M-L
July 8, 2024, 5:31pm
19
J-M-L:
int newPos = map(millis() - startTime, 0, duration, st.startPos, st.endPos);
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.