How can I control the speed of my servos??

Hi, I am working on a robot with 20 servos. Everything is going fine but the most weird thing is their speed. They respond so quickly and thus robot appears to move its legs drastically. I want to control their speed with programming. One method is to split the desired position into steps and acheive that in 2-3 steps. But I think it will become more jerky?? Can anyone explain me how to make them act slower!!

Also I have got 3-4 servos damaged; broken shafts due to multiple reasons!!! Anyone on Earth can tell me whether I can get these fixed or not??? :(

Thanks

The speed at which a servo moves is usually quoted by the maker as the fraction of a second to move 60 degrees under no load. It will be slower under load of course, but nevertheless, the speed is an inherent characteristic of the model of servo and would be one of the selection criteria.

You cannot slow down their movement but you can make them move in smaller increments with a delay between each movement. For instance try this, assuming that you have got a servo connected and defined as servo1

void loop()
{
  servo1.write(0);    //full speed to position zero
  for (int pos = 1; pos <= 180; pos++)
  {
    servo1.write(pos);
    delay(10);
  } 
}

You are right that the servo movement will be more jerky, but adjust the delay to see the effect and choose a value that gives the required compromise between speed and jerkiness.

As to your broken servos, what exactly is broken ? Is it the output shaft or the output arms ? If it is the shafts then you may be able to get spares if the servos are branded, such as Futaba, but don’t hold your breath. Try a shop that sells radio controlled models. If it is the output arms that are broken then they are freely available from the same source or Ebay.

Student09: I want to control their speed with programming.

Yes, that's reasonable.

Student09: One method is to split the desired position into steps and acheive that in 2-3 steps. But I think it will become more jerky??

If you make the movements in large steps, it would be very jerky. But in software you can make the steps as small as you want - once you're making the movement in steps, you can make the steps as small as one degree increments if you want - or even smaller if you set the servo position using writeMicroseconds().

The servo "sweep" example code in the IDE examples shows one method to control servo speed. If you are willing to spend more money, then a stand alone servo controller that handles servo speed commands might be worth while (like the SSC-32 which is often used with hexapods ~$40). The below might also be of interest.

http://arduino.cc/forum/index.php/topic,61586.0.html

The code that UKHeliBob offers will work, but if you want to do it right with multiple servos, you'll need to do something like the BlinkWithoutDelay example - for instance:

http://www.bajdi.com/controlling-a-servo-without-the-delay-function/

This could be fairly easily expanded to multiple servos with the use of several arrays, one element each for:

  1. The servo pin
  2. The old and new positions
  3. The current and previous time intervals
  4. The interval itself (to control the speed of a given servo)

So, six arrays - actually, it would be better to set up a data structure with those elements, then define a single array of that structure's type def; a loop to iterate through each servo defined, the inner code from that link to control each servo, and bob's your uncle. At least in theory.

I'm certain someone has created a library to do this; strangely, though, I couldn't find one easily (might have to dig deeper through google).

Oh - btw - this link is also interesting; if you can get the above to work, integrating it with this would be neat:

http://rcarduino.blogspot.com.au/2012/08/arduino-serial-servos.html

I looked at the below, and not sure what it is intending to do. What it does appears to not require any type of delay.

http://www.bajdi.com/controlling-a-servo-without-the-delay-function/

Thanku everyone for ur suggestions!!! Stay blessed!!! :slight_smile: :slight_smile:

This code worked immediately, with a little adjustment of delay…
void loop()
{
servo1.write(0); //full speed to position zero
for (int pos = 1; pos <= 180; pos++)
{
servo1.write(pos);
delay(10);
}
}

I know that it was me that suggested that code, but now try that with 20 servos. If you only want one servo to move at any one time then maybe, just maybe, you will be OK, but not if more than one has to move at the same time.

There are ways to make more than one servo move at slower speeds, even different speeds, as has been alluded to in this thread but that will involve not using delay().

Yes the problem has already been resolved with the same code. Thanks

Such a common requirement, there's even a library - http://arduino.cc/forum/index.php/topic,61586.0.html

Another problem!!! We are integrating GP2D120 sensors with our robot now. Using the same code as given here:

But there is some problem while reading the value. Actually we have to move servos uptil a particular value read by sensors and then the servos should stop. But in our case servos keep on moving even when the sensor reads a quite large value. Can anyone tell if we need to do some sort of conversion after reading the value from sensor?? For example we need to stop servos when sensor gives greater than 2.5V. So we write in our code as follows:
while(Sensoroutput<= 512)
{ keep moving servos;
}
servos stop;
Is the figure 512 okay?? (2.5/5)*1024
Kindly tell if you identify any error in the code?
Thanks

Kindly tell if you identify any error in the code?

There isn’t enough of it.

Kindly tell if you identify any error in the code?

This code:

while(Sensoroutput<= 512)   
          { keep moving servos;
           }
            servos stop;

has several problems. keep moving servos; is not valid syntax. servos stop; isn’t either.

If Sensoroutput is less than 512, the while loop will never end.

Here is the code that we used for testing the adc:

int analogPin = 8; // potentiometer wiper (middle terminal) connected to analog pin 3 // outside leads to ground and +5V int val = 0; // variable to store the value read void setup() { Serial.begin(9600); // setup serial }

void loop() { val = analogRead(analogPin); // read the input pin Serial.println(val); // debug value delay(500); }

The output for any voltage is: 32 32 32 32 32 What is the problem?? Kindly tell if you can suggest something. Thanks

8 != 3

Duane B rcarduino.blogspot.com

int analogPin = 8;     // potentiometer wiper (middle terminal) connected to analog pin 3

Which pin is the wiper of the pot actually connected to ?

Sorry it is wrongly mentioned in the comments. We switched it to 8th.

One thing more: Whether or not I connect the power supply, output on serial monitor displays 32.. meaning: giving any voltage to adc channel makes no difference on serial monitor.

This going to sound picky, but when you say

We switched it to 8th.

do you mean pin 8 or the 8th pin ?