Note: the only BeagleBone tag I could find was for the Black, this is a Green Wifi, but I have no reason to believe the Green and Black behave differently in this matter. Alternate tagging recommendations welcome.
For an embedded application, I'm using a BeagleBone Green Wireless and the Adafruit python3 libraries, I'm trying to generate some PWM (Pulse Width Modulation) for audio beep alerts to the machine operator, and finding that it's taking ~240 milliseconds to setup for a PWM command, and this is just feels like a crazy long amount of time.
Minimal python code that connects the PWM pin to a speaker (via a transistor):
import time
import Adafruit_BBIO.PWM as PWM
pwmPin = "P8_46"
PWM.start(pwmPin, duty_cycle = 50, frequency = 1000)
time.sleep(0.080)
PWM.stop(pwmPin)
This makes a 1000 Hz beep for 80 msec as expected, but only after a ~240 msec delay while the PWM gets setup.
To fully instrument this, I used another GPIO pin and hooked up both pins to a scope, toggling the I/O pin to help me synchronize the code with what I'm seeing.
Upper trace is the PWM output, which is correct, and the bottom trace shows various sync pulses from the code to let me know what I'm seeing. The long 242 msec pulse (which is active only during the PWM setup statement).
This is the actual code that generated the traces:
import time
import Adafruit_BBIO.GPIO as GPIOn
import Adafruit_BBIO.PWM as PWM
bitPin = "P8_10"
pwmPin = "P8_46"
GPIO.setup(bitPin, GPIO.OUT)
currentBit = GPIO.input(bitPin)
def toggleBit():
global bitPin
global currentBit
currentBit = not currentBit
GPIO.output(bitPin, currentBit)
# INITIAL SYNC PULSE -- 92 microseconds
toggleBit()
toggleBit()
# Now generate PWM beep
toggleBit() # rising edge of 242 msec pulse
PWM.start(pwmPin, duty_cycle = 50, frequency = 1000)
toggleBit() # trailing edge of 242 msec pulse
time.sleep(0.080) # beep for 80 msec
toggleBit()
PWM.stop(pwmPin)
toggleBit()
To rule out that python just makes all bit fiddling slow, just before the long 242 msec high pulse is a very short blippy sync pulse: this is the inset in the upper left of the image showing that pulse 92 microseconds. This seems entirely reasonable, so I have no explanation for the crazy slow PWM setup.
I looked at the C code in the Adafruit library, and I got the sense that there was a one-time setup cost when doing PWM, but this ~240msec thing shows up repeatedly. Changing the PWM pin didn't make any difference, nor did running as root (my non-root user is a member of the proper pwm
and gpio
groups). I ran the proper config-pin
commands prior to doing all this stuff.
I'm super comfortable with Linux/C, pretty comfy w/ BeagleBone, but python is fairly new to me.
I'm stumped.
Components involved (all are the latest as far as I know):
- BeagleBone Green Wireless
- Debian Buster IoT Image 2020-04-06
- Kernel version 4.19.94-ti-r42
- Python 3.7.3
- Adafruit-BBIO 1.2.0