# How to determine minimum and maximum angle for cheap servos?

I have some cheap KY66 (seems to be SG90 clone) servos.

When I turn them to 0°, the servo tries moving and moving, without actually getting to 0°. I read that they are reaching the endpoint but the built-in potentiometer does give a reading of 0.

By changing the code and fiddling with the angle, I find that the minimum for one particular servo is 25°.

I'm now trying to figure out how the Arduino could determine this value automatically. I have tried

``````servo.write(0);
delay(3000);
``````

and expected to get back a value near 25, but it was 0 instead. So the result of `read()` does not seem to be an actual reading, but more the "last known" setpoint.

I've also tried to relax the servo before reading:

``````servo.write(0);
delay(3000);
``````

with no better result.

I like to figure out the minimum and maximum angle of the servo

• because I don't like the servo to make much noise (it really doesn't sound healthy)
• without having the user to figure out by himself and the need of re-programming the Arduino.

I know that these cheap servos only have 3 pins. 2 pins are for power supply only, so there's only 1 pin left.

My questions:

• Is the data pin uni-directional (PWM output from Arduino to servo)?
• Will it ever be possible to implement what I want without additional hardware?
• How do people solve this issue? Do more expensive servos either have better calibration to actually go from 0° to 180° or do they provide a way to read the potentiometer with another pin?

Is the data pin uni-directional (PWM output from Arduino to servo)?

As you found out, standard servos have only three pins. And yes, two of them provide ground and power, and the third is a unidirectional signal.

This signal is commonly a pulse of 1 ms to 2 ms, repeated every 20 ms.

`servo.read()` can therefore only return the last value set by `servo.write()`.

Will it ever be possible to implement what I want without additional hardware?

I don't think so.

You could insert a shunt into the power line and measure the current. If it stays high for extended periods, it means that the servo is still powering its motor. But this could be true also for other reasons than being at its own mechanical limit.

How do people solve this issue? Do more expensive servos either have better calibration to actually go from 0° to 180° or do they provide a way to read the potentiometer with another pin?

Since servos are used as a closed (sub-)system, I don't think that they are opened to read their potentiometer. And even if you do this, you might affect the internal working of the servo.

Eventhough I built several model aircrafts since the late 70s and used different servos, I have no feeling about the calibration of cheap or expensive servos. IIRC some data sheet documented ranges of only +/- 45°.

So the values `0` to `180` for `servo.write()` is just a mapping for 1 ms to 2 ms.

To make a long story short, I have no idea how people solve this.

You might like to limit your range to some "healthy" values, or ask the user to help in calibration. The calibration results can be stored in EEPROM, there is no need to reprogram the Arduino.

If you need the robot's head to turn from 0° to 180°, consider using some gear so that the servo just needs to move between, let's say, 30° to 150°. This is the way modellers go.

I think you have 2 choices: either measure and store for each one individually, or find the worst case for all of them and code around that.

Do you really need the full travel? If you're using the servo to push/pull, the servo-travel endpoints are pretty weak anyway.

I wanted a robot look left and look right, which is 0° or 180°.

Maybe you can make up the limited angular travel of the servo in the linkage between the it and the camera platform.

• Indeed I wanted a robot look left and look right, which is 0° or 180°. 25° is quite a bit off. But well, it seems I need to consider that. – Thomas Weller Jan 26 at 22:14