Unfortunately they seemed to have changed the PWM driver in the newer linux kernels. I’ve been trying to find some good documentation on it myself, but nothing so far. I was able to play around with it a bit by digging through the current Bonescript source for analogWrite to see what it does and was able to PWM an LED via an NPN transistor.
I found the same link and I also find it all a bit overwhelming. I've switched to Debian Squeeze with a 3.2 kernel following the instructions here: http://eewiki.net/display/linuxonarm/BeagleBone. So far I see nothing on HDMI and I'm not seeing any serial connection detecting on my host linux system. Does anyone know if these instructions are valid for the BBB? Will a 3.2 kernel work
Unfortunately I’m in the process of replacing my BBB so I don’t have one for probably another week, but I’m very interested in using the PWM as well (disclaimer: I want to try and make a quadcopter out of it). As soon as I get my bone back I’ll be putting a lot of effort into understanding how the device tree works and such. I’d be happy with work with you on putting together a rock solid beginner tutorial on a wiki or block somewhere. I know that doesn’t help you much now, but hang in there :).
I dug around in some of the other posts and it looks like in general, the entire device tree stuff is in a state of flux. Sounds like there either hasn’t been a solid proposal going forward, or at least there hasn’t been enough agreement quite yet. So it might very well be that there’s not a whole lot of concrete docs yet because it hasn’t been finalized. That said, this IS an open source project so we can easily just start dissecting the device drivers and figuring this stuff out ourselves.
I also want to figure out how these cool PRUs are supposed to work. Flying a quadcopter can be dangerous in a non-realtime OS but the Bone has lots of extras that should make it possible. We just have to unlock all their secrets :).
That is a great idea - count me in. I’ve done lots of arduino / AVR stuff, but this is my first linux / ARM system. I would be delighted to help with the tutorials. My interest is in developing laboratory instrumentation with these things - like pH meters, spectroscopes, impedance analyzers, data loggers etc. So would like to help with your tutorials.
I also teach a college-level instrumentation class, so I might be a user for your tutorials as well.
K
If the goal is a tutorial, the SYSFS interface does provide the simplest way to ease someone into using PWM. I think that being able to simply access it from the command-line does make it very approachable from a beginner point of view. I agree that there is definitely more efficient means for working with the PWM, but realistically if you need that low level of interaction, you’ll likely being using the /dev/mem device to direct access to the registers (or using a polished C library that does it for you).
Also, as I understand it, the SYSFS interface is the only way to mux the pins you’d need from userspace.
I got PWM working on my BBB from the command line the other day. Here’s what I did on Angstrom (4/13 image).
Add the am33xx_pwm module to the bone_capemgr. You’ll have to look at your BBB for the # of the cape manager. Mine is bone_capemgr.8, but since I’ve only tested on a single board, I’m not sure if the numbers are the same across every board.
$ echo am33xx_pwm > /sys/devices/bone_capemgr.#/slots
Add the individual PWM module to the bone_capemgr. For example, EHRPWM2B is pin 13 on the P8 connector. To enable this pin for PWM, use the following command
$ echo bone_pwm_P8_13 > /sys/devices/bone_capemgr.#/slots
This creates a link in /sys/devices/ocp.#/pwm_test_P8_13.#. For my BBB, I have /sys/devices/ocp.2/pwm_test_P8_13.12. The number in the pwm_test has changed for me for a couple times that I’ve used it, so you’ll have to see what number it assigns for you.
All the settings for the PWM configuration are found in that folder similar to the old interface. To generate a 50 Hz signal with 50% duty cycle, (the period and duty times are giving in nanoseconds)
$ echo 20000000 > /sys/devices/ocp.#/pwm_test_P8_13.#/period
$ echo 10000000 > /sys/devices/ocp.#/pwm_test_P8_13.#/duty
I found all this from digging through the BoneScript source code found here https://github.com/jadonk/bonescript. bonescript/node_modules/bonescript/index.js has the core implementation of the module.
The instructions were great in general and was able to get them to work
almost letter for letter. The only hiccup I had was that I had to append
"--no-check-certificate" on all the wget commands, it was complaining about
the certificates being self signed.
Weird, better fire up a new vm and try it without first git cloning
one of the github tree's, as that probably okay'ed the certificate on
my system... Thanks!
The problem I had was just with enabling the PWMs. Following Michael's
instructions I got a "/sys/devices/ocp.2/pwm_test_P8_13.12" folder but there
was were no "duty" or "period" files in the folder. It's possible I made a
typo since I didn't do too much troubleshooting before I rebooted into
Angstrom when I didn't see the links I needed to control the PWM.
Derek, could you elaborate on what you mean by the Ubuntu image not having EHRPWM_TEST set? I’m experiencing the same problem of the missing duty and period files in the Ubuntu image and am trying to figure out where to make these changes (and then how to recompile and and reinstall the kernel).
I’ve succeeded in setting this EHRPWM_TEST flag. Do the following: download demo image for beaglebone black by following instructions from: http://elinux.org/BeagleBoardUbuntu#Demo_Image
After that, run script ./build_kernel.sh. After the building is done, in folder KERNEL, edit the file defconfig - find the flag CONFIG_EHRPWM_TEST, uncomment it and set to:
CONFIG_EHRPWM_TEST=m.
Now just rebuild the kernel with ./tools/rebuild_kernel.sh.
Finally insert your mmc car with previously installed ubuntu, set mmc variable in file system.sh (uncomment and set for example MMC=/dev/mmcblko) and run the script ./tools/rebuild_kernel.sh. The kernel will be updated and now you can follow instructions from: http://elinux.org/EBC_Exercise_13_Pulse_Width_Modulation or you can write:
$ echo 20000000 > /sys/devices/ocp./pwm_test_P8_13./period
$ echo 10000000 > /sys/devices/ocp./pwm_test_P8_13./duty
Wildcards are the best way to do this.
I completely agree with your comments on there needing to be a C/C++ equivalent to the bonescript. With beaglebone 3.8.13, I am able to successfully control a PWM actuator following Mark Yoder’s example: (http://elinux.org/EBC_Exercise_13_Pulse_Width_Modulation), almost exactly the procedure Michael Vernier posted above. However, it will only work after I run a bonescript analogWrite() on the PWM pin. It took some digging to reverse engineer the \bonescript-master\node_modules\bonescript\index.js::analogWrite() to determine what it is doing that afterwards allows me to successfully use the PWM device.
The analogWrite sets the PWM polarity to zero during the configuration of the PWM: “fs.writeFileSync(pwm_test+’/polarity’, 0);”
A similar operation from my C++ side resolved my issue and allowed me to use the PWM device successfully: system(“cd /sys/devices/ocp.2/pwm_test_P9_21.14; echo 0 > polarity”);