servo.attach default values are out of spec for standard servos

I'm a little new to servo control and have just done some trouble shooting to figure diagnose some strange behavior with my analog servo. I have two servos that both behaved the same way with some simple "hello, world" servo tests from the Arduino. They appeared to have a dead zone around zero and 180 degrees when I use the servo.h library commands. When I eventually looked at the pulse width control signal, I discovered that the control signal was out of spec with the standards for servo control. An analog servo wants a pulse width from roughly 1 to 2 ms in width to translate to 0-->180 degrees of rotation.

It turns out that the signal from the Arduino using the servo.h defaults yields a low and high pulse width of around 0.5 ms to 2.4 ms. I might have assumed that a shorter than 1 ms and longer than 2 ms pulse would send the servo to zero and 180 degrees, but both my servos were non-responsive to these excessively shorter and longer pulse widths, yielding a sort of dead zone when ramping a control signal throughout the 0 to 180 degree range. This caused peculiar effects when translating the input from a pot through an A/D pin to a rotation angle. If the pot was slowly moved to an endpoint then the servo would follow. A quick movement on pot to an endpoint would cause little or no movement (with, say a 10 Hz sample rate) as the Arduino's servo control pulse quickly jumped from a valid to a non-valid pulse width.

Then . . . I discovered that servo.attach() actually can take three parameters besides the pin parameter (thank you, C++ for hiding this). The attach function can take, in addition to the pin number, a minimum and max pulse width.

Example programs for servo control everywhere use the following:

myservo.attach(9); // this yields inappropriate pulse widths of 0.544 ms and 2.4 ms

This was corrected in my code by using the following, followed by proper operation of the servo:

myservo.attach(9,1000,2000); // initialize with standard pulse width pulses for servo control

Here is a clip from the documentation for servo.attach()

Syntax

servo.attach(pin)
servo.attach(pin, min, max)
Parameters

servo: a variable of type Servo
pin: the number of the pin that the servo is attached to
min (optional): the pulse width, in microseconds, corresponding to the minimum (0-degree) angle on the servo (defaults to 544)
max (optional): the pulse width, in microseconds, corresponding to the maximum (180-degree) angle on the servo (defaults to 2400)

Seems a bit strange that the default pulse widths for servo.h are out of spec with the long (established 30-40 years?) specs for an analog servo.

Why not default the function to the proper specs or perhaps at least include the pulse width version of the attach() function in the demo programs? I'm sure I'm not the first person that has been confused by this and without a scope, this would have remained a mystery.

Alas, the servos don't seem to be standard either.

...R

An analog servo wants a pulse width from roughly 1 to 2 ms in width to translate to 0-->180 degrees of rotation.

Well I'm impressed that you have uncovered the dirty little secret of the standard arduino servo library. It is pretty lame in that regard and makes some silly assumptions, all in the attempt to make it easy for beginners to get quick (but dirty) results, but it has killed more brain cells then probably any other basic library the arduino distribution offers.

So to either repeat, restate, or add to your findings:

All R/C servos are guaranteed to operate between 1 and 2 millisecond pulse width but with typically no specification of how many degrees of travel that might be for a specific R/C servo model. The arduino library just makes an assumption that
0.544 ms and 2.4 ms equates to 0 to 180 degrees of travel and many servos have mechanical stops in the gear train that prevent such travel amount. So minimum and maximum control pulse width is one specification and maximum travel is another specification, the two are independent and specific to any specific servo model.

Most all R/C servos do have some 'over-travel' range below 1 and above 2 millisecond, but rarely do they publish what exact pulse range a specific model will except. And again there is no 'standard' specification that all servos travel a specific number of degrees.

However all is not lost. One can modify/edit the servo library to utilize the proper minimum and maximum pulse width values that apply to one's specific servo after testing what the values are. And if one still wants to work in degrees, modify the scaling used in the servo library. Of course a better method is to utilize the servo.writemicrosecond command to gain greater postioning resolution (>1000 'steps' Vs 180 'steps').

Another nice thing to come along is how cheap servos have become to play and learn with. Here is 5 servos for less the $3 each.

http://www.ebay.com/itm/5PCS-x-SG90-Micro-9g-Servo-For-RC-Airplane-Car-Boat-Genuine-/400471432862?pt=Radio_Control_Parts_Accessories&hash=item5d3df51e9e

Thanks, retrolefty for your comments. Just from the two different servos I bought, I can see that they sort of need to be custom programmed for a specific application if you are expecting them to behave in any precise manner (amount of travel, even the midpoint on one is really off, one travels more than 180 and one less, etc).