knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(rpigpior)
The Raspberry Pi exposes two PWM channels from the Broadcom chip. These appear on lines which also supply GPIO connections and so the Broadcom ALT functions need to be called.
PWM0 appears on board pins 12 (GPIO18) and 32 (GPIO12).
PWM1 appears on board pins 33 (GPIO13) and 35 (GPIO19).
This causes a confusing situation in two ways:
rpi_pwm()
handles these issues. If you stick to board pin numbers, it
will all work out. If you go astray, rpi_pwm()
will stop
and warn
you.
The Raspberry Pi analog audio output uses both PWM channels. You can't use hardware PWM and audio output at the same time.
Although it is possible to create software PWM, this isn't advised due
to latency of linux and R. rpigpior
does not supply any software PWM
channels.
Raspberry Pi OS uses the device tree to enable hardware PWM. You'll need to do a bit of behind-the-scenes editing to set this up.
To do this, edit /boot/config.txt as root.
On the Raspberry Pi, open a terminal window
Use the command sudo nano /boot/config.txt
. This will open the
nano text editor and display the contents of /boot/config.txt.
Add the dtoverlay
command at the end of the file. The easiest way
to determine the command to add to /boot/config.txt
is to ask
rpi_pwm()
for help. Set pwm_debug=TRUE
then select the pins you
want to use. If they aren't enabled, rpi_pwm()
will stop and
provide you with the correct dtoverlay
string. This looks
something like dtoverlay=pwm,pin18,func-2
but will change
depending on the pins you have chosen.\
\
If you want to do the math yourself, there is an excellent guide
available at
github.com/dotnet.
There is also linux documentation that discusses Enabling one PWM
channel
or Enabling a dual pwm
channel
Use control-o to write the file, then control-x to exit nano
Reboot your Raspberry Pi to enact this change.
Note that if you rebuild your SD card or reinstall Raspberry Pi OS on the OS card, you'll need to repeat this step.
rpi_pwm()
Here's an example:
rpi_pwm(c(12, 33), pwm_period = 50000, pwm_dutycycle = 25000) # This will enable PWM0 and PWM1 with a period (frequency) of 50000 and a duty cycle of 25000. That is to say, 50% power.
Or...
rpi_pwm(12, pwm_period = 50000, pwm_dutycycle = 10000) # This will turn PWM0 down to 20%
If you set pwm_debug = TRUE
then rpi_pwm()
will run diagnostics as
it goes.
rpi_pwm(12, pwm_period = 50000, pwm_dutycycle = 10000, pwm_debug = TRUE)
You've called rpi_pwm(pin_number)
where the pin (or pins) specified
don't supply hardware Pulse Width Modulation. On the Raspberry Pi, this
is only board pins 12, 32, 33, or 35. Keep in mind rpi_pwm()
only
specifies pins as board pins - not GPIO or BCM pins. Lots of
documentation will refer to these other pin numbering schemes.
As you know by now, the Raspberry Pi only has two hardware PWM channels, but each channel is connected to two pins:
PWM0 appears on board pins 12 (GPIO18) and 32 (GPIO12).
PWM1 appears on board pins 33 (GPIO13) and 35 (GPIO19).
So...if you are going to use two PWM channels, you need to use pins
connected to different channels. Since board pin 12 and 32 are both
connected to PWM0, it would be nonsense to use
rpi_pwm(pin_number = c(12,32)
. Instead, these are the valid
combinations:
rpi_pwm(pin_number = c(12,33)
rpi_pwm(pin_number = c(12,35)
rpi_pwm(pin_number = c(32,33)
rpi_pwm(pin_number = c(32,35)
If you try to select an invalid combination and pwm_debut = TRUE
you
will receive an error.
The PWM channel (or channels) you have selected are not yet enabled.
Enabling PWM is described in the above section titled [Enabling hardware
PWM on the Raspberry Pi] . The error message from rpi_pwm
supplies the
string you'll need to paste into /boot/config.txt
.
The Linux driver implementer's API guide has a chapter on PWM : https://www.kernel.org/doc/html/v5.10/driver-api/pwm.html
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.