1

I want create phase delay (as below figure) between each pulse generated from pigpio library, I using usleep to delay before generate pulse as in code, but all pusle generted is not phase difference (as the second figure). Please show me the way to done as the first figure.thanks

import sys, struct
from socket import*
import numpy
import numpy as np
import pickle
import time, pigpio
delay_array1=[10,20,18,15]
##create 40khz pulse      
usleep = lambda x: time.sleep(x/1000000.0)
FREQ=40000
PWM1=2
PWM2=3
PWM3=4
PWM4=21
GPIO=[PWM1,PWM2,PWM3,PWM4]
_channels = len(GPIO)#_channels=26
print(_channels)

_dc=[0]*_channels #_dc=[0,..,0]; 26 phan tu 0
print (_dc)

_micros=1000000/FREQ

old_wid = None

def set_dc(channel, dc):

  global old_wid

  if dc < 0:
     dc = 0
  elif dc > _micros:
     dc = _micros

  _dc[channel] = dc

  for c in range(_channels):#c run 0..25
     d = _dc[c]
     g = GPIO[c]
     if d == 0:
        pi.wave_add_generic([pigpio.pulse(0, 1<<g, _micros)])
     elif d == _micros:
        pi.wave_add_generic([pigpio.pulse(1<<g, 0, _micros)])
     else:

        pi.wave_add_generic(
           [pigpio.pulse(0, 1<<g, d), pigpio.pulse(1<<g, 0, _micros-d)])

  new_wid = pi.wave_create()
  print('id:',new_wid)
  if old_wid is not None:
     pi.wave_send_using_mode(new_wid, pigpio.WAVE_MODE_REPEAT_SYNC)

     #Spin until the new wave has started.
     while pi.wave_tx_at() != new_wid: # returns the id of the waveform currently being transmitted
         pass
     #It is then safe to delete the old wave
     pi.wave_delete(old_wid)

  else:
#transmits the waveform with id wave_id, repeats until wave_tx_stop is called
#or another call to wave_send_* is made
     pi.wave_send_repeat(new_wid)
  old_wid = new_wid

pi = pigpio.pi()
if not pi.connected:
  exit(0)
## calls a user supplied function (a callback) whenever the specified GPIO edge is detected
#def cbf(gpio, level, tick):
#    print (gpio, level, tick)
#cb1 = pi.callback(13, pigpio.EITHER_EDGE, cbf)
#data1= cb1.tally()
#print (data2)
# set wave GPIO to output mode
for g in GPIO:
  pi.set_mode(g, pigpio.OUTPUT)
usleep(delay_array1[0])
set_dc(0,_micros/2)
usleep(delay_array1[1])
set_dc(1,_micros/2)
usleep(delay_array1[2])       
set_dc(2,_micros/2)
usleep(delay_array1[3])
set_dc(3,_micros/2)

time.sleep(60)
pulses=pi.wave_get_pulses()
print(pulses)
pi.wave_tx_stop()

if old_wid is not None:
  pi.wave_delete(old_wid)
pi.wave_clear()
cb1.reset_tally()
cb1.cancel()
pi.stop()

enter image description here enter image description here

1 Answer 1

1

Here is a code snippet from a Python class to generate PWM with waves.

  • self.used[g] is True if GPIO g is providing PWM.

  • self.pS[g] is where the pulse starts within the cycle as a percentage (0=start, 50=middle, 100=end).

  • self.pL[g] is the length of the pulse as a percentage of the cycle (0=off, 50=half cycle length, 1=fully on).

  • self.micros is the length of each wave (25µs for 40kHz).

I will be publishing the code as a complete class within a day or so. It will probably replace the current wave_PWM example at pigpio examples.

def update(self):

   null_wave = True

   for g in range(self.GPIO):

      if self.used[g]:

         null_wave = False

         on = int(round(self.pS[g] / 100.0 * self.micros))
         length = int(round(self.pL[g] / 100.0 * self.micros))

         if length == 0:
            self.pi.wave_add_generic([pigpio.pulse(0, 1<<g, self.micros)])
         elif length == self.micros:
            self.pi.wave_add_generic([pigpio.pulse(1<<g, 0, self.micros)])
         else:
            _off = (on + length) % self.micros
            if on < _off:
               self.pi.wave_add_generic([
                  pigpio.pulse(   0,    0,                on),
                  pigpio.pulse(1<<g,    0,         _off - on),
                  pigpio.pulse(   0, 1<<g, self.micros - _off),
                  ])
            else:
               self.pi.wave_add_generic([
                  pigpio.pulse(   0,    0,              _off),
                  pigpio.pulse(   0, 1<<g,        on - _off),
                  pigpio.pulse(1<<g,    0, self.micros - on),
                  ])

   if not null_wave:

      if not self.stop:

         new_wid = self.pi.wave_create()

         if self.old_wid is not None:

            self.pi.wave_send_using_mode(
               new_wid, pigpio.WAVE_MODE_REPEAT_SYNC)

            # Spin until the new wave has started.

            while self.pi.wave_tx_at() != new_wid:
               pass

            # It is then safe to delete the old wave.
            self.pi.wave_delete(self.old_wid)

            print(self.old_wid)

         else:

            self.pi.wave_send_repeat(new_wid)

         self.old_wid = new_wid
6
  • thanks @joan very much. I want question is that update(self) function which similar as set_dc(GPIO,dc) function , it only difference is added pigpio.pulse(0,0,on) that can create delay time before pulse generated, are you right? But when we use "self.pi.wave_send_repeat(new_wid)" is that whether pigpio.pulse(0,0,on) have repeatly too? it only created a only time, after that is generate pulse 40khz continuously?
    – Gab
    Commented Oct 4, 2016 at 16:10
  • @Gab I still am not clear as to what you want to do. I have put the new example code at abyz.co.uk/rpi/pigpio/examples.html#Python_wavePWM_py
    – joan
    Commented Oct 6, 2016 at 19:23
  • I only want to pulse generated that only delay initial then still is pulse 40khz as figure in link: imgur.com/a/zFTin
    – Gab
    Commented Oct 7, 2016 at 2:20
  • it like as create offset for a pulse
    – Gab
    Commented Oct 7, 2016 at 6:56
  • That's what the new class does. Each GPIO may have a different offset from the start of the cycle.
    – joan
    Commented Oct 7, 2016 at 7:17

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.