|Pi IoT In Python Using Linux Drivers - PWM|
|Written by Harry Fairhead & Mike James|
|Monday, 11 October 2021|
Page 2 of 4
The PWM Driver
All Pi models have two PWM channels implemented in hardware, but on models earlier than the Pi 4 these are also used to generate audio. What this means is that if you want to use hardware PWM on a Pi Zero or earlier you have to disable or at least not use audio at the same time. You can use both on a Pi 4, but notice that the PWM channels and the audio share the same clock signal and this can still cause problems.
The two PWM hardware modules can be configured to drive different GPIO lines. For the Pi the standard configuration is to have PWM0 drive either GPIO18 or GPIO12 and PWM1 drive either GPIO13 or GPIO19.
There are two PWM drivers available. One that activates a single PWM channel and one that activates both the available channels. The documentation for both is:
Name: pwm Info: Configures a single PWM channel Legal pin,function combinations for each channel: PWM0:12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) PWM1:13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0)
Note: There is a relatively recent (late 2019) patch to the driver that fixes a problem at high PWM frequencies. Use:
sudo apt update
sudo apt full-upgrade
to make sure you have the up-to-date driver.
In simple terms you can use one or two channels of PWM and you would be well advised to use GPIO18 for PWM0 and GPIO19 for PWM1 on all modern Pis. Notice that you cannot currently use the driver to set the frequency of the PWM clock, but this is automatically enabled at a default frequency. You can find what the frequency is using:
vcgencmd measure_clock pwm
at the command prompt. It only reports an accurate value if the PWM driver is loaded and enabled. On a Pi Zero and a Pi 4 it reports 99995000, i.e. approximately 100Mhz, and empirical measurements give the effective clock rate, after division by 5, as 20MHz for both the Pi 4 and Pi Zero. The clock rate is important because it determines the resolution of the duty cycle – see later.
If you load either driver by adding:
to boot/config.txt, you will discover that on reboot you have a new pwmchip0 folder in the /sys/pwm folder.
The pi driver is configured to see the PWM hardware as a single PWM “chip”. To work with either PWM channel you have to export it. In this context exporting means that you claim sole use of the channel. To do this you have to write a “0” or a “1” to the export file in the pwmchip0 folder. To unexport you do do the same to the unexport file in the pwmchip0 folder.
After you have exported the channel you will see new folders, pwm0 and pwm1 in the pwmchip0 folder. Of course you only see the folders you have exported and you can only export pwm0 if you have use the PWM driver.
Within the pwmx folder you will find the following important files:
period period in nanoseconds duty_cycle duty cycle in nanoseconds enable write 1 to enable, 0 to disable
So all you have to do is:
Notice that as this is hardware PWM, once you have set and enabled the channel, the PWM generation continues after the program ends.
A simple program to use PWM0 is:
import subprocess import io def checkPWM(): indicator = "pwm-2chan" command =["sudo", "dtoverlay", "pwm-2chan"] temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout = subprocess.PIPE) output = str(temp.communicate()) print(output) if output.find(indicator)==-1: temp = subprocess.Popen(command,
The checkPWM function dynamically loads the pwm-2chan driver – you can change it to pwm if you only need one channel. It exports the channel and then sets the period to 100Hz with an 80% duty cycle. This program doesn’t need root permissions to run, only to dynamically install the driver. You can use the other channel in the same way.
|Last Updated ( Monday, 11 October 2021 )|