Use PWM0 on GPIO12

Folks,

On my journey to pull apart the BeagleY-AI features, I’ve embarked on building a multi-stage lead-acid battery charger.

With @RobertCNelson’s kind help, I was able to come to the bottom of an I2C problem and get I2C0 running, which is great.

This time, I’m trying to generate a variable duty cycle PWM signal out of PWM0 at GPIO12, having loaded the appropriate overlay (/overlays/k3-am67a-beagley-ai-pwm-ecap0-gpio12.dtbo) and rebooted.

Now; my issue is two fold:

  1. The RPi module: knocked together the following test code:
#!/usr/bin/env python
import RPi.GPIO as GPIO
from time import sleep

ledpin = 12				# PWM pin connected to LED
GPIO.setwarnings(False)			#disable warnings
GPIO.setmode(GPIO.BOARD)		#set pin numbering system
GPIO.setup(ledpin,GPIO.OUT)
pi_pwm = GPIO.PWM(ledpin,1000)		#create PWM instance with frequency
pi_pwm.start(0)				#start PWM of required Duty Cycle
while True:
    for duty in range(0,101,1):
        pi_pwm.ChangeDutyCycle(duty) #provide duty cycle in the range 0-100
        sleep(0.01)
    sleep(0.5)

    for duty in range(100,-1,-1):
        pi_pwm.ChangeDutyCycle(duty)
        sleep(0.01)
    sleep(0.5)

Running it returns:

ahmed@beagley:~$ ./testpwm.py
Traceback (most recent call last):
  File "/home/ahmed/./testpwm.py", line 2, in <module>
    import RPi.GPIO as GPIO
  File "/usr/lib/python3/dist-packages/RPi/GPIO/__init__.py", line 23, in <module>
    from RPi._GPIO import *
RuntimeError: This module can only be run on a Raspberry Pi!

Which I guess is to be expected, but what’s the way round this, to get some PWM out of GPIO12 ?

  1. What other possibilities are there to generate PWM output in C code? what are the relevant device files and config structures to use?

Thanks in advance,

Ahmed.

So here’s the working theory…

voodoo@BeagleBone:~$ sudo beagle-version | grep UBOOT
UBOOT: Booted Device-Tree:[k3-am67a-beagley-ai.dts]
UBOOT: Loaded Overlay:[k3-am67a-beagley-ai-pwm-ecap0-gpio12.kernel]

On bootup, we need to export pwm-ecap0-gpio12 so a usable symlink:

voodoo@BeagleBone:~$ sudo beagle-pwm-export --pin hat-32

How does someone know to run --pin hat-32 i need to modify it just figure out which overlay was loaded…

This creates this directory:

voodoo@BeagleBone:~$ tree /dev/hat/pwm/
/dev/hat/pwm/
└── GPIO12 -> /sys/devices/platform/bus@f0000/23100000.pwm/pwm/pwmchip0/pwm0/

2 directories, 0 files

Inside GPIO12 we get:

voodoo@BeagleBone:~$ tree /dev/hat/pwm/GPIO12
/dev/hat/pwm/GPIO12
├── capture
├── duty_cycle
├── enable
├── period
├── polarity
├── power
│   ├── async
│   ├── autosuspend_delay_ms
│   ├── control
│   ├── runtime_active_kids
│   ├── runtime_active_time
│   ├── runtime_enabled
│   ├── runtime_status
│   ├── runtime_suspended_time
│   └── runtime_usage
└── uevent

2 directories, 15 files

So:

ledpin = 12				# PWM pin connected to LED
GPIO.setwarnings(False)			#disable warnings
GPIO.setmode(GPIO.BOARD)		#set pin numbering system
GPIO.setup(ledpin,GPIO.OUT)

Becomes: sudo beagle-pwm-export --pin hat-32

pi_pwm = GPIO.PWM(ledpin,1000)		#create PWM instance with frequency
echo 1000 > /dev/hat/pwm/GPIO12/period
pi_pwm.start(0)				#start PWM of required Duty Cycle
echo 1 > /dev/hat/pwm/GPIO12/enable

Then finally:

echo 500 > /dev/hat/pwm/GPIO12/duty_cycle

Regards,

Much obliged - extensive and authoritative as usual.

I’ve tested it with some C, and it works a treat. Next task: feed this into the Node.Red interface I’m using to control the charging process, and voila: that’s my PWM controller done :slight_smile:

Thanks again,

Ahmed.

Okay, i have the rpi number working:

sudo beagle-pwm-export --pin gpio14

This needs a few changes, so it’ll be apt update/upgrade away… in a few days…

Regards,

1 Like