After a week of hardware and mechanical issues with the AirMobile sensor, my self-esteem was at an alarming low level.
So I switched to tasks that could bring me some satisfaction.
I started wondering how to demonstrate some automation capabilities as required by the challenge.
So I decided to build a "Air Quality" gauge.
The gauge will have a moving needle that will notify about the current air quality. The handle will be moved by means of servo control.
To control the servo, I need two things:
- a PWM output on the BeagleBoardBlack Cape connectors
- a piece of software that make it possible to drive the servo from OpenHAB
In this post I will focus on how to configure an output of the BeagleBoneBlack for PWM
PWM Output
The BBB was specifically designed to be a dynamic piece of hardware, enabling third-party developers to create their own custom configurations and extensions known as capes. The board is so flexible, it can change its hardware configuration at runtime using an in-kernel mechanism known as the Cape Manager in conjunction with Device Tree Overlays.
The Device Tree consists of a set of human readable text files known as DTS files that end in the “.dts” extension. DTS files can be edited using a simple text editor to set the configuration for a particular pin. These source files then get compiled into DTB files, a binary format ending in the “.dtbo” extension. This process creates what are known as device tree fragments or overlays. The kernels Cape Manager can then dynamically load and unload the DTB files post-boot as well as at runtime to set the hardware configuration. For a more in-depth look on how to use device tree overlays, The following links have been very useful to understand how overlays work:
Derek Molloy, Beaglebone: Introduction to GPIOs – Using Device Tree Overlays under Linux 3.8+
Luckily for our purposes, creating a new overlay for configuring PWM is not necessary. Turns out a set of overlays are already present in the “/lib/firmware” directory:
1 2 3 4 5 6 | root@beaglebone:/lib/firmware# ls *pwm* am33xx_pwm-00A0.dtbo am33xx_pwm-00A0.dts bone_pwm_P8_13-00A0.dtbo bone_pwm_P8_13-00A0.dts ... |
All we need to do is load them using the Cape Manager, but first, lets get acquainted with a very useful command that will help us determine if our overlays were properly loaded:
root@beaglebone:~# more /sys/devices/bone_capemgr.9/slot 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
Out of the box, the BBB shows the above slots. Lets add two more slots to configure pin 13 on header P8 for PWM by executing the following commands:
root@beaglebone:~# echo am33xx_pwm > /sys/devices/bone_capemgr.9/slots root@beaglebone:~# echo bone_pwm_P8_13 > /sys/devices/bone_capemgr.9/slots
To confirm the overlays loaded properly we run the slots command again:
root@beaglebone:~# more /sys/devices/bone_capemgr.9/slots 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 7: ff:P-O-L Override Board Name,00A0,Override Manuf,am33xx_pwm 8: ff:P-O-L Override Board Name,00A0,Override Manuf,bone_pwm_P8_13
Our board is now configured for PWM on pin13 of the P8 header! Before we move on, however, it’s worth noting these changes are not permanent. If you power off the board, the PWM slots we just added will disappear. Thankfully, we don’t have to repeat the above steps each time we power up the board. The Cape Manager supports a method to load the overlays at boot time by adding the following argument to the “uEnv.txt” file:
capemgr.enable_partno=am33xx_pwm,bone_pwm_P8_13
Make sure to append the argument in a single line like this:
root@beaglebone:~# more /media/BEAGLEBONE/uEnv.txt optargs=quiet drm.debug=7 capemgr.enable_partno=am33xx_pwm,bone_pwm_P8_13
Once the pwm_test_P8_13 directory exists you'll want to move to it and set run to 0 to disable output while you configure the PWM. Below, I set the period to 20 ms and a starting duty of 1 ms, after enabling output again the servo will swing to left of its central position. After echoing 2 ms into the duty the servo should move to right of its center.
# cd /sys/devices/ocp.3/pwm_test_P8_13.* # echo 0 >run # cat period 500000 # cat duty 0 # cat duty 1 # echo 0 > polarity # echo 20000000 > period # echo 1000000 > duty # echo 1 >run