Inside Servos
I’ve been working on a hobby project lately (…a robot that squirts ketchup) and ran into some issues with some cheap continuous rotation servos I bought. It seemed kinda impossible to calibrate them and I wasn’t sure what I was doing wrong.
I talked to some knowledgable people and got the following information back.
Potentiometers
If you’re not familiar with potentiometers, they’re basically variable-resistance resistors. Servos use them to determine what “position” the servo arm is in. For example for a 5v servo your potentiometer may go from 0v to 5v where 0v is the leftmost point your servo can turn to and 5v is the rightmost point. Pulse-width modulation (PWM) allows you to output “less” or “more” voltage by controlling how frequently your voltage pulse is on or off. So 5v on 50% of the time would read as 2.5v and your servo would move to the position that corresponds to 2.5v.
In a typical servo, voltage corresponds to position.
Continuous Rotation Servos
Continuous rotation servos don’t physically limit the arm so instead of moving to a point at a given voltage, the arm won’t stop! More or less voltage goes from controlling the position to controlling the speed of the servo’s spin.
A continuous rotation servo has a “center” voltage where the directions cancel out and the thing stops spinning. Turns out this is generally adjustable (and requires calibration if you want the center to be exactly some value).
To reiterate, in a continuous rotation servo, voltage corresponds to speed and direction of spin.
Potentiometer Calibration
Continuous rotation servos generally come with a little screw you can turn to adjust the potentiometer. The calibration process works like this:
- Send a PWM signal to the servo you want to calibrate that should be its “neutral” position. For most RC servos this is a pulse width of 1500 usec, but as always in hobby electronics, read the effing data sheet.
- If the servo is not perfectly centered it will be moving. It should be moving.
- Now find the screw that corresponds to the potentiometer and turn it very slowly in the opposite direction of which it’s moving. You should see the servo slow down. When you get the servo to stop completely, you’ve successfully centered your continuous rotation servo.
PWM Signal Resolution
You might write a naive program to send PWM messages to your servos and find weird behaviors:
- My servo is not responding at all!
- Very small values (100-300 usec pulse width) seem to work when according to the data sheet the operating range is only 800-2300 usec pulse widths. What gives?
Chances are you fell victim to signal resolution. For example the PCA 9685
servo controller has a resolution of 4usec at 60HZ. That means if you send PWM signals at 60HZ (standard for analog RC
servos) then 1 “count” you send is actually 4usec. You probably made a mistake and thought you were sending actual pulse
width when in reality you were sending pulse counts (how many times to pulse in a 4096 pulse width period). So if you sent
1500
counts, you were actually saying “Send 1500*4usec pulses” which is obviously nonsense since your whole pulse width is
only 4096.
To send 1500
you should really send ~375
pulses (1500/4).
Digital Servos
Digital servos generally operate at 350Hz+. At higher PWM frequencies the resolution increases so 1 count ~= 1 pulse width. So my large digital servo worked perfectly.
Cheap Continuous Rotation Servos
OK going back to the original problem I was having. I made two mistakes. First I was sending counts, not PWM values as I thought, and neglected to divide my desired PWM signal by 4.
Secondly the potentiometers in these tiny servos are incredibly fragile. I tried getting them to stop to get a good midpoint but found myself woefully unable to calibrate them all to work the same. I found out quickly that if you turn the potentiometer too much you end up breaking it and it gets stuck on a single voltage (1 speed servo, yay).