Beaglebone Black use PWM Pins in Python

I am trying to use the PWM pins from python using the Adafruit-BBIO.PWM library. I have already got the GPIO pins to work using the same method but doing so with the PWM pins gives me the error “RuntimeError: Unknown error”

Some websites suggest that Adafruit-BBIO no longer works, but if it does not then it seems there is no alternative to using the PWM pins in python.

I am using the latest image (BeagleBoard.org Debian Bullseye IoT Image 2023-09-02). I am confused that there is little to no explicit documentation on how to use the board’s basic functions.

Depending on the image, the pwm’s should already exported, they should be under /dev/bone/pwm/

You can use config-pin <pin> pwm to then mux the pin output…

Regards,

Hello @Will_Brunner ,

Seth here. I have had the dealings with specific people that have helped me with PWM on the BBB.

/dev/bone/pwm/ are were the files are located like @RobertCNelson states.

Anyway, if you use pathlib in Python, it is possible.

Seth

P.S. So, something like this:

from pathlib import Path
from time import sleep

pwm1b = Path('/dev/bone/pwm/1/b')
pwm1a = Path('/dev/bone/pwm/1/a')

...

/dev/bone/pwm/1/b/ && /dev/bone/pwm/1/a/ both are files symlinked to another set of files…

ls -l /dev/bone/pwm/* will give you the whereabouts of what is what…

Update

Also…

https://docs.beagleboard.org/latest/books/beaglebone-cookbook/04motors/motors.html#py-servomotor-code

That will help.

Thank you for your help! The python code example made things extremely clear.

I was able to get an output that I could measure with my multimeter. However, the output works if and only if the period is set to 1 second. The example you showed indicates that smaller periods should be allowed, but I get an error:

OSError: [Errno 22] Invalid Argument

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/debian/pwm.py”, line 26 in
f.close()
OSError: [Errno 22] Invalid argument

This occurs for any period that is not 1000000000

I have attached the full code that I ran.

pwm.py (714 Bytes)

1 Like

@Will_Brunner looking the pwm driver configuration: pwm-tiehrpwm.c « pwm « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			     u64 duty_ns, u64 period_ns)
{
	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
	u32 period_cycles, duty_cycles;
	u16 ps_divval, tb_divval;
	unsigned int i, cmp_reg;
	unsigned long long c;

	if (period_ns > NSEC_PER_SEC)
		return -ERANGE;

The developers behind ehrpwm have chosen a max of 1 second…

As long as duty <= period the pwm will operate.

debian@23-am335x-bbb:/dev/bone/pwm/0/a$ ls
capture  duty_cycle  enable  period  polarity  power  uevent
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 1000 > period 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 1 > enable 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 500 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 250 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 150 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 10 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 0 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 500 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 501 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 999 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 1000 > duty_cycle 
debian@23-am335x-bbb:/dev/bone/pwm/0/a$ echo 1001 > duty_cycle 
-bash: echo: write error: Invalid argument

Regards,

Hi Will!

You may want to check out pwm_cap example, that should give you PWM output on 20 BBB pins (and may measure its duty/freq by CAP feature).

Regards