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

    '''
    James Mueller
    9:24 PM  / 1/7/2018   / 1-9-7-5       // Added this thing to keep the update features organised.
    9:28 PM  / 1/7/2018   / 1-10-7-5      // New Command Line Interface style.
    1:53 PM  / 1/8/2018   / 1-11-7-5      // Changed servo listing command.
    3:36 PM  / 1/13/2018  / 1-12-7-5      // Adding support for servos.
    '''

    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.

  • 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

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.