3

I've ran into a bit of an issue with the Raspberry Pi's ability to generate accurate PWM signals for servos. My problem with this is that the servos jitter because of this lack of accuracy. Is there any software or hardware I can use to fix this problem? I'm running everything in python 3, here's the script if you need it.

    import re
    import os
    import sys
    import RPi.GPIO as GPIO

    servoPos = [0, 1, 2, 3, 4]  # servoPos = [rightThumb,rightIndex,rightMiddle,rightRing,rightPinky]

    GPIO.setmode(GPIO.BCM)
    GPIO.setup(4, GPIO.OUT)
    GPIO.setup(17, GPIO.OUT)
    GPIO.setup(27, GPIO.OUT)
    GPIO.setup(22, GPIO.OUT)
    GPIO.setup(5, GPIO.OUT)

    right_thumb = GPIO.PWM(4,50)
    right_index = GPIO.PWM(17, 50)
    right_middle = GPIO.PWM(27, 50)
    right_ring = GPIO.PWM(22, 50)
    right_pinky = GPIO.PWM(5, 50)

    right_thumb.start(7)
    right_index.start(7)
    right_middle.start(7)
    right_ring.start(7)
    right_pinky.start(7)

    def servoUpdate():
        right_thumb.start(servoPos[0])
        right_index.start(servoPos[1])
        right_middle.start(servoPos[2])
        right_ring.start(servoPos[3])
        right_pinky.start(servoPos[4])


    for x in range(5):
        servoPos[x] = 7  # Resting Position


    def servoMove(servo, angle):
        if angle <= 12:
            if angle >= 2:
                servoPos[servo] = angle
                print(servoPos[servo])
            else:
                errorMessage(2)
        else:
            errorMessage(2)


    def servoStatus(servo):
        print(servoPos[servo])


    def screenClear():
        os.system('cls')  # 'clear' on linux and os x


    def errorMessage(error):
        if error == 1:
            print("[Error] - Invalid Command")
        elif error == 2:
            print("[Error] - Value Out Of Range (2-12)")


    def servoPosArray():
        print(str(servoPos).strip('[]'))


    def servoReset():
        for y in range(5):
            servoPos[x] = 7


    def stop():
        GPIO.cleanup()
        sys.exit()


    def commands(cmd):
        m = re.match(r"servoMove\ (\d+)\ (\d+)", cmd)
        if m:
            servoMove(int(m.group(1)), int(m.group(2)))
            return

        m = re.match(r"servoStatus\ (\d+)", cmd)
        if m:
            servoStatus(int(m.group(1)))
            return

        m = re.match(r"screenClear", cmd)
        if m:
            screenClear()
            return

        m = re.match(r"stop", cmd)
        if m:
            stop()
            return

        m = re.match(r"servoPosArray", cmd)
        if m:
            servoPosArray()
            return

        m = re.match(r"servoReset", cmd)
        if m:
            servoReset()
            return

        errorMessage(1)


    def main_loop():
        commands(input())
        servoUpdate()
        main_loop()


    main_loop()
2

you can use The PCA9685 is an I2C-bus controlled 16-channel, and then you have 16 channel to control your servos very easily. you can install the library with commands :

sudo apt-get install git build-essential python-dev
cd ~
git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
cd Adafruit_Python_PCA9685
sudo python setup.py install

you can use example code in an example folder.

1

The RPi.GPIO software PWM is notoriously inaccurate. I also found it to be quite crashy.

The Pi has a couple of hardware PWM pins that can be used to generate very accurate signals, but it looks like you're driving more than a couple of servos, so by itself that won't be sufficient.

The RPIO.PWM module uses the hardware PWM timer to drive multiple DMA-based software PWM channels. From the docs:

Since the PWM is done via DMA, RPIO.PWM uses almost zero CPU resources and can generate stable pulses with a very high resolution.

I haven't used it myself, but it is on my list of Things To Look At If I Need More PWM :). Assuming it works as advertised that sounds like it might be the solution to your problem.

Alternately, get something like the servo HAT for multiple hardware PWM channels.

  • 1
    FWIW, the RPIO library hasn't been maintained for a few years, it isn't compatible with newer Pis. – tedder42 Jun 30 at 20:37
0

As has been mentioned, RPi.GPIO does not generate a very stable signal and will result in very jittery servo control. I have had much better success with the pigpio library. This does require you to install a daemon on the Pi, but that comes with other benefits such as being able to run code that accesses the GPIO remotely.

Your Answer

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