Small angles below 10 degree control.

I would like to know whether it is possible to move a cheap hobby servo at small angles below 10 degrees? the servo dosent move at all for small angles below 10!! :confused: :(

Any suggestion on types of servos that are capable of moving small angles??

I'm not sure if you want to move the servo by small amounts, or if your servo will not move to a smaller angle than you get with Servo.write(10);

Many servos don't work through the full range 0 - 180 deg. You can only discover the range by trial and error.

Try using Servo.writeMicroseconds() for finer control.

...R

One simple way is to gear down your servo output. If your servo has a 90 degree range and you fit a 9 to 1 gear ratio onto it (say 3:1 followed by another 3:1) then the output will rotate 10 degrees. By preloading the output shaft you can eliminate backlash and get reasonably good drive resolution.

Below is some servo test code you can use to test the movement resolution of your servo and determine its rotation limits.

// zoomkat 3-28-14 serial servo incremental test code
// using serial monitor type a character (s to increase or a 
// to decrease) and enter to change servo position 
// (two hands required, one for letter entry and one for enter key)
// use strings like 90x or 1500x for new servo position 
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include<Servo.h>
String readString;
Servo myservo;
int pos=1500; //~neutral value for continuous rotation servo
//int pos=90;

void setup()
{
  myservo.attach(7, 400, 2600); //servo control pin, and range if desired
  Serial.begin(9600);
  Serial.println("serial servo incremental test code");
  Serial.println("type a character (s to increase or a to decrease)");
  Serial.println("and enter to change servo position");
  Serial.println("use strings like 90x or 1500x for new servo position");
  Serial.println();
}

void loop()
{
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }
  if (readString.length() >0) {
    if(readString.indexOf('x') >0) { 
      pos = readString.toInt();
    }

    if(readString =="a"){
      (pos=pos-1); //use larger numbers for larger increments
      if(pos<0) (pos=0); //prevent negative number
    }
    if (readString =="s"){
      (pos=pos+1);
    }

    if(pos >= 400) //determine servo write method
    {
      Serial.println(pos);
      myservo.writeMicroseconds(pos);
    }
    else
    {   
      Serial.println(pos);
      myservo.write(pos); 
    }
  }
  readString=""; //empty for next input
}

Very few servos move more than about 120--150 degrees in total - you cannot expect the full range of 0 to 180 sent to servo.write() to work unless you've tested the servo in question and it works for that range. If your servo has a datasheet that gives the actual range that would be helpful, but the cheap one's don't have much in the way of datasheets - they are cheap and only designed for flapping ailerons on a RC aircraft etc.

You'll get much better precision if you use microseconds instead of "angles". The angle unit is pretty much meaningless since very few servos have exactly 180 degree range of motion.

If you want to move a servo a certain number of degrees, you need to figure out what the pulse to angle conversion factor is for your model of servo.

I'd suggest trying to get the servo to move between 45 degrees from one side of center to 45 degrees on the other side of center. In my experience, this is the most precise area of the servo. While I use these two position to calculate my conversion factor, I apply the conversion factor over the entire range of motion. I just know the positions near the servo's extremes aren't as likely to be as accurate as the positions closer to the center position.

Don't try it with the 9g servos as the gears may strip, but the mechanical rotation limits of standard size servos can be determined just by carefully rotating the servo horn and noting the rotation end stop positions.

thanks,

when i test the servo using a potentiometer and move the servo using arduino's Knob example, i can move the servo for small angles between 10 degrees. however, if lets say my servo is at 90 degrees, and i write servo.write(95), the servo doesn't move. whats wrong.

xjacobll: when i test the servo using a potentiometer and move the servo using arduino's Knob example, i can move the servo for small angles between 10 degrees. however, if lets say my servo is at 90 degrees, and i write servo.write(95), the servo doesn't move. whats wrong.

My guess is there's a problem with the code. If you post the code, we can take a look at it.

DuaneDegn: My guess is there's a problem with the code. If you post the code, we can take a look at it.

I think the code is fine, because if i tell the servo to move from 90 to 100, it moves a little, from 90 to 20, good and so on, as long as the angle difference is big it moves to the position. anything between 90 to 100(i.e. angle between 10 degree) it doesn't move.

xjacobll:
I think the code is fine,

Then why are you asking questions here?

If you really want help just post the code.
And please post your program using the code button </> so it looks like this

…R

i just wanted to know whether servo.write() fails to move a servo at small angles,

here’s a simple code, send an angle through the serial monitor to move the servo…

#include <Servo.h>

Servo myservo; 
   
int angle = 0;   

void setup() {
  
        Serial.begin(9600);     
        myservo.attach(9);
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming integer angle:
                angle = Serial.parseInt();

                myservo.write(angle);

                // say what you got:
                Serial.print("I received: ");
                Serial.println(angle, DEC);
        }
}

xjacobll: thanks,

when i test the servo using a potentiometer and move the servo using arduino's Knob example, i can move the servo for small angles between 10 degrees. however, if lets say my servo is at 90 degrees, and i write servo.write(95), the servo doesn't move. whats wrong.

Could be hysteresis built-in to the servo - rather a lot of hysteresis, but you get what you pay for normally - cheap servos are not precision components.

Are you using an external power source for the servo? (if not, you should); for smaller angles(even smaller than 1 degree), use:

servo.writeMicroseconds(value)

where "value" is not degrees but microseconds (1500ms = 90 deg more or less)

ok i’m aware of servo.writeMicroseconds() and why its better than servo.write(), but then i no longer get to move the the servo at a range from 0 to 180 degrees…

i guess i’ll try to just apply maximum voltage to the servo and see what happens…

i thought someone would have had encountered a similar problem and could’ve provided me with some soloutions

ah well thanks anyways… :slight_smile:

xjacobll: ok i'm aware of servo.writeMicroseconds() and why its better than servo.write(), but then i no longer get to move the the servo at a range from 0 to 180 degrees..

I'm sure, if you think about it for a few minutes, you can do the maths to convert between degrees and microseconds.

...R

xjacobll: but then i no longer get to move the the servo at a range from 0 to 180 degrees..

They're not really degree anyway. Very few servos have exactly 180 degree range with the exact pulse values used by the library. At least with writeMicroseconds you use a number which relates to some real world value.

xjacobll: i guess i'll try to just apply maximum voltage to the servo and see what happens..

I've tried that trick myself. You get smoke.

xjacobll: i thought someone would have had encountered a similar problem and could've provided me with some soloutions

I bet MarkT (once again) identified what's happening.

MarkT: Could be hysteresis built-in to the servo - rather a lot of hysteresis, but you get what you pay for normally - cheap servos are not precision components.

When I'm adjusting the center positions of the 18 servos on my various hexapods, I usually adjust the pulse length values by 10us at a time. I can see a definite movement as long as I'm moving the servo in one direction. If I decide to move the servo back by 10us, then the movement isn't always noticeable. I'd think you should see movement if you advance the servo position from 80, 90, 100. If you then reverse and go back to 90, the movement will be less than the 90 to 100 movement. I think this has a lot to do with the space between gear teeth (there are surprising number of gears in a servo).

Robin2: I'm sure, if you think about it for a few minutes, you can do the maths to convert between degrees and microseconds.

If you don't want to do "the maths" you could instead do a bit of "math" and make the conversion. :)

Different servos have different pulse to angle relationships. I've been pleased to find this conversion rate is relatively consistent within a particular model of servo but when switch from one model of servo to another, a different conversion rate is usually required.

I thought my large hexapod make some rather entertaining moves when I used the code from my small hexapod without changing the conversion factors. At about 2:46 into this video you can see the hexapod doing its bucking bronco imitation.

Here's the hexapod moving with the proper conversion factors being used.

DuaneDegn: ... I usually adjust the pulse length values by 10us at a time. I can see a definite movement as long as I'm moving the servo in one direction. If I decide to move the servo back by 10us, then the movement isn't always noticeable. I'd think you should see movement if you advance the servo position from 80, 90, 100. If you then reverse and go back to 90, the movement will be less than the 90 to 100 movement. I think this has a lot to do with the space between gear teeth (there are surprising number of gears in a servo).

You can also test how large this mechanical hysteresis is, and if you ever do need to do a small movement, move ahead that number first and then the desired number plus the extra number back again. Of course this depends on how desirable this is for your application.

DuaneDegn: If you don't want to do "the maths" you could instead do a bit of "math" and make the conversion. :)

Are you on the other side of the Atlantic?

...R