1

My setup is simply the servo JX-PDI-6221MG being directly activated with raspberry pi's PWM through GPIO library. The servo is brand new, I followed this tutorial and set duty cycle values between 0 and 100. The angles it makes have no pattern, it seems to go one way from 20 to 50 and them from 60 to 90 the other.

I decide to loop through all possible duty cycles (code is below) and I confirm that the variations aren't smooth and it doesn't look precise. After trying to set fix values again it suddenly starts to spin in multiple directions, even without I changing anything. Not even GPIO.cleanup() or killing python related processes made it stop.

Is my Raspberry Pi getting jitter and being very imprecise or was I a victim of falsification?

Code:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.OUT)
pwm=GPIO.PWM(11,330) #which is the same as shown in datasheet
pwm.start(0)

for i in range(0,100):
     pwm.ChangeDutyCycle(i)
     time.sleep(0.02)

for i in range(0,100):
     i = 100 - i
     pwm.ChangeDutyCycle(i)
     time.sleep(0.02)`
1
  • Note that software PWM on your Pi is pretty terrible. There are a limited number of hardware PWM pins available (either 1 or 2, depending on your model), and there are some workarounds for better software PWM (e.g., RPIO.PWM). This isn't posted as an answer because it sounds like maybe there is more going on then simply slightly unstable PWM. You may want to consider asking this on raspberrypi.stackexchange.com instead.
    – larsks
    Commented Jun 7, 2018 at 2:56

3 Answers 3

2

Servos generally need precise timing, so on a non-realtime device like the Raspberry Pi that means you need to use the hardware PWM pins. RPi.GPIO only supports software emulated PWM, so you need to use another library, e.g. pigpio.

1

AFAIK, only GPIO 18 can be used by GPIO library for hardware PWM. try changing tht GPIO.OUT to that.

Also try using pigpio library which allows ANY GPIO pin to do hardware timed PWM.

1
  • RPi.GPIO actually does not support hardware PWM at all. And the hardware does not support PWM on all pins. Only two PWM channels can be active simultaneously, and they are limited to a select few pins.
    – Henrik
    Commented May 23, 2020 at 11:15
0

This is because that Raspberry Pi is a non-Realtime controller.

For that, try to use pigpio, this library includes a support for hardware PWM.

Quick example:

import sys
import time
import random
import pigpio

NUM_GPIO=32

MIN_WIDTH=1000
MAX_WIDTH=2000

step = [0]*NUM_GPIO
width = [0]*NUM_GPIO
used = [False]*NUM_GPIO

pi = pigpio.pi()

if not pi.connected:
   exit()

if len(sys.argv) == 1:
   G = [4]
else:
   G = []
   for a in sys.argv[1:]:
      G.append(int(a))
   
for g in G:
   used[g] = True
   step[g] = random.randrange(5, 25)
   if step[g] % 2 == 0:
      step[g] = -step[g]
   width[g] = random.randrange(MIN_WIDTH, MAX_WIDTH+1)

print("Sending servos pulses to GPIO {}, control C to stop.".
   format(' '.join(str(g) for g in G)))

while True:

   try:

      for g in G:

         pi.set_servo_pulsewidth(g, width[g])

         # print(g, width[g])

         width[g] += step[g]

         if width[g]<MIN_WIDTH or width[g]>MAX_WIDTH:
            step[g] = -step[g]
            width[g] += step[g]

      time.sleep(0.1)

   except KeyboardInterrupt:
      break

print("\nTidying up")

for g in G:
   pi.set_servo_pulsewidth(g, 0)

pi.stop()

You can take a look on Servo Code from Python examples at pigpio website.

Or, check out the support of pigpio in gpiozero.

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