I am using pigpio to generate a PWM signal varying in time. I create a wave, which contains one period of a sine wave, in the form of PWM signal. I use wave_send_using_mode and WAVE_MODE_REPEAT_SYNC to get synchronisation. It works perfectly as long as I don't try to change the wave (for example with a new amplitude or period). Then it seems that there's no synchronisation, I get steps at transitions (see screenshot).

This is the PWM generation code:

#import necessary libraries
import pigpio
import numpy as np

#pi - pigpio instancem pin - PWM pin, frequency - sine frequency, lower - lower bound of the PWM in %, upper - upper bound of the PWM in %
def set_PWM(pi, pin, frequency, lower, upper):
    #create variables
    fla = []
    zero = 0

    #how many steps in a period
    bits = 1000
    #carrier frequency * 5
    carrier = 5000*5

    period = (5/frequency)/carrier * 10e6

    pi.set_mode(pin, pigpio.OUTPUT)

    amplitude = (upper - lower) / 100

    #create a profile, sine
    for i in range(bits):
        sine = ((np.sin(2*np.pi * i/bits) + 1) / 2 * amplitude) + lower / 100 
        fla.append(pigpio.pulse(1<<pin, zero, int(sine * period/2)))
        fla.append(pigpio.pulse(zero, 1<<pin, int((1-sine) * period/2)))

    #clear current waveforms

    #add the created pulses to a new waveform

    #create a bew waveform
    fi = pi.wave_create()

    #send the waveform indefinitely
    pi.wave_send_using_mode(fi, pigpio.WAVE_MODE_REPEAT_SYNC)

    #check if force is ok, if not then create a new profile, and use wave_send_using_mode command with wave_mode_repeat_sync parameter
    #this will try to synchronise the previous profile with a new one, to avoid step changes of duty cycle

    #this approach doesn't block the program, something else can be done in the meanwhile

#set solenoid current to 0, pi - pigpio instance
def stop_PWM(pi):

and the code for changing PWM every 3 seconds:

#import necessary libraries
import pigpio
from time import sleep
import time
import numpy as np
import PWM
import RPi.GPIO as GPIO

#specify PWM pin
pin = 12


frequency = 1

lower = 20
upper = 80

PI_HOST = ''
pi = pigpio.pi(PI_HOST)


while 1:
    PWM.set_PWM(pi, pin, frequency, lower, upper)
    PWM.set_PWM(pi, pin, frequency, 40, 60)
    PWM.set_PWM(pi, pin, frequency*2, lower, upper)
    PWM.set_PWM(pi, pin, frequency*2, 50, 50)

when I look up the generated output, using a device which translates PWM to a proper analog signal, I get this:enter image description here

and sending only one wave (but repeating set_PWM function every 3 seconds): enter image description here

If I just do set_PWM once, the generated waveform is a perfect sine with no transition problems.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.