Raspberry Pi IoT In C - Basic Pulse Width Modulation
Written by Harry Fairhead   
Monday, 20 June 2022
Article Index
Raspberry Pi IoT In C - Basic Pulse Width Modulation
Clock rate
How Fast

PWM is a workhorse of many motor and power control applications. This is an extract from Raspberry Pi IoT in C, Second Edition.

Raspberry Pi And The IoT In C Second Edition

By Harry Fairhead


Buy from Amazon.


  1. Why Pi For IoT?
  2. Getting Started
  3. Getting Started With The GPIO
  4. Simple Output
  5. Some Electronics
  6. Simple Input
  7. GPIO The Linux Way
       Extract 1:The Linux GPIO Driver 
  8. Advanced Input – Events, Threads, Interrupts
       Extract 1: Events & Interrupts 
  9. Pulse Width Modulation - Servos And More
       Extract 1:Basic Pulse Width Modulation 
  10. Using The I2C Bus
  11. The DHT22 Sensor Implementing A Custom Protocol
  12. Exploring - 1‑Wire Bus Basics ***NEW!
  13. Using iButtons
  14. DS18B20 Temperature Sensor
      Extract 1: The DS18B20 Temperature Sensor 
  15. The Multidrop 1‑Wire Bus
  16. The Serial Port
      Extract 1: 1-wire Via Serial 
  17. Getting Started With The SPI Bus
  18. A to D With The SPI Bus
  19. Connecting With The Web - Sockets
  20. Memory-Mapped GPIO
  21. Almost Real-Time Linux
  22. Appendix I GPIO Sysfs Interface



One way around the problem of getting a fast response from a microcontroller is to move the problem away from the processor. In the case of the Pi's processor there are some built-in devices that can use GPIO lines to implement protocols without the CPU being involved. In this chapter we take a close look at Pulse Width Modulation (PWM) including generating sound, driving LEDs and servos.

When performing their most basic function, i.e. output, the GPIO lines can be set high or low by the processor. How fast they can be set high or low depends on the speed of the processor.

Using the GPIO line in its Pulse Width Modulation (PWM) mode you can generate pulse trains up to 4.8MHz, i.e. pulses as short as just a little more than 0.08µs. You can even go faster if you are prepared to do some additional work. The reason for the increase in speed is that the GPIO is connected to a pulse generator and, once set to generate pulses of a specific type, the pulse generator just gets on with it without needing any intervention from the GPIO line or the processor. In fact, the pulse output can continue after your program has ended if you forget to reset it.

Of course, even though the PWM line can generate pulses as short as 0.1µs, it can only change the pulses it produces each time that the processor can modify them. For example, you can't use PWM to produce a single 0.1µs pulse because you can't disable the PWM generator in just 0.1µs.

Some Basic Pi PWM Facts

There are some facts worth getting clear right from the start, although some of their significance will only become clear as we progress.

First, what is PWM? The simple answer is that a Pulse Width Modulated signal has pulses that repeat at a fixed rate - say one pulse every millisecond, but the width of the pulse can be changed.

There are two basic things to specify about the pulse train that is generated, its repetition rate and the width of each pulse. Usually the repetition rate is set as a simple repeat period and the width of each pulse is specified as a percentage of the repeat period, referred to as the duty cycle.

So, for example, a 1ms repeat and a 50% duty cycle specifies a 1ms period, which is high for 50% of the time, i.e. a pulse width of 0.5ms. The two extremes are 100% duty cycle, i.e. the line is always high, and 0% duty cycle, i.e. the line is always low.

Notice it is the duty cycle that carries the information in PWM and not the frequency. What this means is that generally you select a repeat rate and stick to it and what you change as the program runs is the duty cycle.

In many cases PWM is implemented using special PWM-generator hardware that is built either into the processor chip or provided by an external chip. The processor simply sets the repeat rate by writing to a register and then changing the duty cycle by writing to another register. This generally provides the best sort of PWM with no load on the processor and, generally, glitch-free operation. You can even buy add-on boards that will provide additional channels of PWM without adding to the load on the processor.

The alternative to dedicated PWM hardware is to implement it in software. You can quite easily work out how to do this. All you need is to set a timing loop to set the line high at the repetition rate and then set it low again according to the duty cycle. You can implement this either using interrupts or a polling loop and in more advanced ways, such as using a DMA (Direct Memory Access) channel.

In the case of the Pi, the PWM lines are implemented using special PWM hardware.

The big problem is that, although there are two PWM implementations, both of which are available, the second PWM is used for sound generation. However, as long as you don't want to use sound, you can use both PWM channels on the Pi 4 and Pi Zero and this is enough to run two servos or motors. The main PWM channel zero is brought out on the connector on pin 2 via GPIO 18. The secondary channel, which is also used by the system for sound generation, is brought out on the connector on pin 35 via GPIO 13 – obviously you can only use it if you don't want sound generation.

Both PWM lines are driven by the same clock and this sometimes causes people to conclude that the two lines must work at the same repeat rate. Although there are some restrictions, each PWM line can be set to its own repeat rate.

Two PWM lines is limiting and often forces users to either use hardware expansion or implement PWM in software.

As you can guess, there are no PWM inputs, just output. If for some reason you need to decode, or respond to, a PWM input then you need to program it using the GPIO input lines and the pulse measuring techniques introduced in the previous chapters.

Last Updated ( Saturday, 25 June 2022 )