Pi IoT In Python Using GPIO Zero - PWM
Written by Harry Fairhead & Mike James   
Monday, 28 February 2022
Article Index
Pi IoT In Python Using GPIO Zero - PWM
Software PWM
How Fast Can You Modulate

PWM - Pulse Width Modulation is a very common way of controlling everything from LEDs to Servos. In this extract from our book on using GPIO Zero on the Pi in Python we look at how to get started.

Raspberry Pi IoT In Python Using GPIO Zero
Second Edition

By Harry Fairhead & Mike James


Buy from Amazon.


  1. Why Pi for IoT?
  2. Getting Started With Python And GPIO Zero
  3. Introduction to the GPIO
  4. Python - Class and Object
  5. Simple On/Off Devices
      Extract 1: On/Off Devices *
  6. Pins And Pin Factories
      Extract 1: Pins 
  7. Some Electronics
  8. Simple Input
      Extract 1:Getting Input ***NEW!!
  9. Complex Input Devices
      Extract 1: Complex Input *
  10. Pulse Width Modulation
      Extract 1:  PWM*
  11. Controlling Motors And Servos
      Extract 1: DC Motors *
  12. Working With Compound Devices
      Extract 1: Compound Devices*
  13. The SPI Bus
  14. Custom SPI Devices
  15. Using The Lgpio Library
  16. Appendix Visual Studio Code Remote Python
    *Extracts from first edition - will be updated.


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 and driving LEDs.

When performing their most basic function, i.e. output, the GPIO lines can be set high or low by the processor. How quickly 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 just a little more than 0.08µs. The reason for the increase in speed, a factor of at least 100, 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.

Hardware-generated PWM sounds like a really good idea, and it is, but there is a problem. A the time of writing, none of the pin factories actually support the use of hardware for PWM. They all generate PWM signals using software although two pin factories, RPIO and pigpio, use advanced methods that put minimum load on the CPU.

At the moment the default RPi.GPIO pin factory supports only software-implemented PWM. While this means you can use any pin as a PWM output, the speed is limited by how much power the CPU can dedicate to the task. There are plans to support hardware PWM in the future, but there seems to be very little activity on the project’s site.

The alternatives offer some advantages and some big disadvantages as discussed in Chapter 6. RPIO implements PWM on any GPIO line using software and DMA. This puts much less strain on the CPU and can generate very fast PWM signals. However, as noted in Chapter 6, this project appears to be defunct. The pigpio pin factory also uses DMA to generate PWM signals, but by making use of a daemon – a driver that runs all the time in the background. There are suggestions that this daemon isn’t 100% stable and support for Pi 4 is still experimental. However, the project does seem alive and well.

I would advise using the RPi.GPIO, rpigpio, pin factory and if you really need high-speed PWM then I would suggest moving to C and working with the hardware directly. Here we will mostly ignore the hardware PWM features of the Pi. If you want to make use of it then see Raspberry Pi IoT in C, Second Edition, ISBN:9781871962635.

Some Basic Pi PWM Facts

There are some facts worth getting clear right from the start, although their full 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. The duty cycle is simply the proportion of time the line is set high. 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-generating hardware that is either built 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.

Last Updated ( Monday, 28 February 2022 )