





















































This is an article written by Rodolfo Giometti, the author of the book BeagleBone Essentials.
The pulse-width modulation (PWM) is a technique used to encode a message in a pulsing signal, to generate an analog signal using a digital source, to allow the control of the power supplied to electrical devices, such as electrical motors, or to set the position of a servo motor.
In this article, we're going to discuss how an embedded developer can use the BeagleBone Black's PWM generator to control a servo motor with a few Bash commands.
(For more resources related to this topic, see here.)
A PWM generator is a device that can generate a PWM signal, according to its internal settings.
The output of a PWM generator is just a sequence of pulse signals as square waveforms with well-defined characteristics:
By referring to the preceding diagram, where we have a simple PWM waveform, we can define the following parameters:
In the preceding diagram, the amplitude is 5 V (ymax=5 V and ymin=0 V), the period is 1 ms (the wave is periodic and it repeats itself every 0.001 seconds), and the duty cycle is 25 percent (thigh=0.25 ms and T=1 ms).
You can find the details about the PWM at https://en.wikipedia.org/wiki/Pulse-width_modulation.
The PWM generator lines are reported in the following table:
Name |
Description |
PWM output |
The PWM output signal |
GND |
Common ground |
Our BeagleBone Black has eight PWM generators, and even if some of them may have their output lines multiplexed with another device, they cannot be used without disabling the conflicting device. The complete list is reported at the BeagleBone Black's support page (http://beagleboard.org/support/bone101) and summarized in the following table:
Name |
PWM output |
pwm0 |
P9.22 or P9.31 |
pwm1 |
P9.21 or P9.29 |
pwm2 |
P9.42 |
pwm3 |
P8.36 or P9.14 |
pwm4 |
P8.34 or P9.16 |
pwm5 |
P8.19 or P8.45 |
pwm6 |
P8.13 or P8.46 |
pwm7 |
P9.28 |
In the preceding table, the notation P9.22 means that pin 22 is on the expansion connector P9.
We can directly get these values from the BeagleBone Black firmware settings, using the following command:
root@BeagleBone:~# dtc -I dtb -O dts <dtbo> | grep exclusive-useHere, <dtbo> is one of the firmware files available in the /lib/firmware/ directory:
root@beaglebone:~# ls /lib/firmware/bone_pwm_*.dtbo
/lib/firmware/bone_pwm_P8_13-00A0.dtbo
/lib/firmware/bone_pwm_P9_16-00A0.dtbo
/lib/firmware/bone_pwm_P8_19-00A0.dtbo
/lib/firmware/bone_pwm_P9_21-00A0.dtbo
/lib/firmware/bone_pwm_P8_34-00A0.dtbo
/lib/firmware/bone_pwm_P9_22-00A0.dtbo
/lib/firmware/bone_pwm_P8_36-00A0.dtbo
/lib/firmware/bone_pwm_P9_28-00A0.dtbo
/lib/firmware/bone_pwm_P8_45-00A0.dtbo
/lib/firmware/bone_pwm_P9_29-00A0.dtbo
/lib/firmware/bone_pwm_P8_46-00A0.dtbo
/lib/firmware/bone_pwm_P9_31-00A0.dtbo
/lib/firmware/bone_pwm_P9_14-00A0.dtbo
/lib/firmware/bone_pwm_P9_42-00A0.dtbo
To enable a PWM generator, we have to use one of the preceding dtbo files in conjunction with the
/lib/firmware/am33xx_pwm-00A0.dtbo file, as
shown in the following code:
root@beaglebone:~# echo am33xx_pwm > /sys/devices/bone_capemgr.9/slots
root@beaglebone:~# echo bone_pwm_P9_22 > /sys/devices/bone_capemgr.9/slots
This should cause the following kernel messages activity:
[ 31.350494] bone-capemgr bone_capemgr.9: slot #7: Applied #8 overlays.
[ 46.144068] bone-capemgr bone_capemgr.9: part_number 'bone_pwm_P9_22', version
'N/A'
[ 46.144266] bone-capemgr bone_capemgr.9: slot #8: generic override
[ 46.144319] bone-capemgr bone_capemgr.9: bone: Using override eeprom data
at slot 8
[ 46.144374] bone-capemgr bone_capemgr.9: slot #8: 'Override Board
Name,00A0,Override Manuf,bone_pwm_P9_22'
[ 46.144640] bone-capemgr bone_capemgr.9: slot #8: Requesting part
number/version based 'bone_pwm_P9_22-00A0.dtbo
[ 46.144698] bone-capemgr bone_capemgr.9: slot #8: Requesting firmware
'bone_pwm_P9_22-00A0.dtbo' for board-name 'Override Board Name',
version '00A0'
[ 46.144762] bone-capemgr bone_capemgr.9: slot #8: dtbo 'bone_pwm_P9_22-
00A0.dtbo' loaded; converting to live tree
[ 46.148901] bone-capemgr bone_capemgr.9: slot #8: #2 overlays
[ 46.155642] bone-capemgr bone_capemgr.9: slot #8: Applied #2 overlays
Now, in the /sys/devices/ocp.3/ directory, we should see a new directory named pwm_test_P9_22.12, where we have the following files:
root@beaglebone:~# ls /sys/devices/ocp.3/pwm_test_P9_22.12/
driver duty modalias period polarity power run subsystem uevent
Here, the important files are period, duty, and polarity. In the period file, we can store the period (T) of the desired PWM waveform in nanoseconds (ns), while in duty, we can store the high state time (thigh) in nanoseconds (of course, with this parameter, we can set the duty cycle too). In the end, with the polarity file, we can invert the waveform polarity (that is, by swapping the high state and low state).
For example, the waveform of the preceding figure can be obtained using the following commands:
root@beaglebone:~# echo 1000000 > /sys/devices/ocp.3/pwm_test_P9_22.12/period
root@beaglebone:~# echo 250000 > /sys/devices/ocp.3/pwm_test_P9_22.12/
To show you how to use a PWM generator in order to manage a peripheral, we can use a servo motor. This is a really simple motor where we can set a specific gear position by setting a proper duty cycle of the PWM signal.
The following image shows the servo motor used in this example:
The device can be purchased at (or by surfing the Internet)
First of all, we've to set up the electrical connections. In the following table, we have reported the correspondence between the BeagleBone Black's pins and the servo motor's cables:
BeagleBone Black pins – Label |
Servo motor's cables – Color |
P9.4 – Vcc |
Red |
P9.22 |
Yellow |
P9.2 – GND |
Black |
By taking a look at the datasheet available at http://hitecrcd.com/files/Servomanual.pdf, we discover that the servo can be managed using a periodic square waveform of 20 ms period (T) and a high state time (thigh) between 0.9 ms and 2.1 ms with 1.5 ms as (more or less) the center.
So, once connected, we can set the center position using the following settings:
root@beaglebone:~# echo 0 > /sys/devices/ocp.3/pwm_test_P9_22.12/polarity
root@beaglebone:~# echo 20000000 > /sys/devices/ocp.3/pwm_test_P9_22.12/period
root@beaglebone:~# echo 1500000 > /sys/devices/ocp.3/pwm_test_P9_22.12/duty
Then, we can move the gear totally clockwise using the following command:
root@beaglebone:~# echo 2100000 > /sys/devices/ocp.3/pwm_test_P9_22.12/duty
We can move the gear totally anticlockwise using the following command:
root@beaglebone:~# echo 900000 > /sys/devices/ocp.3/pwm_test_P9_22.12/duty
In this article, we discovered that managing a BeagleBone Black's PWM generator is really as simple as controlling a servo motor!
Further resources on this subject: