Explanation of the PWM Modules on the Beaglebone

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
or
// 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
or
// 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.

Advertisements

About ajaykumarkannan

I am a final year student pursuing my Bachelor's degree in Electronics and Communications Engineering at IIT Guwahati. I am currently on semester break. View all posts by ajaykumarkannan

20 responses to “Explanation of the PWM Modules on the Beaglebone

  • Eric

    “For example, in my ESC, by varying the frequency from 50Hz – 60Hz, you can vary the speed of the motors.” Are you saying that the frequency, as well as the pulse width should vary to control the speed of the motors? I just a built a servo controller using a 555 timer for my esc. It is fixed to provide a 1 – 2ms pulse at 50Hz only. I am now wondering if I need to be able to adjust the frequency as well?

    • ajaykumarkannan

      No. In my case, the ESC control is based purely on the frequency and not on the duty cycle at all. So you can set the duty cycle at a fixed rate and vary the frequency. I think servo control should be in a similar way. I can check with a friend who has worked on it and let you know by tomorrow if you want.

      • ajaykumarkannan

        Sorry, I had made a mistake here. You don’t need to adjust the frequency. You vary the duty cycle.
        You can vary that using the duty_cycle and set the percent or set the duty_ns value which is the value of the on time in nano seconds. I find the second to be easier because as you said, the motor speeds are set by the duty cycle being from 1ms-2ms.
        I’ll update the blog entry to fix the mistakes.

  • GP

    This is a really great article, one of the best I’ve discovered so far with the BeagleBone.

    Thanks for taking the time to research and post this!

  • Carter

    What OS do you have on the beaglebone for this?

    • ajaykumarkannan

      I had this running on the latest Angstrom OS at the time. Apparently, Ubuntu may require a recompilation of the kernel. This was 5-6 months back when I was checking this out. It may have changed by now.

  • Jason

    Just a note for those that might stumble upon this article. When controlling servos (and ESC), be careful now to confuse the “PWM” used to control them with the typical association of using PWM in a microcontroller sense.

    To be specific, as stated in this article, you want to generate a pulse every 50-60 Hz, and that pulse should stay HIGH between 1ms (min range/speed) – 2ms (full range/speed).

    These details are important because if you were to try and use a “standard” PWM output with a duty cycle from 0-100%, you would end up with a pulse that stays high much longer than 2ms, which could damage a servo that doesn’t have safe-guards in place.

  • Maxx

    The new BBB don’t have a “omap_mux” directory in /sys/kernel/debug/. Nor can I create one there. Any advice as to what direction to take? Thanks.

    • ajaykumarkannan

      I don’t have access to a BBB anymore. Could you post the output of ls of /sys/kernel/debug ?
      What have they changed it to?

  • Julio

    I’m trying to use the ehrpwm.2:0 and ehrpwm.2.1 that are assigned to P8.19 and P8.13 respectively Pines, I have sent to Mode 4 without problems.
    The problem is that when I go to / sys / class / pwm only there ehrpwm.0:0 ehrpwm.1:0 ehrpwm.1:1 ehrpwm.0:1 NOT EXIST ehrpwm.2:X, then there is no such set duty_percent, run, stop, etc.

    Can you help me please????

    What I have to do???

    • ajaykumarkannan

      Which version of the Beaglebone do you have and which OS are you currently running on it? Could you post the list of files in /sys/class/pwm ?

      • Julio

        Hello.

        My beaglebone is a normal (white) beagle, the OS, is a Kernel of ubuntu ver. 3.2.5+, in the directory /sys/class/pwm there are: ecap.0; ecap.1; ehrpwm.0:0; ehrpwm.0:1, ehrpwm.1:0, ehrpwm.1:1

        thanks

      • ajaykumarkannan

        I’m not sure that Ubuntu has the support for all three PWM modules. I haven’t touched a Beaglebone in a while but the last time I used it, Ubuntu was lacking a lot of drivers. Could you try the latest update to the Beaglebone version of Ubuntu. And if that fails, could you try on Angstrom?

        Also, what is the version number of the Beaglebone? As in, I was using a Beaglebone Rev A5.

  • Shantanu Bhadoria

    Hi There,
    I have been trying to switch over control of my quad from R Pi attached to a dedicated PWM generator(PCA9685) to my Beaglebone black with onboard PWM pins,

    What makes me nervous to use onboard PWM generators on Beaglebone black is the description on AM335X wiki page http://processors.wiki.ti.com/index.php/AM335x_PWM_Driver%27s_Guide

    It looks like all the three PWM modules on this class of processors have different specifications on PWM signals generated!! Before I go further I must admit my lack of understanding of how PWM signal type may affect motor operation:

    Two PWM outputs (EPWMA and EPWMB) that can be used in the following configurations

    * Two independent PWM outputs with single-edge operation
    * Two independent PWM outputs with dual-edge symmetric operation
    * One independent PWM output with dual-edge asymmetric operation

    I read somewhere that there are qualitative differences in single edge and dual-edge PWM w.r.t DC motor control.

    So I am curious to know which outputs do you connect your ESCs to? Have you experienced any qualitative difference between the two types of signals?
    Maybe I am overthinking this but I would like to know your experience with your exact setup.
    Cheers,
    -Shantanu Bhadoria

    • ajaykumarkannan

      Hey Shantanu. To be honest, I hadn’t given this much thought when I worked on this. I just stuck with the default which was sufficient enough. I assume that would be the the first case (Two independent PWM outputs with single edge operation). Theoretically, this should suffice for most motor control. I have not tried the two types but it should make much of a difference for motor control beyond the fact that the operating frequency might drop by half for dual edge operation. The difference is like the difference between a sawtooth signal and a triangle signal (Applying a comparator on that of course). I suggest you go ahead with the single-edge operation.

      There are two EHRPWM modules, each with two outputs. Each of those two outputs within the same module must have the same frequency but can have different duty cycles. The same applies for eCap which too has two outputs. In my case, I was using servo motor control (That’s what the ESCs accept). These are not like DC motor control. In servo motor control, the duty cycle of the PWM is used to set the speed of rotation. This is done electronically by the ESC, very much unlike DC motors in theory, though the result is similar. For DC motors, the longer you apply the voltage (ON Time), the faster it is going to go. So again, here too, you can keep a steady frequency and just vary the duty cycle to increase or decrease the speed.

  • Mike

    Since there are 8 PWM pins, could I use 4 to read the PWM from my radio controller and another 4 to send the signals to the ESC. I am looking at auto stabilization (from a 6DOF IMU).

    • ajaykumarkannan

      I’m not too sure whether you can read PWM in that way. These pins that we are talking about has a Pulse generator which are used as outputs. However, what you’re looking for is an input pins. I think you’d be better of using the GPIOs on the Beaglebone.

  • karim

    hello , i am trying to dim a led using Beaglebone pwm pin 8_13 but i can’t get high voltage to dim blue led , i have tried with red led and it works(the pin dim the red one ), how to get high voltage values and i don’t think the problem is in the values of period and duty .

    • ajaykumarkannan

      Hi Karim, sorry about the delay.
      What do you mean by “get high voltage values”? Could you elaborate on your problem please? Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: