Controlling 3 Servos with4 potentiometers problem

Hi everybody,

I am new in using the arduino board and i need help in controlling multiple servos. My project is to control 3 servos using 4 potentiometer.
Each servos are programmed to perform different movement at the same time. But the problem is that the servos preform its movement one-by-one not at the same time. Is there any way/method to make the servos move at the same time? It could be timing problem/ interrupt but i not sure how to solve this problem. Help me please…

Below shows the sketch that i have written for 1 potentiometer controlling 3 servos.

// Proto_Testing
// by Khairul Shariman Kalid kshariman@gmail.com
/* Currently the problem is to perform multitasking
which is to control multiple output with variance
task using single input

  1. Is there any method/source code that can be applied for
    multi tasking in arduino?
    */

#include <Servo.h>

Servo Arm1; //create servo object to control servo 1
Servo Arm2; //create servo object to control servo 2
Servo Arm3; //create servo object to control servo 3

int fwd = 0; // forward input control at analog pin 0
int fwdvalue = 0; //set initial value of analog input
int fwdpos1_Arm1 = 0; // variable to store the servo position
int fwdpos2_Arm1 = 0; // variable to store the servo position
int revpos1_Arm1 = 0; // variable to store the servo position
int revpos2_Arm1 = 0; // variable to store the servo position
int fwdpos1_Arm2 = 0; // variable to store the servo position
int fwdpos2_Arm2 = 0; // variable to store the servo position
int revpos1_Arm2 = 0; // variable to store the servo position
int revpos2_Arm2 = 0; // variable to store the servo position
int fwdpos1_Arm3 = 0; // variable to store the servo position
int fwdpos2_Arm3 = 0; // variable to store the servo position
int revpos1_Arm3 = 0; // variable to store the servo position
int revpos2_Arm3 = 0; // variable to store the servo position

void setup()
{
pinMode(fwd,INPUT); //set pin 0 as input
Arm1.attach(3); // attaches the servo on pin 3 to the servo object
Arm2.attach(5); // attaches the servo on pin 5 to the servo object
Arm3.attach(9); // attaches the servo on pin 9 to the servo object

}

void loop()
{
fwdvalue = analogRead(fwd);
delay(15);

if(fwdvalue > 512)
{
Arm1_Rev();
Arm2_Fwd();
Arm3_Fwd();

}
else if(fwdvalue < 512)
{
Arm1_Fwd();
Arm2_Rev();
Arm3_Rev();
}
else
{
Donothing();
}
}

//…ARM_1…

void Arm1_Fwd()
{
for(fwdpos1_Arm1 = 0; fwdpos1_Arm1 < 180; fwdpos1_Arm1 += 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm1.write(fwdpos1_Arm1); // tell servo to go to position in variable ‘pos’
delay(15);
}
for(fwdpos2_Arm1 = 180; fwdpos2_Arm1 > 0; fwdpos2_Arm1 -= 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm1.write(fwdpos2_Arm1); // tell servo to go to position in variable ‘pos’
delay(15);
}
return;
}

//…

void Arm1_Rev()
{
for(revpos2_Arm1 = 180; revpos2_Arm1 > 0; revpos2_Arm1 -= 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm1.write(revpos2_Arm1); // tell servo to go to position in variable ‘pos’
delay(15);
}
for(revpos1_Arm1 = 0; revpos1_Arm1 < 180; revpos1_Arm1 += 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm1.write(revpos1_Arm1); // tell servo to go to position in variable ‘pos’
delay(15);
}
return;
}

//…ARM_2…
void Arm2_Fwd()
{
for(fwdpos1_Arm2 = 0; fwdpos1_Arm2 < 180; fwdpos1_Arm2 += 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm2.write(fwdpos1_Arm2); // tell servo to go to position in variable ‘pos’
delay(15);
}
for(fwdpos2_Arm2 = 180; fwdpos2_Arm2 > 0; fwdpos2_Arm2 -= 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm2.write(fwdpos2_Arm2); // tell servo to go to position in variable ‘pos’
delay(15);
}
return;
}

//…

void Arm2_Rev()
{
for(revpos2_Arm2 = 180; revpos2_Arm2 > 0; revpos2_Arm2 -= 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm2.write(revpos2_Arm2); // tell servo to go to position in variable ‘pos’
delay(15);
}
for(revpos1_Arm2 = 0; revpos1_Arm2 < 180; revpos1_Arm2 += 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm2.write(revpos1_Arm2); // tell servo to go to position in variable ‘pos’
delay(15);
}
return;
}

//…ARM_3…
void Arm3_Fwd()
{
for(fwdpos1_Arm3 = 0; fwdpos1_Arm3 < 180; fwdpos1_Arm3 += 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm3.write(fwdpos1_Arm3); // tell servo to go to position in variable ‘pos’
delay(15);
}
for(fwdpos2_Arm3 = 180; fwdpos2_Arm3 > 0; fwdpos2_Arm3 -= 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm3.write(fwdpos2_Arm3); // tell servo to go to position in variable ‘pos’
delay(15);
}
return;
}

//…

void Arm3_Rev()
{
for(revpos2_Arm3 = 180; revpos2_Arm3 > 0; revpos2_Arm3 -= 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm3.write(revpos2_Arm3); // tell servo to go to position in variable ‘pos’
delay(15);
}
for(revpos1_Arm3 = 0; revpos1_Arm3 < 180; revpos1_Arm3 += 5) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Arm3.write(revpos1_Arm3); // tell servo to go to position in variable ‘pos’
delay(15);
}
return;
}

//…

void Donothing()
{
Arm1.write(0); // tell servo to go to position in variable ‘pos’
Arm2.write(0); // tell servo to go to position in variable ‘pos’
Arm3.write(0); // tell servo to go to position in variable ‘pos’
return;
}

//…

If you remove all those "delay()"s, that’ll help make it look like that’re working at the same time.
You really need to turn the problem inside-out, and have all the movements in the main loop, with target positions updated each time through the loop.

Thanks for the feedback,

So, i need to remove all the call functions? and what do you mean by "target position update"? Can you give some example on how to do it?

When you call Servo.write(), you are specifying a target position. The function returns immediately. The delay() call is there so that you do not call Servo.write() again before the servo has had time to actually more to the specified position.

If you specify new positions for all three servos:

Arm1.write(arm1Val);
Arm2.write(arm2Val);
Arm3.write(arm3Val);

with no delays between the calls, all three servos will move at the same time. After commanding all three servos, you would then wait for them to arrive at the new target position before updating the target position.

Owh..i get it...Thanks ;D I'll try this method first...

int fwdpos1_Arm1 = 0; // variable to store the servo position int fwdpos2_Arm1 = 0; // variable to store the servo position int revpos1_Arm1 = 0; // variable to store the servo position int revpos2_Arm1 = 0; // variable to store the servo position int fwdpos1_Arm2 = 0; // variable to store the servo position int fwdpos2_Arm2 = 0; // variable to store the servo position int revpos1_Arm2 = 0; // variable to store the servo position int revpos2_Arm2 = 0; // variable to store the servo position int fwdpos1_Arm3 = 0; // variable to store the servo position int fwdpos2_Arm3 = 0; // variable to store the servo position int revpos1_Arm3 = 0; // variable to store the servo position int revpos2_Arm3 = 0; // variable to store the servo position

:o

:( AAAAAAAHHH!!! You should use an array for this. ;)

hehe...sori, I actually dont know how to do an array...please show me ;)

Your in luck, because your example seems perfect to use an array with. You'll have to restructure the code a bit, but read thru this:

http://www.arduino.cc/en/Reference/Array

You'll want to make an array large enough to hold all those variables, and then write to the proper space in the array as opposed to writing specific variables

Thanks very much ;D .
Now my programming skills becomes better and better :slight_smile:

Regarding with the problem that I faced. Now I can run the servos ‘simultaneously’ thanks AWOL but at certain speed, the servo’s movement become not smooth.
There are pauses during running, and it runs only for several times then it pause again…
If I increase the ‘delay()’ or I increase the increment value for the “for loop” then it can run smoothly. I need it to run as fast as possible (no delay if possible);
FYI, I’m using the Arduino Demi model.
Below shows the sample of my latest sketch.

// Proto_Testing
// by Khairul Shariman Kalid kshariman@gmail.com
/* Currently the problem is to perform multi task
which is to control multiple output with variance
task using single input

  1. Is there any method/source code that can be applied for
    multi tasking in arduino?
  2. Why the servos have pauses during movement
  3. How to make the servos runs fast and smooth
    */

#include <Servo.h>

Servo Arm1; //create servo object to control servo 1
Servo Arm2; //create servo object to control servo 2
Servo Arm3; //create servo object to control servo 2

int fwd = 0; // forward input control at analog pin 0
int fwdvalue = 0; //set initial value of analog input
int ArmPos; //set initial value for servo position

void setup()
{
pinMode(fwd,INPUT); //set pin 0 as input
Arm1.attach(3); // attaches the servo on pin 3 to the servo object
Arm2.attach(5); // attaches the servo on pin 5 to the servo object
Arm3.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop()
{
fwdvalue = analogRead(fwd); //Read singnal from analog pin 0

//…Servos Movement…
else if(fwdvalue > 512)
{
int Armrev = 90;
for(ArmPos=0;ArmPos<90;ArmPos += 1) //servo move from 0 to 90 degree
{
Arm1.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Arm2.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Arm3.write(Armrev); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Armrev = Armrev - 5; //set to servo move from 90 to 0 degree
}
int Armfwd = 0;
for(ArmPos=90;ArmPos>0;ArmPos -= 5) //servo move from 90 to 0 degree
{
Arm1.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Arm2.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Arm3.write(Armfwd); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Armfwd = Armfwd + 5; //set to servo move from 0 to 90 degree
}
}
else
{
Arm1.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Arm2.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
Arm3.write(ArmPos); // tell servo to go to position in variable ‘ArmPos’
delay(15)
return;
}
}

You've still got delays in there. If you write to three servos in a for loop, you only need one delay (if you need a delay at all).

BTW, you know all your servos are going to the same position? I didn't think that's what you wanted.

Hi everybody,

Thank you for the feedback. I've already uploaded the one without "delay()"s but the servos movement did not turn smoothly. There are pauses where the servo stops for a while then it continues to move again then it pause again. But if i put the delay there, the servo moves smoothly and no pauses but of course the movement will be slow.

As you can see, the Arm3 movement are not the same as Arm1 and Arm2 where Arm3 move in different direction.

My problem right now is that the servo did not move contineuously (not as expected) and it moves slow. Is there any method that can solve this other than removing "delay()"s

Have a look at the Blink Without Delay example, and work through it.

There are pauses where the servo stops for a while then it continues to move again then it pause again. But if i put the delay there, the servo moves smoothly and no pauses but of course the movement will be slow.

With the delays, there is only one servo moving at a time. With a delay in the loop, but not between each servo command, all three servers should move at once.

If you are not getting smooth movement when all three servos move at once, but you do get smooth movement when only one moves at a time, I'd suspect that you are not providing enough current to drive the three servos simultaneously.

What servos are they, and how are you powering them?

I'm using Bizchip Servo Motor model SV01. Here is the link to datasheet for the servos that i use http://bizchip.com/servo.pdf . All the servos are connected to Arduino's 5V pin. Could this be the problem the servos not moves smoothly? So, I need to power the servos with external power source?

So, I need to power the servos with external power source?

Always.

Owh...okey...Thanks guys ;D

Servos can draw up to 1A each, depending on type and load. So if you run even one servo directly from the 5v pin of the arduino, there is a good chance that it won't get all the juice it needs if you put too much load on it.