Skip to main content

3.1.3 Use PWM

The Hobot.GPIO library only supports PWM on pins with additional hardware PWM controllers. Unlike the RPi.GPIO library, the Hobot.GPIO library does not implement software simulated PWM.

The RDK X3 RDK Ultra both support 2 PWM channels.

RDK X5 supports four PWM groups, with two output channels per group, providing a total of eight PWM outputs, as shown in the table below:

PMW GroupPWM Channel40PIN Pin
PWM0LSIO_PWM_OUT029
PWM0LSIO_PWM_OUT131
PWM1LSIO_PWM_OUT237
PWM1LSIO_PWM_OUT324
PWM2LSIO_PWM_OUT428
PWM2LSIO_PWM_OUT527
PWM3LSIO_PWM_OUT632
PWM3LSIO_PWM_OUT733

By default, PWM3 is enabled on the RDK X5. Additional PWM groups can be enabled via the srpi-config system configuration tool, which will remap the corresponding pins for PWM output. The configuration takes effect after reboot.

Select 3 Interface OptionsI3 Peripheral Bus Config, then choose the corresponding PWM group and set it to okay.

Refer to /app/40pin_samples/simple_pwm.py for detailed information on how to use PWM channels.

Test Code

Open the PWM channel specified by output_pin, with an initial duty cycle of 25%. Increase the duty cycle by 5% every 0.25 seconds until 100% is reached, and then decrease the duty cycle by 5% every 0.25 seconds. When the normal output waveform is present, you can measure the output signal and observe the waveform using an oscilloscope or logic analyzer.

#!/usr/bin/env python3

import Hobot.GPIO as GPIO
import time

# PWM-supporting pins: 32 and 33
output_pin = 33

def main():
# Pin Setup:
# Board pin-numbering scheme
GPIO.setmode(GPIO.BOARD)
# Supported frequency range for RDK X3: 48KHz ~ 192MHz
# Supported frequency range for RDK Ultra: 1Hz ~ 12MHz
# Supported frequency range for RDK X5: 1Hz ~ 12MHz
p = GPIO.PWM(output_pin, 48000)
# Initial duty cycle of 25%. Increase by 5% every 0.25 seconds until 100% is reached, then decrease by 5% every 0.25 seconds
val = 25
incr = 5
p.start(val)

print("PWM running. Press CTRL+C to exit.")
try:
while True:
time.sleep(0.25)
if val >= 100:
incr = -incr
if val <= 0:
incr = -incr
val += incr
p.ChangeDutyCycle(val)
finally:
p.stop()
GPIO.cleanup()

if __name__ == '__main__':
main()