Servo jittering and not turning fully

Question:

I started a project with servos, making a crude robotic arm, with two servos. the issue is, that my servo keeps jittering when stationary, sometimes too much, and can cause the thing to fall over. Also, whenever i enter an angle for the servo to turn to ( using GPIOZERO library ) it doesnt seem to turn the full way. for example, when i enter 90 degrees, the server seems to stick around 70 degrees. the servos are attached parallel to the floor, and when not powered, i can manually move them which shows that they can turn more than they are. Here is the code below.

from gpiozero import AngularServo
from time import sleep

joint_base = AngularServo(14, min_angle=-90, max_angle=90)
joint_top = AngularServo(15, min_angle=-90, max_angle=90)
angle_base = 0
angle_top = 0
while True:
    angle = int(input())
  
    angle_base = angle
    joint_base.angle = angle_base

    angle_top = 90-angle_base
    joint_top.angle = angle_top

    print(angle, angle_base, angle_top)

    
   
Asked By: Anton Chernyshov

||

Answers:

I thought I’d turn this from a comment into an answer.

Servo jitter often means that your controller isn’t able to maintain accurate timing. This is a common issue with tools that generate the PWM in software, particular for a non-realtime device like the Pi. You could experiment with something that has support for hardware PWM and see if that improves the situation. The pi supports two hardware PWM channels (see e.g. this article).

The pigpio module has support for hardware PWM, and it looks as if support for this is available in gpiozero.

But in theory you already knew that; if I run your code locally, I see:

/usr/lib/python3/dist-packages/gpiozero/output_devices.py:1532: PWMSoftwareFallback: To reduce servo jitter, use the pigpio pin factory.See https://gpiozero.readthedocs.io/en/stable/api_output.html#servo for more info


If we modify your test program so that it looks like this (there’s only one servo here because I only had a single servo handy at my desk)…

from gpiozero.pins.pigpio import PiGPIOFactory
from gpiozero import AngularServo
from time import sleep

factory = PiGPIOFactory()
joint_base = AngularServo(17, min_angle=-90, max_angle=90, pin_factory=factory)
angle_base = 0
while True:
    angle = int(input("Angle: "))

    angle_base = angle
    joint_base.angle = angle_base

    print(angle, angle_base)

…then all the jitter goes away.

Answered By: larsks