Hi I want to run a sweep command for 4 servos off of one Arduino Uno simultaneously, but each at different rates.
Currently I have figured out how to run 4 servos simultaneously but at the same rate, and how to run each at a different rate, but not simultaneously.
Here is my code, which makes all the servos rotate together 90 degrees first, then two rotate back 90 degrees at a rate of 40 ms, and then the other two rotate back after that at a rate of 15 ms.
//QUADSweep
//edited from the original code by BARRAGAN
#include "Servo.h"
Servo myservo; // create servo object to control a servo, a maximum of eight servo objects can be created
Servo mysecondservo; // servo 2
Servo mythirdservo; // servo3
Servo myfourthservo; // servo4
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
mysecondservo.attach(10); // attaches the servo on pin 10 to the servo object
mythirdservo.attach(8); // attaches the servo on pin 8 to the servo object
myfourthservo.attach(11); // attaches the servo on pin 11 to the servo object
}
void loop()
{
for(pos = 0; pos < 90; pos += 1) // goes from 0 degrees to 90 degrees in steps of 1 degree
{
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
mythirdservo.write(pos); // tell servo to go to position in variable 'pos'
delay(40); // waits 40ms for the servo to reach the position
}
{
mysecondservo.write(pos); // tell servo to go to position in variable 'pos'
myfourthservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10);
}
}
for(pos = 90; pos>=0; pos-=1) // goes from 90 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
mythirdservo.write(pos); // tell servo to go to position in variable 'pos'
delay(40); // waits 40ms for the servo to reach the position
}
for(pos = 90; pos>=0; pos-=1) // goes from 90 degrees to 0 degrees
{
mysecondservo.write(pos); // tell servo to go to position in variable 'pos'
myfourthservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 10ms for the servo to reach the position
}
}
loop()
{
unsigned long start = millis();
int sweepsNotFinished;
do
{
unsigned long now = millis() - start;
sweepsNotFinished = 0;
sweepsNotFinished += sweep(now, 500, 1500, 90, 0, servo1); // 1/2 second delay then 1 second sweep from 90 to 0
sweepsNotFinished += sweep(now, 0, 2000, 180, 75, servo2); // no delay and 2 second sweep from 180 to 75
sweepsNotFinished += sweep(now, 250, 10000, 30, 100, servo3); // 1/4 second delay, then 9.75 second sweep from 30 to 100
} while (sweepsNotFinished > 0);
}
int sweep(unsigned long currentTime, unsigned long startTime, unsigned long endTime, int startPosition, int endPosition, Servo &servo)
{
if (currentTime < startTime)
return 1;
if (currentTime > endTime)
return 0;
servo.write( startPosition + (endPosition-startPosition) * (currentTime-startTime) / (endTime-startTime);
return 1;
}
ok sorry but I'm a super duper hack beginner....I'm trying to upload it but it's saying "expected `)' before ';' token" and points to the red line below. What does this mean...?
//QUADSweep
//edited from the original code by BARRAGAN
#include "Servo.h"
Servo myservo; // create servo object to control a servo, a maximum of eight servo objects can be created
Servo mysecondservo; // servo 2
Servo mythirdservo; // servo3
Servo myfourthservo; // servo4
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
mysecondservo.attach(10); // attaches the servo on pin 10 to the servo object
mythirdservo.attach(8); // attaches the servo on pin 8 to the servo object
myfourthservo.attach(11); // attaches the servo on pin 11 to the servo object
}
void loop()
{
unsigned long start = millis();
int sweepsNotFinished;
do
{
unsigned long now = millis() - start;
sweepsNotFinished = 0;
sweepsNotFinished += sweep(now, 500, 1500, 90, 0, myservo); // 1/2 second delay then 1 second sweep from 90 to 0
sweepsNotFinished += sweep(now, 0, 2000, 180, 75, mysecondservo); // no delay and 2 second sweep from 180 to 75
sweepsNotFinished += sweep(now, 250, 10000, 30, 100, mythirdservo); // 1/4 second delay, then 9.75 second sweep from 30 to 100
} while (sweepsNotFinished > 0);
}
int sweep(unsigned long currentTime, unsigned long startTime, unsigned long endTime, int startPosition, int endPosition, Servo &servo)
{
if (currentTime < startTime)
return 1;
if (currentTime > endTime)
return 0;
servo.write( startPosition + (endPosition-startPosition) * (currentTime-startTime) / (endTime-startTime));
return 1;
}
I understand how the delay works (I think?) but is that set of lines supposed to only apply to one servo? With that code I just have one servo which alternates between twitching and sweeping.
Are you sure you have all the servos connected correctly? Others have found that their servos act very strangely if they accidentally swap any two of the three wires.
Are you supplying enough power to drive multiple servos? Even one servo might be too much for USB power and four is probably too much to run off the Arduino 5V power line. You should have a separate 5 or 6 volt power supply for the servos. The Arduino ground should be connected to the servo's ground pin. The Arduino data pins should connect to the servo's signal pin.
Ok I've played with the numbers and I've got it much closer to where I need it to be (thankyouthankyou!). Here is my code now:
//QUADSweep
//edited from the original code by BARRAGAN
#include "Servo.h"
Servo myservo; // create servo object to control a servo, a maximum of eight servo objects can be created
Servo mysecondservo; // servo 2
Servo mythirdservo; // servo3
Servo myfourthservo; // servo4
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
mysecondservo.attach(10); // attaches the servo on pin 10 to the servo object
mythirdservo.attach(8); // attaches the servo on pin 8 to the servo object
myfourthservo.attach(11); // attaches the servo on pin 11 to the servo object
}
void loop()
{
unsigned long start = millis();
int sweepsNotFinished;
do
{
unsigned long now = millis() - start;
sweepsNotFinished = 0;
sweepsNotFinished += sweep(now, 250, 10000, 0, 90, myservo); // 1/4 second delay, then 9.75 second sweep from 30 to 100
sweepsNotFinished += sweep(now, 0, 1000, 0, 180, mysecondservo); // 0 second delay, then 9.75 second sweep from 30 to 100
sweepsNotFinished += sweep(now, 1000, 8000, 0, 180, mythirdservo); // 1 second delay, then 9.75 second sweep from 30 to 100
sweepsNotFinished += sweep(now, 500, 5000, 0, 90, myfourthservo); // 1/2 second delay, then 9.75 second sweep from 30 to 100
} while (sweepsNotFinished > 0);
}
int sweep(unsigned long currentTime, unsigned long startTime, unsigned long endTime, int startPosition, int endPosition, Servo &servo)
{
if (currentTime < startTime)
return 1;
if (currentTime > endTime)
return 0;
servo.write( startPosition + (endPosition-startPosition) * (currentTime-startTime) / (endTime-startTime));
return 1;
}
My question now is that right now I feel like I have good control of the second half of the sweep, but not the first (ie. what controls the speed of the first half of the sweep in the code?) Also, is there a way to make all the sweeps more continuous? Right now, all the servos wait until all other servos have completed their loops before restarting--is there a way that the servos can run continuously, irregardless to where the other servos are in their loops?
int servoSpeeds[NBR_SERVOS] = {1, 10, 100, 255}; // sweep speed, 1 is slowest, 255 fastest)
A word of warning about high servo speeds setting - 255 in this case: The updating of the servo happens faster that the servo is actually able to move. So in this example, you might end up with switching between the extreme positions at each PWM cycle for the servo. The resulting movement won't be a servo wiping left and right at a fast speed, but a servo twitching randomly in some random position. You probably need to decrease the speed from 255 to some lower value until your servos has enough time to complete the sweep. In my tests with the little servos I had, speeds over 128 were usually above the hardware speed of the servo and all looked the same.
@john wasser: yes, I just want the servos to act independently of each other and just to be ongoing, completely irregardless of each other. @mem: thank you for your input, I'll try it a little bit later today and see if that works better @korman: thank you I'll keep that in mind
Also, I might be turning my code over to more capable hands soon...thanks for all the input!
This is very helpfull but my question is: I want my servo's to go in the opposite direction but I have no idea how to do it...
Can someone please help me?