def ProcessStepSate(self): # send data to serial port ---------------------------------------------- # check if we are done with gcode if self.workingProgramCounter >= len(self.gcodeDataLines): self.swState = gc.gSTATE_IDLE self.progExecOutQueue.put(gc.threadEvent(gc.gEV_STEP_END, None)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread reach last PC, swState->gc.gSTATE_IDLE" return # update PC self.progExecOutQueue.put(gc.threadEvent(gc.gEV_PC_UPDATE, self.workingProgramCounter)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) # end IDLE state if self.workingProgramCounter > self.initialProgramCounter: self.swState = gc.gSTATE_IDLE self.progExecOutQueue.put(gc.threadEvent(gc.gEV_STEP_END, None)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread finish STEP cmd, swState->gc.gSTATE_IDLE" return gcode = self.gcodeDataLines[self.workingProgramCounter] # don't sent unnecessary data save the bits for speed for reComments in gReGcodeComments: gcode = reComments.sub("", gcode) self.RunStepSendGcode(gcode)
def SerialRead(self): serialData = "" if not self.progExecSerialRxInQueue.empty(): # get item from queue e = self.progExecSerialRxInQueue.get() if e.event_id == gc.gEV_ABORT: # make sure we stop processing any states... self.swState = gc.gSTATE_ABORT # add data to queue and signal main window to consume self.progExecOutQueue.put(gc.threadEvent(gc.gEV_ABORT, e.data)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) elif e.event_id == gc.gEV_SER_RXDATA: if len(e.data) > 0: # add data to queue and signal main window to consume self.progExecOutQueue.put(gc.threadEvent(gc.gEV_DATA_IN, e.data)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) serialData = e.data # item acknowledge self.progExecSerialRxInQueue.task_done() return serialData
def ProcessRunSate(self): # send data to serial port ---------------------------------------------- # check if we are done with gcode if self.workingProgramCounter >= len(self.gcodeDataLines): self.swState = gc.gSTATE_IDLE self.progExecOutQueue.put(gc.threadEvent(gc.gEV_RUN_END, None)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread reach last PC, swState->gc.gSTATE_IDLE" return # update PC self.progExecOutQueue.put(gc.threadEvent(gc.gEV_PC_UPDATE, self.workingProgramCounter)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) # check for break point hit if (self.workingProgramCounter in self.breakPointSet) and \ (self.workingProgramCounter != self.initialProgramCounter): self.swState = gc.gSTATE_BREAK self.progExecOutQueue.put(gc.threadEvent(gc.gEV_HIT_BRK_PT, None)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread encounter breakpoint PC[%s], swState->gc.gSTATE_BREAK" % \ (self.workingProgramCounter) return # get gcode line gcode = self.gcodeDataLines[self.workingProgramCounter] # check for msg line reMsgSearch = gReGcodeMsg.search(gcode) if (reMsgSearch is not None) and \ (self.workingProgramCounter != self.initialProgramCounter): self.swState = gc.gSTATE_BREAK self.progExecOutQueue.put(gc.threadEvent(gc.gEV_HIT_MSG, reMsgSearch.group(1))) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread encounter MSG line PC[%s], swState->gc.gSTATE_BREAK, MSG[%s]" % \ (self.workingProgramCounter, reMsgSearch.group(1)) return # don't sent unnecessary data save the bits for speed for reComments in gReGcodeComments: gcode = reComments.sub("", gcode) # send g-code command self.RunStepSendGcode(gcode)
def SerialRead(self): serialData = "" if not self.progExecSerialRxInQueue.empty(): # get item from queue e = self.progExecSerialRxInQueue.get() if e.event_id == gc.gEV_ABORT: # make sure we stop processing any states... self.swState = gc.gSTATE_ABORT # add data to queue and signal main window to consume self.progExecOutQueue.put(gc.threadEvent(gc.gEV_ABORT, e.data)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) elif e.event_id == gc.gEV_SER_RXDATA: if len(e.data) > 0: # add data to queue and signal main window to consume self.progExecOutQueue.put( gc.threadEvent(gc.gEV_DATA_IN, e.data)) serialData = e.data self.DecodeStatusData(serialData) return serialData
def RunStepSendGcode(self, gcodeData): gcode = gcodeData.strip() if len(gcode) > 0: gcode = "%s\n" % (gcode) # write data self.SerialWrite(gcode) # wait for response #responseData = self.WaitForResponse() self.WaitForAcknowledge() self.workingProgramCounter += 1 # if we stop early make sure to update PC to main UI if self.swState == gc.gSTATE_IDLE: self.progExecOutQueue.put(gc.threadEvent(gc.gEV_PC_UPDATE, self.workingProgramCounter)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None))
def SerialWrite(self, serialData): exFlag = False exMsg = "" # sent data to UI self.progExecOutQueue.put(gc.threadEvent(gc.gEV_DATA_OUT, serialData)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) try: # send command self.serPort.write(serialData.encode('ascii')) if self.cmdLineOptions.vverbose: print "[%03d] -> ASCII:{%s} HEX:{%s}" % (len(serialData), serialData.strip(), ':'.join(x.encode('hex') for x in serialData)) elif self.cmdLineOptions.verbose: print "[%03d] -> %s" % (len(serialData), serialData.strip()) except serial.SerialException, e: exMsg = "** PySerial exception: %s\n" % e.message exFlag = True
def run(self): """Run Worker Thread.""" # This is the code executing in the new thread. self.endThread = False if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread start." # inti serial RX thread self.serialRxThread = gsatSerialPortThread(self, self.serPort, self.progExecSerialRxOutQueue, self.progExecSerialRxInQueue, self.cmdLineOptions) # init communication with device (helps to force tinyG into txt mode if self.deviceID == gc.gDEV_TINYG2 or self.deviceID == gc.gDEV_TINYG: self.SerialWrite(gc.gTINYG_CMD_GET_STATUS) elif self.deviceID == gc.gDEV_GRBL: self.SerialWrite(gc.gGRBL_CMD_GET_STATUS) self.SerialWrite(gc.gGRBL_CMD_GET_STATUS) while(self.endThread != True): # process input queue for new commands or actions self.ProcessQueue() # process write queue from UI cmds self.ProcessSerialWriteQueue() # check if we need to exit now if self.endThread: break if self.serPort.isOpen(): if self.swState == gc.gSTATE_RUN: self.ProcessRunSate() elif self.swState == gc.gSTATE_STEP: self.ProcessStepSate() elif self.swState == gc.gSTATE_IDLE: self.ProcessIdleSate() elif self.swState == gc.gSTATE_BREAK: self.ProcessIdleSate() elif self.swState == gc.gSTATE_ABORT: # do nothing, wait to be terminated pass else: if self.cmdLineOptions.verbose: print "** gsatProgramExecuteThread unexpected state [%d], moving back to IDLE." \ ", swState->gc.gSTATE_IDLE " % (self.swState) self.ProcessIdleSate() self.swState = gc.gSTATE_IDLE else: message ="** Serial Port is close, gsatProgramExecuteThread terminating.\n" if self.cmdLineOptions.verbose: print message.strip() # make sure we stop processing any states... self.swState = gc.gSTATE_ABORT # add data to queue and signal main window to consume self.progExecOutQueue.put(gc.threadEvent(gc.gEV_ABORT, "")) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) wx.LogMessage(message) break time.sleep(0.02) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread exit."
def ProcessQueue(self): # check output queue and notify UI if is not empty if not self.progExecOutQueue.empty(): if self.okToPostEvents: self.okToPostEvents = False wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) # process events from queue --------------------------------------------- if not self.progExecInQueue.empty(): # get item from queue e = self.progExecInQueue.get() self.lastEventID = e.event_id if e.event_id == gc.gEV_CMD_EXIT: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_EXIT." self.endThread = True self.swState = gc.gSTATE_IDLE if self.serialRxThread is not None: self.progExecSerialRxOutQueue.put(gc.threadEvent(gc.gEV_CMD_EXIT, None)) elif e.event_id == gc.gEV_CMD_RUN: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_RUN, swState->gc.gSTATE_RUN" self.gcodeDataLines = e.data[0] self.initialProgramCounter = e.data[1] self.workingProgramCounter = self.initialProgramCounter self.breakPointSet = e.data[2] self.swState = gc.gSTATE_RUN elif e.event_id == gc.gEV_CMD_STEP: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_STEP, swState->gc.gSTATE_STEP" self.gcodeDataLines = e.data[0] self.initialProgramCounter = e.data[1] self.workingProgramCounter = self.initialProgramCounter self.breakPointSet = e.data[2] self.swState = gc.gSTATE_STEP elif e.event_id == gc.gEV_CMD_STOP: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_STOP, swState->gc.gSTATE_IDLE" self.swState = gc.gSTATE_IDLE elif e.event_id == gc.gEV_CMD_SEND: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_SEND." self.serialWriteQueue.append((e.data, False)) elif e.event_id == gc.gEV_CMD_SEND_W_ACK: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_SEND_W_ACK." self.serialWriteQueue.append((e.data, True)) elif e.event_id == gc.gEV_CMD_AUTO_STATUS: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_AUTO_STATUS." self.machineAutoStatus = e.data elif e.event_id == gc.gEV_CMD_OK_TO_POST: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_OK_TO_POST." self.okToPostEvents = True else: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got unknown event!! [%s]." % str(e.event_id)
exFlag = True except IOError, e: exMsg = "** IOError exception: %s\n" % str(e) exFlag = True if exFlag: # make sure we stop processing any states... self.swState = gc.gSTATE_ABORT if self.cmdLineOptions.verbose: print exMsg.strip() # add data to queue and signal main window self.progExecOutQueue.put(gc.threadEvent(gc.gEV_ABORT, exMsg)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) def DecodeStatusData (self, serialData): # ----------------------------------------------------------------- # Grbl if self.deviceID == gc.gDEV_GRBL: # GRBL status data rematch = gReGRBLMachineStatus.match(serialData) # data is expected to be an array of strings as follows # statusData[0] : Machine state # statusData[1] : Machine X # statusData[2] : Machine Y # statusData[3] : Machine Z
def run(self): """Run Worker Thread.""" # This is the code executing in the new thread. self.endThread = False if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread start." # inti serial RX thread self.serialRxThread = gsatSerialPortThread( self, self.serPort, self.progExecSerialRxOutQueue, self.progExecSerialRxInQueue, self.cmdLineOptions) # init communication with device (helps to force tinyG into txt mode if self.deviceID == gc.gDEV_TINYG2 or self.deviceID == gc.gDEV_TINYG: self.SerialWrite(gc.gTINYG_CMD_GET_STATUS) elif self.deviceID == gc.gDEV_GRBL: self.SerialWrite(gc.gGRBL_CMD_GET_STATUS) self.SerialWrite(gc.gGRBL_CMD_GET_STATUS) while (self.endThread != True): # process input queue for new commands or actions self.ProcessQueue() # process write queue from UI cmds self.ProcessSerialWriteQueue() # check if we need to exit now if self.endThread: break if self.serPort.isOpen(): if self.swState == gc.gSTATE_RUN: self.ProcessRunSate() elif self.swState == gc.gSTATE_STEP: self.ProcessStepSate() elif self.swState == gc.gSTATE_IDLE: self.ProcessIdleSate() elif self.swState == gc.gSTATE_BREAK: self.ProcessIdleSate() elif self.swState == gc.gSTATE_ABORT: # do nothing, wait to be terminated pass else: if self.cmdLineOptions.verbose: print "** gsatProgramExecuteThread unexpected state [%d], moving back to IDLE." \ ", swState->gc.gSTATE_IDLE " % (self.swState) self.ProcessIdleSate() self.swState = gc.gSTATE_IDLE else: message = "** Serial Port is close, gsatProgramExecuteThread terminating.\n" if self.cmdLineOptions.verbose: print message.strip() # make sure we stop processing any states... self.swState = gc.gSTATE_ABORT # add data to queue and signal main window to consume self.progExecOutQueue.put(gc.threadEvent(gc.gEV_ABORT, "")) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) wx.LogMessage(message) break time.sleep(0.02) if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread exit."
def ProcessQueue(self): # check output queue and notify UI if is not empty if not self.progExecOutQueue.empty(): if self.okToPostEvents: self.okToPostEvents = False wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) # process events from queue --------------------------------------------- if not self.progExecInQueue.empty(): # get item from queue e = self.progExecInQueue.get() self.lastEventID = e.event_id if e.event_id == gc.gEV_CMD_EXIT: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_EXIT." self.endThread = True self.swState = gc.gSTATE_IDLE if self.serialRxThread is not None: self.progExecSerialRxOutQueue.put( gc.threadEvent(gc.gEV_CMD_EXIT, None)) elif e.event_id == gc.gEV_CMD_RUN: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_RUN, swState->gc.gSTATE_RUN" self.gcodeDataLines = e.data[0] self.initialProgramCounter = e.data[1] self.workingProgramCounter = self.initialProgramCounter self.breakPointSet = e.data[2] self.swState = gc.gSTATE_RUN elif e.event_id == gc.gEV_CMD_STEP: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_STEP, swState->gc.gSTATE_STEP" self.gcodeDataLines = e.data[0] self.initialProgramCounter = e.data[1] self.workingProgramCounter = self.initialProgramCounter self.breakPointSet = e.data[2] self.swState = gc.gSTATE_STEP elif e.event_id == gc.gEV_CMD_STOP: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_STOP, swState->gc.gSTATE_IDLE" self.swState = gc.gSTATE_IDLE elif e.event_id == gc.gEV_CMD_SEND: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_SEND." self.serialWriteQueue.append((e.data, False)) elif e.event_id == gc.gEV_CMD_SEND_W_ACK: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_SEND_W_ACK." self.serialWriteQueue.append((e.data, True)) elif e.event_id == gc.gEV_CMD_AUTO_STATUS: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_AUTO_STATUS." self.machineAutoStatus = e.data elif e.event_id == gc.gEV_CMD_OK_TO_POST: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got event gc.gEV_CMD_OK_TO_POST." self.okToPostEvents = True else: if self.cmdLineOptions.vverbose: print "** gsatProgramExecuteThread got unknown event!! [%s]." % str( e.event_id)
exFlag = True except IOError, e: exMsg = "** IOError exception: %s\n" % str(e) exFlag = True if exFlag: # make sure we stop processing any states... self.swState = gc.gSTATE_ABORT if self.cmdLineOptions.verbose: print exMsg.strip() # add data to queue and signal main window self.progExecOutQueue.put(gc.threadEvent(gc.gEV_ABORT, exMsg)) wx.PostEvent(self.notifyWindow, gc.threadQueueEvent(None)) def DecodeStatusData(self, serialData): # ----------------------------------------------------------------- # Grbl if self.deviceID == gc.gDEV_GRBL: # GRBL status data rematch = gReGRBLMachineStatus.match(serialData) # data is expected to be an array of strings as follows # statusData[0] : Machine state # statusData[1] : Machine X # statusData[2] : Machine Y # statusData[3] : Machine Z # statusData[4] : Work X