RPi.GPIO only has software PWM - which by its nature is imprecise.
pigpio has hardware timed PWM which is better (and also hardware PWM if you look hard enough).
bcm2835 has hardware PWM and so does WiringPi (but it is deprecated).
My clone of RPi.GPIO (Pi.GPIO) now has hardware PWM in the final stages of testing expected to be released in the next few days.
Pi.GPIO is updated and can be downloaded :-
git clone https://github.com/Milliways2/Pi.GPIO.git
The following code produces the trace below. (The BitScope is a bit slow to capture edges).
#! /usr/bin/env python3 """ """ import sys, os, time import Pi.GPIO as GPIO PWM0=12 PWM1=13 # Pi3 & earlier have 19.2MHz clock # DIVIDER=15 # gives a precise 10kHz signal # RANGE=128 # Pi4 has 54MHz clock # DIVIDER=36 # gives a precise 10kHz signal # RANGE=150 DIVIDER=45 # gives a precise 10kHz signal RANGE=120 def main(): GPIO.setmode(GPIO.BCM) GPIO.pwm_setmode(0) GPIO.pwm_setClock(DIVIDER) GPIO.pwm_setGpio(PWM0) GPIO.pwm_setGpio(PWM1) GPIO.pwm_setmode(GPIO.PWM_MODE_MS) GPIO.pwm_setRange(PWM1, RANGE) GPIO.pwm_Write(PWM1, RANGE//4) # duty cycle of 25% GPIO.pwm_setRange(PWM0, RANGE) GPIO.pwm_Write(PWM0, RANGE//2) # duty cycle of 50% if __name__ == '__main__': main()
