# Control PWM duration with python

I need to control the PWM module on the raspberry pi. I’m now familiar with pigpio, and with hardware_PWM. However, I did not find anywhere where I can control the total duration of the PWM. Example: turn off after 50 clock cycles. Also, what would be the most accurate way in doing so using python?

My pulses can vary in duty cycle, and are between 0-1khz. I tried sing the software pwm but it couldn’t get to 1khz, but when I tried using the hardware_pwm it was honestly perfect. But I can’t control it.

If the pulses aren't very fast and you don't mind jitter you could do it in software. Untested Python.

``````def send_PWM(GPIO, pulses, frequency, dutycycle):

# dutycycle expected to be in range 0.0 to 1.0

duration = 1.0 / frequency
on_period = duration * dutycycle
off_period = duration - on_period

for i in range(pulses):
pi.write(GPIO, 1)
time.sleep(on_period)
pi.write(GPIO, 0)
time.sleep(off_period)
``````

If the pulses are fast (say the 100 kHz or less region) and you don't like jitter you could use a wave chain.

There are various examples of using waves at http://abyz.me.uk/rpi/pigpio/examples.html

Here is an example using waves and wave chains.

``````#!/usr/bin/env python

import time
import pigpio

def tx_pulses(pi, GPIO, frequency, num, dutycycle=0.5):
assert 1 <= frequency <= 500000
assert 1 <= num <= 65535
assert 0.0 <= dutycycle <= 1.0

duration = int(1000000/frequency)

on_micros = int(duration * dutycycle)

num_low = num % 256
num_high = num // 256

wf = []

#                           on      off    time
wf.append(pigpio.pulse(1<<GPIO,       0, on_micros))
wf.append(pigpio.pulse(      0, 1<<GPIO, duration - on_micros))

wid = pi.wave_create()

if wid >= 0:
pi.wave_chain([255, 0, wid, 255, 1, num_low, num_high])
while pi.wave_tx_busy():
time.sleep(0.01)
pi.wave_delete(wid)

pi = pigpio.pi()
if not pi.connected:
exit()

GPIO=19

pi.set_mode(GPIO, pigpio.OUTPUT)

tx_pulses(pi, GPIO, 100, 25) # 25 pulses @ 100 Hz 50% duty

tx_pulses(pi, GPIO, 1000, 250, 0.1) # 250 pulses @ 1000 Hz 10% duty

tx_pulses(pi, GPIO, 5000, 2391, 0.03) # 2391 pulses @ 5000 Hz 3% duty

pi.stop()
``````
• My pulses can vary in duty cycle, and are between 0-1khz. I tried sing the software pwm but it couldn’t get to 1khz, but when I tried using the hardware_pwm it was honestly perfect. But I can’t control it. The wave chain looks neat since I can looo it for an x amount, I’ll need to look more into that. It says it disables the hardwsre_PWM tho Feb 14, 2020 at 13:16
• Yes, waves use PWM and PCM so no audio from them. When I get time I will add a wave chain example to the answer.
– joan
Feb 14, 2020 at 14:22
• Great, thank you Feb 14, 2020 at 14:49
• I tried this out, and this works out really good for my purposes for now. Thank you Feb 15, 2020 at 21:01