Is there a way to stop servos from "shaking"?

When using the Servo library on an Arduino, a common source of servo buzz is that the interrupt-driven servo routines don't actually give a very stable output pulse. Because the AVR takes interrupts for servicing the millis() clock and other things in the Arduino runtime, the jitter in the Servo library is on the order of several microseconds, which translates to a lot of movement in the servo.

The fix for this is to write your own pulse. Something like this:

cli();
long start = micros();
digitalWrite(PIN, HIGH);
while (micros() - start < duration)
  ;
digitalWrite(PIN, LOW);
sei();

This will turn off other interrupts, and generate a much cleaner PWM pulse. However, it will make the "millis() timer miss some clock ticks. (The "micros()" function may be called something else -- I forget exactly what.)

In general, for timing critical code, you want to get rid of the Arduino runtime entirely, and write your own using the avr-gcc compiler and avr-libc library that powers the Arduino environment. Then you can set up a timer to tick 4 times per microsecond, or even 16 times per microsecond, and get a much better resolution in your PWM.

Another cause of buzz in servos is cheap servos with cheap sensors, where the sensors are noisy, or when the exact position requested with the pulse can't actually be encoded by the sensor. The servo will see "move to position 1822" and try to do it, but ends up with the sensor reading 1823. The servo will then say "move back a little bit" and it ends up with the sensor reading 1821. Repeat! The fix for this is to use high-quality servos. Ideally, not hobby servos at all, but real servos with optical or magnetic absolute encoders.

Finally, if the servos don't get enough power, or if you try to drive their power from the 5V rail on the Arduino, this will generate voltage-sag-induced buzz in the servos, as suggested above. You may be able to fix it with large electrolytic capacitors (which are a good idea for general filtering anyway) but you more likely want to make sure your servo power source can actually deliver several amps of current at the servo voltage.


This is called "buzz".

There are a couple of things that will cause it. Instability in the power to the servo is a common cause. R/C servos can draw some BIG spikes when they first put the motor in motion.

Many years ago, I played with a Tower Hobbies Royal Titan Standard servo, controlling it from a 555 and a one-transistor inverter. Dead-simple control circuit. I learned that the servo motor drew 250 mA from the 5V supply while in continuous motion. Buzzing, it easily drew half-amp spikes. (Maybe more: I was just monitoring the current meter on my bench supply, not scoping a current-sensing shunt.)

It took 220 uF directly across my servo to tame it.

Try putting an electrolytic capacitor, at least 100 uF, directly across the power supply to the servo, as electrically close to the servo as you can, and see if that helps.

Based on those experiments, I would never consider using R/C servos for ANYTHING without adding capacitors. That includes radio-controlled models.

This can also be caused by dirt in the servo pot inside the servo. Try the capacitor first.


Is your buzzing/shaking happening only when at or close to the servo's limits (0 degrees or 180 degrees)? If so, there may be a simple fix for you. I have found that cheap servos don't know how to stay at the limits of their movement very well, which can cause the buzzing/shaking you're mentioning. However, if you just limit their range to 10~170 degrees, the issue will be fixed.

If that's not good enough for you, you can follow the more complex fixes mentioned in the other answers, like better power, better servo sensors, etc.

Tags:

Arduino

Servo