I have a pair of Futaba S3001 servers that I am controlling with a Raspberry Pi, using the pigpio library.

To control the angles of the servos, I set the pulse width according to the formula:

pulse_width = centre + angle * multiplier

where centre is the pulse width required for 0 degrees, and the multiplier is a figure arrived at by trial and error to that represents the pulse width difference required for one degree change.

For one servo, I have arrived at:

multiplier_1 = 9.444444444444445
centre_1 = 1350

and the other:

multiplier_2 = 9.222222222222221
centre_2 = 1315

This seems to work reasonably well, at least within +/- 45 degrees.

At larger angles, I am not so sure it's still within bounds, but it's hard to tell.

My questions are:

  • Is the relationship between pulse width and angle wholly linear, as I am assuming?

  • Does the linearity break down more towards the ends of the servo's travel?

  • What sort of accuracy should I expect from a hobby servo such as this?

  • Is there a better way to arrive at the function I need?

  • 1
    \$\begingroup\$ Manufacturers would try to use a nominally linear taper potentiometer, but there will be far too many details that change between brands and models (or even as you perhaps have found between samples of the same brand/model) for this question to be answerable. Ultimately, hobby servos are made for systems where the arm lengths and neutral angles will be tuned on installation, and for use in human-in-the-loop applications. That they're re-usable with care in hobby robots is an incidental benefit, not really a design goal. Fortunately you can easily tune your software. \$\endgroup\$ – Chris Stratton Dec 25 '18 at 21:22
  • 1
    \$\begingroup\$ No, yes, maybe a couple percent over the center 70-80% when approached from the same direction, better from what sense? You can calibrate... \$\endgroup\$ – Spehro Pefhany Dec 25 '18 at 21:58
  • \$\begingroup\$ @ChrisStratton If you wrote your comment as an answer, I'd be inclined to accept that, unless someone else turns up with one including a really good calibration strategy. \$\endgroup\$ – Daniele Procida Dec 25 '18 at 22:16

I would expect much closer to 1500 for center, but that's off-topic.

A hobby servo, with the main intent being to be placed in a closed-loop control system (where the driver, a human, closes the loop) is not required to behave precisely. Add on to this that the control link itself may be non-linear, and the output of the system may also be non-linear (doubling the throw on an elevator does not necessarily exactly double the rate of rotation of the aircraft). The human won't even notice non-linearity. In fact often we add curves (expo) to the system for more precise control around center stick, and more aggressive throws at the extents.

That being said, I would expect Futaba, if anyone, to make relatively predictable servos. The control loop may in fact be linear, but the feedback within the servo may not; a servo uses a potentiometer for position feedback, potentiometers are tricky and often imperfect.

A hall sensor, brushless servo will be more accurate, assuming that it's trying to be linear. A separate, more predictable position feedback (a hall sensor potentiometer) may also work. The ideal solution here is a stepper motor, where precise angular displacement is predictable, as that is the intent of the design.


A typical function is a polynomial with multiple terms. 3 or four terms are required to get a function that fits reasonably well.

I have established this empirically through testing multiple servos (and multiple different models).

In the graph below, the x-axis represents degrees and the y-axis represents pulse-widths. This particular example is from a Tower Pro SG90, a very cheap hobby servo, with the dots representing actual values.

However, it's fairly typical of all the devices I tested:

  • the actual results don't track the curve perfectly
  • the response of the motors becomes less sensitive towards the extremes.

There's more information about this, plus a link to the Jupyter Notebook I used to produce the graph.

pulse-widths to angles

Having said that. In most cases I tested I have found that a 10ms change in pulse-width will produce roughly one degree of movement, which provides a useful rule of thumb for many applications.

So to answer the specific questions:

  • The relationship between pulse-width and angle isn't wholly linear, though I guess it's supposed to be roughly so.
  • The linearity breaks down increasingly towards the ends of the servo's travel.
  • Micro-servos such as SG90s seem to have a resolution of (quite approximately) 1.25 degrees, but they also suffer from hysteresis (i.e. where they land can depend on which direction you're coming from). I had better results with some larger, more powerful servos (Futaba S3001) but not some others.
  • In order to arrive at the function I needed, I captured some pulse-width/angle values, as shown, and used Numpy to find the curve of best-fit.

Generally, pulses are 1 to 2 ms wide, repeating at 50 Hz rate. 1.5 ms is centered (1500 μs), 1 ms (1000 μs) is fully to one side, 2 ms (2000 μs) is fully to the other side.

  • 1
    \$\begingroup\$ That is only true in the general sense, and varies quite a bit by brand. Further, you haven't really answered any of the specifics asked - not that you could, because those are even more variable. \$\endgroup\$ – Chris Stratton Dec 25 '18 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.