hi i'm trying to controll four servo motors to move back and forth.
i want servo 1 to start move from 40 to 140 degrees
i want servo 2 to start move from 10 to 170 degrees
i want servo 3 to start move from 170 to 10 degrees
and last i want servo 4 to start move from 140 to 40 degrees
i want them to move at the same time... or at least move servo 1 and 4 at the same time and 2 and 3 at the same time.
is this possible? have been messing around with the code below tried diffrent "int pos" values and several "int pos" values at the same time.
i'm no coder att all so this is probably easy to solve
edit: servo 1 and 4 moves as intended
Then You have lots to learn. Forum will **not ** make that code for You.
There are example codes in the IDE regarding steppers, how to do several things at the same time, using millis etc.
Cut down You project in smaller pieces and start learning by working.
Agree with @Railroader. But did you mean “ Forum will NOT make that code for You.” ?
The trick with servos is to move the first one a little bit , then the second a little bit , then the third etc etc … then move first one a bit more , then the second a bit more etc etc ..
If you want to move servo motors independent of each other and at slow speeds, then you can update them every 10ms or every 20ms.
You need to be good at math, to calculate where the servo motor should be each after interval.
Example in Wokwi (Click on the start button to start the simulation, press buttons, turn knobs):
Do you want the maximum speed of the servo motors ? Do you know how much current that could take ? Even a small cheap servo motor might require a peak current of 0.5A.
Can you tell more about the timing ?
How long should the servo motors be moving ? How much pause before they return ?
some more clarity requested. Your servos are moving different amounts - do you want them to move for the same time periods? Then you will want them to move different amounts each step, or move at different time increments. This is doable, you just need to clarify which it is.
C
The reason I ask is because you create your motion loop differently depending upon which it is. If you want each motion to move at the same speed, then a loop that changes each position variable by one degree is acceptable. If you want your motions to begin and end at the same time, then you need to have a loop that changes each position one degree, but at different time intervals. Still easy to do, but the thought process is different.
C
Suppose that all servos should start at the same time and stop at the same time, and the motion needs to be 1 minute, followed by a 5 minute pause. Then I can show how the math that is needed.
Krheigh, describing a problem from the real-world in a logical way is the hardest part of programming. Put on your coding-hat and tell us what it should do, with actual numbers.
Indeed, a good specification leads to clean code, as well. The best specification also identifies where the project will go - i.e. identifies what future demands will be made, so that the software accommodates not only the present request, but the future growth.
to clarify some i made this sketch Fusion
the movement pattern is mostly estetic
the projekt is for flow in a aqurium. if i get them to move in the estetic pattern the flow will be more turbulent when the flows hit eachother.
havn't had time yet to test the suggestions some of you gave.
There appears to be no need for the servo start and end times to be synchronised. If fact, it might be better if they weren't
How about adding some random wait periods either at the end of the servo movements or during their movements and/or random step sizes and number of steps for the servos
modified the sweep sketch from arduino ide examples with some of yor code. simulated the code in tinkercad... it seems to skip the 2nd part (//back to 40) of the code and jumps back to starting angle. i can't realiy see why
Your problem is not programming, it is math I like to throw in some math, but I would like to have some numbers.
Suppose during 5 seconds one servo should go from 50 to 110 and a other servo from 200 to 10.
It is possible to calculate the step size as a floating point number and increment that, or to calculate the position all over again every time. I choose the second option and use floating point for the calculation.
Not tested:
// 10 ms delay, 5 seconds total, that are 500 steps.
int n = 500;
for( int i=0; i<n; i++)
{
// Calculate the position of the first servo.
// offset is 50, range is 60.
float posFloat1 = 50.0 + (float(i) / float(n) * 60.0);
int pos1 = (int) posFloat1;
servo1.write(pos1);
// Calculate the position of the second servo.
// offset is 200, range is -190.
float posFloat2 = 200.0 - (float(i) / float(n) * 190.0);
int pos2 = (int) posFloat2;
servo2.write(pos2);
delay( 10);
}
It is not hard to understand. The variable 'i' goes from zero to 'n'. During that, the servo should do the range. The position is a part of the range plus the offset.
The note by UKHeliBob is important. Even a small servo motor could require 500mA peak current at the moment it starts to move. If your power supply is strong enough, then there will still be a current peak through the wires. Therefor I prefer to turn the servo motors one by one and if they turn simultaneously, then don't start them at the same time.
You mushed the two choices together to get the wrong result. Look at reply 12 again and pick one, not a mix of the two.
You originally said you want servo1 and servo4 to sweep 40 to 140 and back in opposite directions and wanted servo2 and servo3 to sweep 10 to 170 and back in opposite directions. That gives you sweeps of 100 degrees and 160 degrees.
To do both sweeps at the same time we can move 100 steps and multiply by 1.6 to get the 160 degree sweep:
void loop()
{
for (pos = 0; pos <= 100; pos++) //from 0 to 100
{
myservo1.write(pos + 40); // from 40 to 140
myservo4.write(140 - pos); // from 140 to 40
int pos2 = pos * 1.6; // 0 to 160
myservo2.write(pos2 + 10); // from 10 to 170
myservo3.write(170 - pos2); // from 170 to 10
delay(30);
}
for (pos = 0; pos <= 100; pos++) //from 0 to 100
{
myservo1.write(140 - pos); // from 140 to 40
myservo4.write(pos + 40); // from 40 to 140
int pos2 = pos * 1.6; // 0 to 160
myservo2.write(170 - pos2); // from 170 to 10
myservo3.write(pos2 + 10); // from 10 to 170
delay(30);
}
}
finally i got time to test this...
i was tinkereing with an almost identical code (before asking here) but something was wrong with it so i assumed i couldn't use pos and pos2.
your code works as i imagined the pumps would move.