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    
//setting ping GPIO 18 as a pwm output
//Set clock divisor to 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.

  • Try connecting a led and setting the clock divisor to 50x higher. Next set the duty cycle to 50% and check if the led blinks once a second.
    – Gerben
    Nov 20, 2013 at 14:10
  • I know this isn't an answer (hence, it's a comment) but you might want to try using ServoBlaster - it's working wonderfully for me. Nov 21, 2013 at 3:36

2 Answers 2


To answer the question "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.".

Recent Pis (the ones with the 40 pin expansion header) have two hardware PWM channels available.

Channel 0 is available on GPIO 12 and 18. Channel 1 is available on GPIO 13 and 19.

So you can have hardware PWM on GPIO 12/13/18/19. However 12 and 18 will have the same settings as will 13 and 19.

pigpio has C, Python, and command line methods to choose the settings.

From the command line

pigs hp GPIO 50 dutycycle

will start PWM at 50 Hz on GPIO (12, 13, 18, or 19) with dutycycle. dutycycle is 0 for 0% (off) or 1000000 for 100% (fully on).

0,8 ms is 0,8 / 20 % or a dutycycle of 40000. 2,1 ms is 2,1 / 20 % or a dutycycle 0f 105000

So for GPIO 18 with 0,8 ms pulses use

pigs hp 18 50 40000

By the way pigpio and servoblaster will let you generate servo PWM on any of the GPIO.

The pigpio method to generate a servo pulse of 0,8 ms on GPIO 23 is

pigs servo 23 800 # 800 denotes the desired pulse width in microseconds


I went through the same process. I finally got it by using a division of 1920 for the clock and a range of 200. This is more close to 50Hz, the requirement for servo SG90. Having range 200 it give you a resolution of 0.1ms. So for a 0.8 width it will be pwmWrite(PWM_NUMBER, 8). The PWM_NUMBER will depends on where you connected it and what type of setup function you use from wiringPi. If wiringPiSetupGpio() you can keep the 18 (GPIO24) if wiringPiSetup() then it work with 1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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