This is the first time posting so I hope I do everything correct.
I have two servos. I need one servo to start moving but the second servo doesn't start until the first servo is at 90. Both servos should then be doing sweeps. I just can't think of how to do it. Have posted the code but there is something I just can't figure out to get it running.
#include <Servo.h>
Servo servo1; // create servo object to control a servo
Servo servo2; // create servo object to control a servo
int servo1Position = 0; // the current angle of the servo - starting at 0.
int servo1Interval = 80; // millisecs between servo moves
int servo2Position = 0;
int servo2Interval = 20;
int servo1Degrees = 1; // amount servo moves at each step
int servo2Degrees = 1; // will be changed to negative value for movement in the other direction
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis = 0; // the time when the servo was last moved
void setup() {
servo1.write(servo1Position); // sets the initial position
servo1.attach(8);
servo2.write(servo2Position); // sets the initial position
servo2.attach(9);
Serial.begin(9600);
}
void loop () {
currentMillis = millis();// this is equivalent to noting the time from a clock
servoSweep();
Serial.println(servo1Position);
Serial.println(servo2Position);
}
void servoSweep() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis - previousServoMillis >= servo1Interval) {
// its time for another move
previousServoMillis += servo1Interval;
servo1Position = servo1Position + servo1Degrees; // servoDegrees might be negative
if ((servo1Position >= 180) || (servo1Position <= 0)) {
// if the servo is at either extreme change the sign of the degrees to make it move the other way
servo1Degrees = - servo1Degrees; // reverse direction
// and update the position to ensure it is within range
servo1Position = servo1Position + servo1Degrees;
}
{
servo1.write(servo1Position);
// and record the time when the move happened
}
// make the servo move to the next position
if (servo1Position >= 90){
servo2Position = servo2Position + servo2Degrees;
servo2.write(servo2Position);
}
if (currentMillis - previousServoMillis >= servo2Interval) {
// its time for another move
previousServoMillis += servo2Interval; }
if ((servo2Position >= 180) || (servo2Position <= 0)) {
// if the servo is at either extreme change the sign of the degrees to make it move the other way
servo2Degrees = - servo2Degrees; // reverse direction
// and update the position to ensure it is within range
}
}
}
I see what you mean with the coding. Have changed it so now have both servos running simultaneously at different speeds but am still stumped as to how to get servo 2 to start its first sweep when servo 1 is at 90 degree. Any ideas appreciated.
#include <Servo.h>
Servo servo1; // create servo object to control a servo
Servo servo2; // create servo object to control a servo
int servo1Position = 20; // the current angle of the servo - starting at 0.
int servo1Interval = 20; // millisecs between servo moves
int servo2Position = 20;
int servo2Interval = 200;
int servo1Degrees = 1; // amount servo moves at each step
int servo2Degrees = 1; // will be changed to negative value for movement in the other direction
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServo1Millis = 0;
unsigned long previousServo2Millis = 0;// the time when the servo was last moved
void setup() {
servo1.write(servo1Position); // sets the initial position
servo1.attach(8);
servo2.write(servo2Position); // sets the initial position
servo2.attach(9);
Serial.begin(9600);
}
void loop () {
currentMillis = millis();// this is equivalent to noting the time from a clock
servo1Sweep();
servo2Sweep();
Serial.println(servo1Position);
Serial.println(servo2Position);
}
void servo1Sweep()
{
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis - previousServo1Millis >= servo1Interval) {
// its time for another move
previousServo1Millis += servo1Interval;
servo1Position = servo1Position + servo1Degrees; // servoDegrees might be negative
if ((servo1Position >= 150) || (servo1Position <= 20)) {
// if the servo is at either extreme change the sign of the degrees to make it move the other way
servo1Degrees = - servo1Degrees; // reverse direction
// and update the position to ensure it is within range
servo1Position = servo1Position + servo1Degrees;
}
{
servo1.write(servo1Position);
// and record the time when the move happened
}
}
}
// make the servo move to the next position
void servo2Sweep()
{
if (currentMillis - previousServo2Millis >= servo2Interval)
{
// its time for another move
previousServo2Millis += servo2Interval;
servo2Position = servo2Position + servo2Degrees;
}
if ((servo2Position >= 150) || (servo2Position <= 20)) {
// if the servo is at either extreme change the sign of the degrees to make it move the other way
servo2Degrees = - servo2Degrees; // reverse direction
// and update the position to ensure it is within range
servo2Position = servo2Position + servo2Degrees;
}
{
servo2.write(servo2Position);
}
}
You will also need separate timers for the two sweeps.
No. The situation is the servos operate fingers in a hand. I imagine the hand is resting on the table, finger tips down, and you start drumming your fingers on the table. You don't start with fingers raised. Yes, I wish I could have just offset the start position, it would have been an easy fix.
Sadly, the Arduino has no idea where each servo is while it’s in motion, unless you make incremental small angular steps in your code.
Then - you know when the servo has been told to go to 91-degrees, and can start servo #2
A more sophisticated approach would be to bring the feedback loop out of the RC servo, either with wires to an analog input, or a completely separate ‘servo’ using a separate DC servo’-motor and encoder - which provides you with complete control & positioning in real-time.
Thanks for all the replies. There's some new commands I've not used before so will sepnd some time over the next few days wrapping myhead around it.
And yes, they are RC servos.
And how are they powered? It is generally not acceptable to run two servos off the Arduino’s 5V output, you need an external power supply and good decoupling circuits between each motor.
lastchancename: Hadn't seen those off the shelf - niiice!!!
There's not only the adafruit ones: OP here says this one has feedback although I only see 3 wires in the photo and in the mechanical drawing. Maybe there's a "special".
Grumpy_Mike:
And how are they powered? It is generally not acceptable to run two servos off the Arduino’s 5V output, you need an external power supply and good decoupling circuits between each motor.
The projects are school based. When trialling coding we use up to 5 servo's on 1 arduino with no load however when hooked up to the fingers (loaded) we use separate power supplies that we purchased as our normal laboratory power supplies are rectified but not smoothed so caused havoc. I have not come across the concept of decoupling circuits but upon reading up on the topic they make a lot of sense so will bear them in mind for future work. Thanks