Hello,
I have an application with several iterations in the field. There is a problem with motion suddenly becoming VERY fast (Pigpio pi.wave_send_once(self.plan)
The motion is calculated using the listed module once at program startup.
This is a rare problem, but has happened several times on several different fixtures.
Re-starting the main python program does not restore the playback speed for the waveform.
Reboot of Raspbian does restore the correct playback speed
It seems to happen after extended runtime of the Pi.
I unfortunately cannot reproduce the problem at will. I only know it takes a reboot to fix the problem
In the module:
Instantiating the class PiMoto and then calling instance.Start() is the correct procedure for startup of the motion part of this module.
Calling MakeProfile will create the waveform from the parameters coded into this line:
for each in self.Planner(50,20000,25000,1745):#Vstart,Vmax,Accel,Dist
and calling instance.Clamp() or instance.Unclamp() will play the motion
Any ideas of how to fix or avoid this problem?
I have an application with several iterations in the field. There is a problem with motion suddenly becoming VERY fast (Pigpio pi.wave_send_once(self.plan)
The motion is calculated using the listed module once at program startup.
This is a rare problem, but has happened several times on several different fixtures.
Re-starting the main python program does not restore the playback speed for the waveform.
Reboot of Raspbian does restore the correct playback speed
It seems to happen after extended runtime of the Pi.
I unfortunately cannot reproduce the problem at will. I only know it takes a reboot to fix the problem
In the module:
Instantiating the class PiMoto and then calling instance.Start() is the correct procedure for startup of the motion part of this module.
Calling MakeProfile will create the waveform from the parameters coded into this line:
for each in self.Planner(50,20000,25000,1745):#Vstart,Vmax,Accel,Dist
and calling instance.Clamp() or instance.Unclamp() will play the motion
Any ideas of how to fix or avoid this problem?
Code:
class PiMoto(): def __init__(self): #Input Numbers self.rc = 16 self.ro = 17 self.lc = 6 self.lo = 19 self.lid = 20 #output numbers self.d1dir = 4 self.d2dir = 18 self.d1pul = 12 self.d2pul = 13 self.enstp = 27 self.Homed = False self.Active = False def Start(self): self.pi = pigpio.pi() if not self.pi.connected: exit(0) self.pi.wave_clear() self.MakeProfile() self.pi.set_mode(self.d1pul,pigpio.OUTPUT) self.pi.set_mode(self.d2pul,pigpio.OUTPUT) self.pi.set_mode(self.enstp,pigpio.OUTPUT) self.pi.set_mode(self.d1dir,pigpio.OUTPUT) self.pi.set_mode(self.d2dir,pigpio.OUTPUT) self.Active = True def Stop(self): if self.Active: self.pi.stop() def Home(self): self.pi.write(self.d1dir,1) self.pi.write(self.d2dir,0) self.Homed = False while self.Homed == False: if self.pi.read(self.lo) == 1: self.pi.gpio_trigger(self.d2pul, 5, 1) if self.pi.read(self.ro) == 1: self.pi.gpio_trigger(self.d1pul, 5, 1) sleep(.005) if self.pi.read(self.lo) == 0 and self.pi.read(self.ro) == 0: self.Homed = True def Clamp(self): if self.Homed: if self.pi.read(self.ro) == 0 and self.pi.read(self.lo) == 0: self.pi.write(self.d1dir,0) self.pi.write(self.d2dir,1) self.pi.wave_send_once(self.plan) print("Clamping") while self.pi.wave_tx_busy(): sleep(.02) print("Clamped") else: print("Fixture cannot clamp") def Unclamp(self): if self.Homed: if self.pi.read(self.rc) == 0 and self.pi.read(self.lc) == 0: self.pi.write(self.d1dir,1) self.pi.write(self.d2dir,0) self.pi.wave_send_once(self.plan) print("Unclamping") while self.pi.wave_tx_busy(): sleep(.02) print("Unclamped") else: print("Fixture cannot unclamp") def MakeProfile(self): #Build the waveform for moving the stepper motors open_close = [] #Fixture.Home() bitmask = 1<<self.d1pul | 1<<self.d2pul #create bitmask so that playing the waveform runs both motors #create the waveform for the entire motion for each in self.Planner(50,20000,25000,1745):#Vstart,Vmax,Accel,Dist ms = int(each[1]*500000) open_close.append(pigpio.pulse(bitmask,0,ms)) open_close.append(pigpio.pulse(0,bitmask,ms)) self.pi.wave_add_generic(open_close) self.plan = self.pi.wave_create()#This is the motion with ramp for travel def Planner(self,Vstart,Vmax,A,D): Vstart = float(Vstart) Vmax = float(Vmax) AccelTime = (Vmax - Vstart) / A#Get time for full acceleration AccelDist = (Vstart * AccelTime) + (.5 * A * (AccelTime ** 2)) #Determine if we will reach max speed if D/2 > AccelDist: full_profile = True full_speed_steps = int(D - (AccelDist * 2)) else: full_profile = False AccelDist = D / 2 #Initialize first step speed_time = [[Vstart, 1/Vstart]] #Speed in pulses per sec, time between pulses. #Special case of 1 step if D == 1: return speed_time #Build the profile, accel first for idx in range(int(AccelDist -1)):#already made the first step old_speed_time = speed_time[-1] new_speed = old_speed_time[0] + (A * old_speed_time[1]) speed_time.append([new_speed, 1 / new_speed]) #Add steady speed if appropriate if full_profile: for idx in range(int(full_speed_steps)+1): speed_time.append([Vmax,1/Vmax]) #reverse copy accel to make decel for idx in range(int(AccelDist-1),0,-1): speed_time.append(speed_time[idx]) #Return to first step data speed_time.append([Vstart, 1/Vstart]) #add steps to compensate odd number of steps when Vmax not reached for idx in range(len(speed_time) , D): speed_time.append([Vstart, 1/Vstart]) return speed_timeStatistics: Posted by rallenbaggett — Mon Jun 09, 2025 4:50 pm