PWM – Every robotics enthusiast has heard of this term. Some fear it with a vengeance. Just kidding. But it is incredibly useful though! PWM is the short form for Pulse Width Modulation. I won’t go into detail on what PWM is exactly but I will briefly deal with it. Most of this post will be about how to use the in-built PWM modules on the Beaglebone.
PWM probably comes from communications but what it essentially is is a square wave (No, the double is was not a typo!). Well, not exactly a square wave… But imagine this. Take a square wave like this one:
Now, keep the rising edge at the same position each time and only move around the falling edge between the previous and the next rising edge. That is PWM for you! Basically, you’re modifying the width of the pulses but you keep the time period constant. That means a PWM signal has a characteristic frequency which is kept constant because if it were to be modified, it wouldn’t be called PWM but rather Pulse Position modulation (PPM – The digital analog of frequency modulation) but we don’t need to get into that! A PWM signal looks like this:
There are different ways in which PWM can be produced. In the image above, you can see that he takes the point at which the triangular wave cuts through the input signal for both sides of the pulse. In other cases, only the rising edge is used for syncing and the pulse starts agains after the signal is over. In this kind, a sawtooth signal as opposed to a triangular wave. The duty cycle of a PWM signal is the ratio of the ON portion of the wave to the whole time period. In our case, we will use a constant duty cycle in the short scale and vary it when we need to.
So that’s the basics of PWM. Now what is it used for? With digital controllers, it is difficult to produce an analog voltage. You need to work with DACs (Digital to analog converters) and it is generally a pain to use. Another problem with DAC is that sometimes, like when you’re controlling an LED, it is current controlled and has a threshold voltage. Since it is current controlled, you lose some power on the resistor you put in series to carry the extra voltage drop. What you do instead is use a PWM signal. If you take a high enough frequency (Even 50 Hz would do) and you use the PWM signal to control a transistor switch (Which in turn controls your load, in this case the LED), an averaging effect occurs and the LED brightness can be varied easily by changing the duty cycle. With this, you can have very low duty cycle which can achieve very low brightness which cannot be done with a voltage controller. Awesome, right?!
With respect to quadrotors, how is it used, you say. Well, I may get into the working of the BLDC (Brushless DC Motors) in a later post but basically it takes three sinusoidal inputs which are 120 degrees out of phase with one another. This is fairly difficult to generate, especially because the currents are insanely high. So what we do is use an ESC (No, not escape, Electronic Speed Controller). These are high power devices which take a 12V input and provide three output wires to connect to the motor. Easy enough. Just match them up. Be careful about the polarities (Two will be opposite – Again, I’ll post about this in a later post). So how do you control the speed? You cannot directly vary the voltage, especially because the power is so much.
Generally, ESCs are programmable and require a PWM input to control the speed. For example, in my ESC,
by varying the frequency from 50Hz – 60Hz you fix the frequency at some value between 50-60Hz and vary the duty cycle from 1ms-2ms to set the speed. At 1ms, the motors will be off and 2ms, it will be maximum. For initial tests, I was using something like 1.2ms. Apparently, this is the perfect format for radio controllers but using a microcontroller has the same effect. I would suggest using a circuit in between, just to be safe. I haven’t done that with this microcontroller yet because I was working on using the PWM modules on the Beaglebone itself. Here’s how it works:
There are three enhanced high resolution PWM modules (ehrpwm). Each has two outputs. The duty cycle of the two outputs can be different but they both have to be at the same frequency and the same run state.
This posed a problem because I only had access to three outputs of which I could control the frequency! Well, let’s trying using them anyway (Hmmm… What is that itching sensation up my sleeve?) That means each PWM module can control two motors each giving control over a total of 6 motors.
First, the mux settings have to be adjusted to allow the PWM output to be provided at the particular pins as shown below. The first module is called the ehrpwn.0
The two pins are denoted as ehrpwm.0:0 (Pin P9-31) and ehrpwm.0:1 (Pin P9-29) respectively. Those are the pin numbers where the output will appear. Here is what you have to do.
root:~# echo 1 > /sys/kernel/debug/omap_mux/mcasp0_aclkx
root:~# echo 1 > /sys/kernel/debug/omap_mux/mcasp0_fsx
If you want to use the second module: ehrpwm.1:0 (Pin P9-14) and ehrpwm.1:1 (Pin P9-16) respectively:
root:~# echo 6 > /sys/kernel/debug/omap_mux/gpmc_a2
root:~# echo 6 > /sys/kernel/debug/omap_mux/gpmc_a3
For the third module: ehrpwm.2:0 (Pin P8-19) and ehrpwm.2:1 (Pin P8-13) respectively:
root:~# echo 4 > /sys/kernel/debug/omap_mux/gpmc_ad8
root:~# echo 4 > /sys/kernel/debug/omap_mux/gpmc_ad9
I got all this information from the datasheet. You can go through it in detail. Note that the first module can be obtained at a second set of pins if you want.
After doing all this, the PWM settings are directly exposed in the file system. The main ones we will be dealing with are: period_freq (Frequency in Hz) and duty_percent (Duty cycle)
We covered both of these features in the intro section. Make sure the duty_percent is set to 0 before changing the period. Otherwise, it is said that the duty_percent may be randomly changed to a different value. If i and j define the PWM module and the output:
root:~# cd /sys/class/pwm/ehrpwm.i:j
root:/sys/class/pwm/ehrpwm.i:j# echo 1 > request
root:/sys/class/pwm/ehrpwm.i:j# echo 0 > duty_percent
root:/sys/class/pwm/ehrpwm.i:j# echo 1 > period_freq
// Sets the duty cycle in percent
root:/sys/class/pwm/ehrpwm.i:j# echo 50 > duty_percent
// Sets the duty cycle in nano seconds. Use either
root:/sys/class/pwm/ehrpwm.i:j# echo 1000000 > duty_ns
root:/sys/class/pwm/ehrpwm.i:j# echo 1 > run
For example: root:~# cd /sys/class/pwm/ehrpwm.0:0
It is good to check the availability of the PWM pins first through the following command.
root~:/sys/class/pwm/ehrpwm.i:j# cat request
ehrpwm.i:j is free
period_freq is directly in hertz while the duty_percent is in percent. The polarity is also useful to invert the logic.
Easy enough, right? Beats embedded C any day of the week and twice on Sunday! (Stole that from some movie :D)
So what about that fourth motor!! So what about that extreme case you want to control 8 motors? Do we just pair up two motors, sacrificing mobility?
NO!! There is another module which can be used as a PWM called the ecap module, short for enhanced capture. The procedure to use it is very similar to that of the ehrpwm. The AM3358 has three ecap modules but the Bone implements only two of these. These are the mux pins for the two different ecap modules:
For ecap1 on P9-42
root:~# echo 0 > /sys/kernel/debug/omap_mux/ecap0_in_pwm0_out
For ecap2 on P9-28
root:~# echo 4 > /sys/kernel/debug/omap_mux/mcasp0_ahclkr
And then, almost the same set of commands as for ehrpwm (With the addition of one extra command)
root:~# cd /sys/class/pwm/ecap.i
root:/sys/class/pwm/ecap.i# echo 1 > request
root:/sys/class/pwm/ecap.i# echo 0 > duty_percent
root:/sys/class/pwm/ecap.i# echo 1 > period_freq
// Sets the duty cycle in percent
root:/sys/class/pwm/ecap.i# echo 50 > duty_percent
// Sets the duty cycle in nano seconds. This is for 1ms on time Use either
root:/sys/class/pwm/ecap.i# echo 1000000 > duty_ns
root:/sys/class/pwm/ecap.i# echo 1 > run
Where i is either 0 or 2 (Those are the ones that Beaglebone implements).
So to summarize what the Beaglebone can do in terms of PWM: There are 3 independent ehrpwm modules, each of which has two outputs. The outputs of one module must have the same frequency but can have different duty cycles. This gives you 6 output pins. There are two ecap modules which can be used for PWM. These modules are independent. That gives you a total of 8 PWM pins to play with…
Enjoy! Just don’t connect your loads directly! LEDs may be okay with a resistor in series but if you’re not sure, follow a tutorial or use a transistor switch to protect the board.
So that’s it for today. As always, if you need some help with this, feel free to post in the comments.