Controlling a servo with raspberry pi using the hardware PWM with wiringPi

user2543697 picture user2543697 · Nov 19, 2013 · Viewed 25.5k times · Source

I tried controlling the servo with softPwm using the wiringPi Library but this made the servo stutter. Therefore I want to use the hardware PWM pin on the Raspberry Pi (GPIO18) with the wiringPi library. But I don't understand how to set the frequency to 50 Hz and change the duty cycle to have a pulse width ranging from 0.8 ms to 2.5 ms.

I found the following relationship on the internet (i dont know if it is correct):

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.

i know the clock divisor max value is something around 4000 and the Raspberry Pi PWM clock has a base frequency of 19.2 MHz. so this gives me ~4,8KHz.

i already got these settings which should give me ~50Hz using the following relationship:

//put PWM in mark-space mode, which will give you 
//the traditional (and easily predictable) PWM    
pwmSetMode(PWM_MODE_MS);
//setting ping GPIO 18 as a pwm output
pinMode(18,PWM_OUTPUT);
//Set clock divisor to 4000
pwmSetClock(4000);
pwmSetRange (10) ;

I dont got a oscilloscope to test the output signal to check what setting changes what. this makes it hard to find it out myself.

Long story short: Can anyone tell me how I can achieve a duty cycle with a pulse width of 0,8ms to 2,1ms for controlling a servo using the hardware PWM on the Raspberry Pi.

Answer

Koen picture Koen · Jan 25, 2014

I'm a complete newby to Pi and to Servo's. But I got it to work with wiringPi.

It says here that we're looking to create pulse of 1ms to 2ms in length, every 20ms or so. Assuming this 19.2Mhz base clock is indeed correct, setting pwm clock to 400 and pwm range to 1000, should give a pulse at 48Hz or every 20.8 ms. Then setting pwm value to 48 should give you a 1ms long pulse and a pwm value of 96 should give you a 2ms long pulse. But you need to set the chip in pwm-ms mode. (Lots of shoulds here, since I do not have an osciolloscope either)

So to set it up:

  • gpio mode 1 pwm
  • gpio pwm-ms
  • gpio pwmc 400
  • gpio pwmr 1000

And then you can turn the servo from left to right via

  • gpio pwm 1 48
  • gpio pwm 1 96

(Actually, the servo I got worked from 28 up to 118; could be the servo) (The setup sequence seems important; could be a bug)