Esempio n. 1
0
    def parseBracketSquare(self, line):
        pat = POSPAT.match(line)
        if pat:
            if pat.group(1) == "PRB":
                OCV.CD["prbx"] = float(pat.group(2))
                OCV.CD["prby"] = float(pat.group(3))
                OCV.CD["prbz"] = float(pat.group(4))

                self.master.gcode.probe.add(
                    OCV.CD["prbx"] + OCV.CD["wx"] - OCV.CD["mx"],
                    OCV.CD["prby"] + OCV.CD["wy"] - OCV.CD["my"],
                    OCV.CD["prbz"] + OCV.CD["wz"] - OCV.CD["mz"])
                self.master._probeUpdate = True
            OCV.CD[pat.group(1)] = \
                [float(pat.group(2)),
                 float(pat.group(3)),
                 float(pat.group(4))]
        else:
            pat = TLOPAT.match(line)
            if pat:
                OCV.CD[pat.group(1)] = pat.group(2)
                self.master._probeUpdate = True
            elif DOLLARPAT.match(line):
                OCV.CD["G"] = line[1:-1].split()
                CNC.updateG()
                self.master._gUpdate = True
Esempio n. 2
0
 def parseBracketSquare(self, line):
     pat = POSPAT.match(line)
     if pat:
         if pat.group(1) == "PRB":
             CNC.vars["prbx"] = float(pat.group(2))
             CNC.vars["prby"] = float(pat.group(3))
             CNC.vars["prbz"] = float(pat.group(4))
             #if self.running:
             self.master.gcode.probe.add(
                 CNC.vars["prbx"] + CNC.vars["wx"] - CNC.vars["mx"],
                 CNC.vars["prby"] + CNC.vars["wy"] - CNC.vars["my"],
                 CNC.vars["prbz"] + CNC.vars["wz"] - CNC.vars["mz"])
             self.master._probeUpdate = True
         CNC.vars[pat.group(1)] = \
          [float(pat.group(2)),
           float(pat.group(3)),
           float(pat.group(4))]
     else:
         pat = TLOPAT.match(line)
         if pat:
             CNC.vars[pat.group(1)] = pat.group(2)
             self.master._probeUpdate = True
         elif DOLLARPAT.match(line):
             CNC.vars["G"] = line[1:-1].split()
             CNC.updateG()
             self.master._gUpdate = True
Esempio n. 3
0
	def parseBracketSquare(self, line):
		pat = POSPAT.match(line)
		if pat:
			if pat.group(1) == "PRB":
				CNC.vars["prbx"] = float(pat.group(2))
				CNC.vars["prby"] = float(pat.group(3))
				CNC.vars["prbz"] = float(pat.group(4))
				#if self.running:
				self.master.gcode.probe.add(
					 CNC.vars["prbx"]
					+CNC.vars["wx"]
					-CNC.vars["mx"],
					 CNC.vars["prby"]
					+CNC.vars["wy"]
					-CNC.vars["my"],
					 CNC.vars["prbz"]
					+CNC.vars["wz"]
					-CNC.vars["mz"])
				self.master._probeUpdate = True
			CNC.vars[pat.group(1)] = \
				[float(pat.group(2)),
				 float(pat.group(3)),
				 float(pat.group(4))]
		else:
			pat = TLOPAT.match(line)
			if pat:
				CNC.vars[pat.group(1)] = pat.group(2)
				self.master._probeUpdate = True
			elif DOLLARPAT.match(line):
				CNC.vars["G"] = line[1:-1].split()
				CNC.updateG()
				self.master._gUpdate = True
Esempio n. 4
0
 def parseBracketSquare(self, line):
     word = SPLITPAT.split(line[1:-1])
     #print word
     if word[0] == "PRB":
         CNC.vars["prbx"] = float(word[1])
         CNC.vars["prby"] = float(word[2])
         CNC.vars["prbz"] = float(word[3])
         #if self.running:
         self.master.gcode.probe.add(CNC.vars["prbx"] - CNC.vars["wcox"],
                                     CNC.vars["prby"] - CNC.vars["wcoy"],
                                     CNC.vars["prbz"] - CNC.vars["wcoz"])
         self.master._probeUpdate = True
         CNC.vars[word[0]] = word[1:]
     if word[0] == "G92":
         CNC.vars["G92X"] = float(word[1])
         #print( float(word[2]) )
         CNC.vars["G92Y"] = float(word[2])
         CNC.vars["G92Z"] = float(word[3])
         #if Utils.config.get("bCNC","enable6axis") == "true":
         if len(word) > 4:
             CNC.vars["G92A"] = float(word[4])
         if len(word) > 5:
             CNC.vars["G92B"] = float(word[5])
         if len(word) > 6:
             CNC.vars["G92C"] = float(word[6])
         CNC.vars[word[0]] = word[1:]
         self.master._gUpdate = True
     if word[0] == "G28":
         CNC.vars["G28X"] = float(word[1])
         CNC.vars["G28Y"] = float(word[2])
         CNC.vars["G28Z"] = float(word[3])
         CNC.vars[word[0]] = word[1:]
         self.master._gUpdate = True
     if word[0] == "G30":
         CNC.vars["G30X"] = float(word[1])
         CNC.vars["G30Y"] = float(word[2])
         CNC.vars["G30Z"] = float(word[3])
         CNC.vars[word[0]] = word[1:]
         self.master._gUpdate = True
     elif word[0] == "GC":
         CNC.vars["G"] = word[1].split()
         CNC.updateG()
         self.master._gUpdate = True
     elif word[0] == "TLO":
         CNC.vars[word[0]] = word[1]
         self.master._probeUpdate = True
         self.master._gUpdate = True
     else:
         CNC.vars[word[0]] = word[1:]
Esempio n. 5
0
    def parseBracketSquare(self, line):
        word = SPLITPAT.split(line[1:-1])
        # print word
        if word[0] == "PRB":
            OCV.CD["prbx"] = float(word[1])
            OCV.CD["prby"] = float(word[2])
            OCV.CD["prbz"] = float(word[3])

            self.master.gcode.probe.add(OCV.CD["prbx"] - OCV.CD["wcox"],
                                        OCV.CD["prby"] - OCV.CD["wcoy"],
                                        OCV.CD["prbz"] - OCV.CD["wcoz"])
            self.master._probeUpdate = True
            OCV.CD[word[0]] = word[1:]
        if word[0] == "G92":
            OCV.CD["G92X"] = float(word[1])
            OCV.CD["G92Y"] = float(word[2])
            OCV.CD["G92Z"] = float(word[3])
            OCV.CD[word[0]] = word[1:]
            self.master._gUpdate = True
        if word[0] == "G28":
            OCV.CD["G28X"] = float(word[1])
            OCV.CD["G28Y"] = float(word[2])
            OCV.CD["G28Z"] = float(word[3])
            OCV.CD[word[0]] = word[1:]
            self.master._gUpdate = True
        if word[0] == "G30":
            OCV.CD["G30X"] = float(word[1])
            OCV.CD["G30Y"] = float(word[2])
            OCV.CD["G30Z"] = float(word[3])
            OCV.CD[word[0]] = word[1:]
            self.master._gUpdate = True
        elif word[0] == "GC":
            OCV.CD["G"] = word[1].split()
            CNC.updateG()
            self.master._gUpdate = True
        elif word[0] == "TLO":
            OCV.CD[word[0]] = word[1]
            self.master._probeUpdate = True
            self.master._gUpdate = True
        elif word[0] == "MSG:" and word[1:] == "Pgm End":
            # Catch the program end message as sometimes it hangs in Run state.
            print("GRBL1: PE")
            OCV.c_pgm_end = True
        else:
            OCV.CD[word[0]] = word[1:]
Esempio n. 6
0
	def parseBracketSquare(self, line):
		word = SPLITPAT.split(line[1:-1])
		#print word
		if word[0] == "PRB":
			CNC.vars["prbx"] = float(word[1])
			CNC.vars["prby"] = float(word[2])
			CNC.vars["prbz"] = float(word[3])
			#if self.running:
			self.master.gcode.probe.add(
				 CNC.vars["prbx"]-CNC.vars["wcox"],
				 CNC.vars["prby"]-CNC.vars["wcoy"],
				 CNC.vars["prbz"]-CNC.vars["wcoz"])
			self.master._probeUpdate = True
			CNC.vars[word[0]] = word[1:]
		if word[0] == "G92":
			CNC.vars["G92X"] = float(word[1])
			CNC.vars["G92Y"] = float(word[2])
			CNC.vars["G92Z"] = float(word[3])
			CNC.vars[word[0]] = word[1:]
			self.master._gUpdate = True
		if word[0] == "G28":
			CNC.vars["G28X"] = float(word[1])
			CNC.vars["G28Y"] = float(word[2])
			CNC.vars["G28Z"] = float(word[3])
			CNC.vars[word[0]] = word[1:]
			self.master._gUpdate = True
		if word[0] == "G30":
			CNC.vars["G30X"] = float(word[1])
			CNC.vars["G30Y"] = float(word[2])
			CNC.vars["G30Z"] = float(word[3])
			CNC.vars[word[0]] = word[1:]
			self.master._gUpdate = True
		elif word[0] == "GC":
			CNC.vars["G"] = word[1].split()
			CNC.updateG()
			self.master._gUpdate = True
		elif word[0] == "TLO":
			CNC.vars[word[0]] = word[1]
			self.master._probeUpdate = True
			self.master._gUpdate = True
		else:
			CNC.vars[word[0]] = word[1:]
Esempio n. 7
0
 def parseBracketSquare(self, line):
     word = SPLITPAT.split(line[1:-1])
     # print word
     if word[0] == "PRB":
         CNC.vars["prbx"] = float(word[1])
         CNC.vars["prby"] = float(word[2])
         CNC.vars["prbz"] = float(word[3])
         # if self.running:
         self.master.gcode.probe.add(CNC.vars["prbx"] - CNC.vars["wcox"],
                                     CNC.vars["prby"] - CNC.vars["wcoy"],
                                     CNC.vars["prbz"] - CNC.vars["wcoz"])
         self.master._probeUpdate = True
         CNC.vars[word[0]] = word[1:]
     if word[0] == "G92":
         CNC.vars["G92X"] = float(word[1])
         CNC.vars["G92Y"] = float(word[2])
         CNC.vars["G92Z"] = float(word[3])
         CNC.vars[word[0]] = word[1:]
         self.master._gUpdate = True
     if word[0] == "G28":
         CNC.vars["G28X"] = float(word[1])
         CNC.vars["G28Y"] = float(word[2])
         CNC.vars["G28Z"] = float(word[3])
         CNC.vars[word[0]] = word[1:]
         self.master._gUpdate = True
     if word[0] == "G30":
         CNC.vars["G30X"] = float(word[1])
         CNC.vars["G30Y"] = float(word[2])
         CNC.vars["G30Z"] = float(word[3])
         CNC.vars[word[0]] = word[1:]
         self.master._gUpdate = True
     elif word[0] == "GC":
         CNC.vars["G"] = word[1].split()
         CNC.updateG()
         self.master._gUpdate = True
     elif word[0] == "TLO":
         CNC.vars[word[0]] = word[1]
         self.master._probeUpdate = True
         self.master._gUpdate = True
     else:
         CNC.vars[word[0]] = word[1:]
Esempio n. 8
0
    def serialIO(self):
        cline = []  # length of pipeline commands
        sline = []  # pipeline commands
        wait = False  # wait for commands to complete
        tosend = None  # next string to send
        status = False  # waiting for status <...> report
        tr = tg = time.time()  # last time a ? or $G was send to grbl

        while self.thread:
            t = time.time()

            # refresh machine position?
            if t - tr > SERIAL_POLL:
                # Send one ?
                self.serial.write(b"?")
                status = True
                #print ">S> ?"
                tr = t

            # Fetch new command to send if...
            if tosend is None and not wait and not self._pause and self.queue.qsize(
            ) > 0:
                try:
                    tosend = self.queue.get_nowait()
                    #print "+++",repr(tosend)

                    if isinstance(tosend, tuple):
                        # Count executed commands as well
                        self._gcount += 1
                        # wait to empty the grbl buffer
                        if tosend[0] == WAIT:
                            wait = True
                            #print "+++ WAIT ON"
                        elif tosend[0] == PAUSE:
                            if tosend[1] is not None:
                                # show our message on machine status
                                self._msg = tosend[1]
                            # Feed hold
                            # Maybe a M0 would be better?
                            self.serial.write(b"!")
                            #print ">S> !"
                        elif tosend[0] == UPDATE:
                            self._update = tosend[1]
                        tosend = None

                    elif not isinstance(tosend, str):
                        try:
                            tosend = self.gcode.evaluate(tosend)
                            #							if isinstance(tosend, list):
                            #								cline.append(len(tosend[0]))
                            #								sline.append(tosend[0])
                            #								self.log.put((True,tosend[0]))
                            if isinstance(tosend, str):
                                tosend += "\n"
                            else:
                                # Count executed commands as well
                                self._gcount += 1
                            #print "+++ eval=",repr(tosend),type(tosend)
                        except:
                            self.log.put((True, sys.exc_info()[1]))
                            tosend = None
                except Empty:
                    break

                if tosend is not None:
                    # All modification in tosend should be
                    # done before adding it to cline
                    if isinstance(tosend, unicode):
                        tosend = tosend.encode("ascii", "replace")

                    # FIXME should be smarter and apply the feed override
                    # also on cards with out feed (the first time only)
                    # I should track the feed rate for every card
                    # and when it is changed apply a F### command
                    # even if it is not there
                    if CNC.vars["override"] != 100:
                        pat = FEEDPAT.match(tosend)
                        if pat is not None:
                            try:
                                tosend = "%sf%g%s\n" % \
                                 (pat.group(1),
                                  float(pat.group(2))*CNC.vars["override"]/100.0,
                                  pat.group(3))
                            except:
                                pass

                    # Bookkeeping of the buffers
                    sline.append(tosend)
                    cline.append(len(tosend))
                    self.log.put((True, tosend))

            # Anything to receive?
            if self.serial.inWaiting() or tosend is None:
                line = str(self.serial.readline()).strip()
                #print "<R<",repr(line)
                #print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
                if line:
                    if line[0] == "<":
                        pat = STATUSPAT.match(line)
                        if pat:
                            if not status: self.log.put((False, line + "\n"))
                            status = False
                            if not self._alarm:
                                CNC.vars["state"] = pat.group(1)
                            CNC.vars["mx"] = float(pat.group(2))
                            CNC.vars["my"] = float(pat.group(3))
                            CNC.vars["mz"] = float(pat.group(4))
                            CNC.vars["wx"] = float(pat.group(5))
                            CNC.vars["wy"] = float(pat.group(6))
                            CNC.vars["wz"] = float(pat.group(7))
                            self._posUpdate = True

                            if pat.group(1) != "Hold" and self._msg:
                                self._msg = None

                            # Machine is Idle buffer is empty
                            # stop waiting and go on
                            #print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
                            if wait and not cline and pat.group(1) == "Idle":
                                wait = False
                                #print "<<< NO MORE WAIT"
                        else:
                            self.log.put((False, line + "\n"))

                    elif line[0] == "[":
                        self.log.put((False, line + "\n"))
                        pat = POSPAT.match(line)
                        if pat:
                            if pat.group(1) == "PRB":
                                CNC.vars["prbx"] = float(pat.group(2))
                                CNC.vars["prby"] = float(pat.group(3))
                                CNC.vars["prbz"] = float(pat.group(4))
                                if self.running:
                                    self.gcode.probe.add(
                                        CNC.vars["prbx"] + CNC.vars["wx"] -
                                        CNC.vars["mx"], CNC.vars["prby"] +
                                        CNC.vars["wy"] - CNC.vars["my"],
                                        CNC.vars["prbz"] + CNC.vars["wz"] -
                                        CNC.vars["mz"])
                                self._probeUpdate = True
                            CNC.vars[pat.group(1)] = \
                             [float(pat.group(2)),
                              float(pat.group(3)),
                              float(pat.group(4))]
                        else:
                            pat = TLOPAT.match(line)
                            if pat:
                                CNC.vars[pat.group(1)] = pat.group(2)
                                self._probeUpdate = True
                            else:
                                CNC.vars["G"] = line[1:-1].split()
                                CNC.updateG()
                                self._gUpdate = True

                    else:
                        #print "<r<",repr(line)
                        self.log.put((False, line + "\n"))
                        uline = line.upper()
                        if uline.find("ERROR") == 0 or uline.find(
                                "ALARM") == 0:
                            self._gcount += 1
                            if cline: del cline[0]
                            if sline: CNC.vars["errline"] = sline.pop(0)
                            if not self._alarm: self._posUpdate = True
                            self._alarm = True
                            CNC.vars["state"] = line
                            if self.running:
                                self.emptyQueue()
                                # Dangerous calling state of Tk if not reentrant
                                self.runEnded()
                                tosend = None
                                del cline[:]
                                del sline[:]

                        elif line.find("ok") >= 0:
                            self._gcount += 1
                            if cline: del cline[0]
                            if sline: del sline[0]

            # Received external message to stop
            if self._stop:
                self.emptyQueue()
                tosend = None
                del cline[:]
                del sline[:]
                self._stop = False

            #print "tosend='%s'"%(repr(tosend)),"stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
            if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
                #				if isinstance(tosend, list):
                #					self.serial.write(str(tosend.pop(0)))
                #					if not tosend: tosend = None

                #print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
                self.serial.write(bytes(tosend))
                #				self.serial.flush()

                tosend = None
                if not self.running and t - tg > G_POLL:
                    tosend = b"$G\n"
                    sline.append(tosend)
                    cline.append(len(tosend))
                    tg = t
Esempio n. 9
0
File: Sender.py Progetto: YUESS/bCNC
	def serialIO(self):
		cline  = []		# length of pipeline commands
		sline  = []		# pipeline commands
		wait   = False		# wait for commands to complete
		tosend = None		# next string to send
		status = False		# waiting for status <...> report
		tr = tg = time.time()	# last time a ? or $G was send to grbl

		while self.thread:
			t = time.time()

			# refresh machine position?
			if t-tr > SERIAL_POLL:
				# Send one ?
				self.serial.write(b"?")
				status = True
				#print ">S> ?"
				tr = t

			# Fetch new command to send if...
			if tosend is None and not wait and not self._pause and self.queue.qsize()>0:
				try:
					tosend = self.queue.get_nowait()
					#print "+++",repr(tosend)

					if isinstance(tosend, tuple):
						#print "gcount tuple=",self._gcount
						# wait to empty the grbl buffer
						if tosend[0] == WAIT:
							# Don't count WAIT until we are idle!
							wait = True
							#print "+++ WAIT ON"
							#print "gcount=",self._gcount, self._runLines
						elif tosend[0] == MSG:
							# Count executed commands as well
							self._gcount += 1
							if tosend[1] is not None:
								# show our message on machine status
								self._msg = tosend[1]
						elif tosend[0] == UPDATE:
							# Count executed commands as well
							self._gcount += 1
							self._update = tosend[1]
						else:
							# Count executed commands as well
							self._gcount += 1
						tosend = None

					elif not isinstance(tosend,str) and not isinstance(tosend,unicode):
						try:
							tosend = self.gcode.evaluate(tosend)
#							if isinstance(tosend, list):
#								cline.append(len(tosend[0]))
#								sline.append(tosend[0])
#								self.log.put((True,tosend[0]))
							if isinstance(tosend,str) or isinstance(tosend,unicode):
								tosend += "\n"
							else:
								# Count executed commands as well
								self._gcount += 1
								#print "gcount str=",self._gcount
							#print "+++ eval=",repr(tosend),type(tosend)
						except:
							self.log.put((True,sys.exc_info()[1]))
							tosend = None
				except Empty:
					break

				if tosend is not None:
					# All modification in tosend should be
					# done before adding it to cline
					if isinstance(tosend, unicode):
						tosend = tosend.encode("ascii","replace")

					#Keep track of last feed
					pat = FEEDPAT.match(tosend)
					if pat is not None:
						self._lastFeed = pat.group(2)
						self._newFeed = float(self._lastFeed)*CNC.vars["override"]/100.0

					#If Override change, attach feed
					if CNC.vars["overrideChanged"]:
						CNC.vars["overrideChanged"] = False
						if pat is None and self._newFeed!=0:
							tosend = "f%g" % (self._newFeed) + tosend

					#Apply override Feed
					if CNC.vars["override"] != 100 and self._newFeed!=0:
						pat = FEEDPAT.match(tosend)
						if pat is not None:
							try:
								tosend = "%sf%g%s\n" % \
									(pat.group(1),
									 self._newFeed,
									 pat.group(3))
							except:
								pass

					# Bookkeeping of the buffers
					sline.append(tosend)
					cline.append(len(tosend))
					self.log.put((True,tosend))

			# Anything to receive?
			if self.serial.inWaiting() or tosend is None:
				line = str(self.serial.readline()).strip()
				#print "<R<",repr(line)
				#print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
				if line:
					if line[0]=="<":
						pat = STATUSPAT.match(line)
						if pat:
							if not status: self.log.put((False, line+"\n"))
							status = False
							if not self._alarm:
								CNC.vars["state"] = pat.group(1)
							CNC.vars["mx"] = float(pat.group(2))
							CNC.vars["my"] = float(pat.group(3))
							CNC.vars["mz"] = float(pat.group(4))
							CNC.vars["wx"] = float(pat.group(5))
							CNC.vars["wy"] = float(pat.group(6))
							CNC.vars["wz"] = float(pat.group(7))
							self._posUpdate = True
							if pat.group(1) != "Hold" and self._msg:
								self._msg = None

							# Machine is Idle buffer is empty
							# stop waiting and go on
							#print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
							#print ">>>", line
							if wait and not cline and pat.group(1)=="Idle":
								#print ">>>",line
								wait = False
								#print "<<< NO MORE WAIT"
								self._gcount += 1
						else:
							self.log.put((False, line+"\n"))

					elif line[0]=="[":
						self.log.put((False, line+"\n"))
						pat = POSPAT.match(line)
						if pat:
							if pat.group(1) == "PRB":
								CNC.vars["prbx"] = float(pat.group(2))
								CNC.vars["prby"] = float(pat.group(3))
								CNC.vars["prbz"] = float(pat.group(4))
								#if self.running:
								self.gcode.probe.add(
									 CNC.vars["prbx"]
									+CNC.vars["wx"]
									-CNC.vars["mx"],

									 CNC.vars["prby"]
									+CNC.vars["wy"]
									-CNC.vars["my"],

									 CNC.vars["prbz"]
									+CNC.vars["wz"]
									-CNC.vars["mz"])
								self._probeUpdate = True
							CNC.vars[pat.group(1)] = \
								[float(pat.group(2)),
								 float(pat.group(3)),
								 float(pat.group(4))]
						else:
							pat = TLOPAT.match(line)
							if pat:
								CNC.vars[pat.group(1)] = pat.group(2)
								self._probeUpdate = True
							elif DOLLARPAT.match(line):
								CNC.vars["G"] = line[1:-1].split()
								CNC.updateG()
								self._gUpdate = True

					else:
						#print "<r<",repr(line)
						self.log.put((False, line+"\n"))
						uline = line.upper()
						if uline.find("ERROR")==0 or uline.find("ALARM")==0:
							self._gcount += 1
							#print "gcount ERROR=",self._gcount
							if cline: del cline[0]
							if sline: CNC.vars["errline"] = sline.pop(0)
							if not self._alarm: self._posUpdate = True
							self._alarm = True
							CNC.vars["state"] = line
							if self.running:
								self._stop = True
								#self.emptyQueue()
								# Dangerous calling state of Tk if not reentrant
								self.runEnded()
								#tosend = None
								#del cline[:]
								#del sline[:]

						elif line.find("ok")>=0:
							self._gcount += 1
							#print "gcount OK=",self._gcount
							if cline: del cline[0]
							if sline: del sline[0]
							#print "SLINE:",sline

			# Received external message to stop
			if self._stop:
				self.emptyQueue()
				tosend = None
				del cline[:]
				del sline[:]
				# WARNING if maxint then it means we are still preparing/sending
				# lines from from bCNC.run(), so don't stop
				if self._runLines != sys.maxint:
					self._stop = False

			#print "tosend='%s'"%(repr(tosend)),"stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
			if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
				self._sumcline = sum(cline)
#				if isinstance(tosend, list):
#					self.serial.write(str(tosend.pop(0)))
#					if not tosend: tosend = None

				#print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
				if self.controller==Utils.SMOOTHIE: tosend = tosend.upper()
				self.serial.write(bytes(tosend))
#				self.serial.write(tosend.encode("utf8"))
#				self.serial.flush()

				tosend = None
				if not self.running and t-tg > G_POLL:
					tosend = b"$G\n"
					sline.append(tosend)
					cline.append(len(tosend))
					tg = t
Esempio n. 10
0
	def serialIO(self):
		cline  = []		# length of pipeline commands
		sline  = []		# pipeline commands
		wait   = False		# wait for commands to complete
		tosend = None		# next string to send
		status = False		# waiting for status <...> report
		tr = tg = time.time()	# last time a ? or $G was send to grbl

		while self.thread:
			t = time.time()

			# refresh machine position?
			if t-tr > SERIAL_POLL:
				# Send one ?
				self.serial.write(b"?")
				status = True
				#print ">S> ?"
				tr = t

			# Fetch new command to send if...
			if tosend is None and not wait and not self._pause and self.queue.qsize()>0:
				try:
					tosend = self.queue.get_nowait()
					#print "+++",repr(tosend)

					if isinstance(tosend, tuple):
						# Count executed commands as well
						self._gcount += 1
						# wait to empty the grbl buffer
						if tosend[0] == WAIT:
							wait = True
							#print "+++ WAIT ON"
						elif tosend[0] == PAUSE:
							if tosend[1] is not None:
								# show our message on machine status
								self._msg = tosend[1]
							# Feed hold
							# Maybe a M0 would be better?
							self.serial.write(b"!")
							#print ">S> !"
						elif tosend[0] == UPDATE:
							self._update = tosend[1]
						tosend = None

					elif not isinstance(tosend, str):
						try:
							tosend = self.gcode.evaluate(tosend)
#							if isinstance(tosend, list):
#								cline.append(len(tosend[0]))
#								sline.append(tosend[0])
#								self.log.put((True,tosend[0]))
							if isinstance(tosend,str):
								tosend += "\n"
							else:
								# Count executed commands as well
								self._gcount += 1
							#print "+++ eval=",repr(tosend),type(tosend)
						except:
							self.log.put((True,sys.exc_info()[1]))
							tosend = None
				except Empty:
					break

				if tosend is not None:
					# All modification in tosend should be
					# done before adding it to cline
					if isinstance(tosend, unicode):
						tosend = tosend.encode("ascii","replace")

					# FIXME should be smarter and apply the feed override
					# also on cards with out feed (the first time only)
					# I should track the feed rate for every card
					# and when it is changed apply a F### command
					# even if it is not there
					if CNC.vars["override"] != 100:
						pat = FEEDPAT.match(tosend)
						if pat is not None:
							try:
								tosend = "%sf%g%s\n" % \
									(pat.group(1),
									 float(pat.group(2))*CNC.vars["override"]/100.0,
									 pat.group(3))
							except:
								pass

					# Bookkeeping of the buffers
					sline.append(tosend)
					cline.append(len(tosend))
					self.log.put((True,tosend))

			# Anything to receive?
			if self.serial.inWaiting() or tosend is None:
				line = str(self.serial.readline()).strip()
				#print "<R<",repr(line)
				#print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
				if line:
					if line[0]=="<":
						pat = STATUSPAT.match(line)
						if pat:
							if not status: self.log.put((False, line+"\n"))
							status = False
							if not self._alarm:
								CNC.vars["state"] = pat.group(1)
							CNC.vars["mx"] = float(pat.group(2))
							CNC.vars["my"] = float(pat.group(3))
							CNC.vars["mz"] = float(pat.group(4))
							CNC.vars["wx"] = float(pat.group(5))
							CNC.vars["wy"] = float(pat.group(6))
							CNC.vars["wz"] = float(pat.group(7))
							self._posUpdate = True

							if pat.group(1) != "Hold" and self._msg:
								self._msg = None

							# Machine is Idle buffer is empty
							# stop waiting and go on
							#print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
							if wait and not cline and pat.group(1)=="Idle":
								wait = False
								#print "<<< NO MORE WAIT"
						else:
							self.log.put((False, line+"\n"))

					elif line[0]=="[":
						self.log.put((False, line+"\n"))
						pat = POSPAT.match(line)
						if pat:
							if pat.group(1) == "PRB":
								CNC.vars["prbx"] = float(pat.group(2))
								CNC.vars["prby"] = float(pat.group(3))
								CNC.vars["prbz"] = float(pat.group(4))
								if self.running:
									self.gcode.probe.add(
										 CNC.vars["prbx"]
										+CNC.vars["wx"]
										-CNC.vars["mx"],

										 CNC.vars["prby"]
										+CNC.vars["wy"]
										-CNC.vars["my"],

										 CNC.vars["prbz"]
										+CNC.vars["wz"]
										-CNC.vars["mz"])
								self._probeUpdate = True
							CNC.vars[pat.group(1)] = \
								[float(pat.group(2)),
								 float(pat.group(3)),
								 float(pat.group(4))]
						else:
							pat = TLOPAT.match(line)
							if pat:
								CNC.vars[pat.group(1)] = pat.group(2)
								self._probeUpdate = True
							else:
								CNC.vars["G"] = line[1:-1].split()
								CNC.updateG()
								self._gUpdate = True

					else:
						#print "<r<",repr(line)
						self.log.put((False, line+"\n"))
						uline = line.upper()
						if uline.find("ERROR")==0 or uline.find("ALARM")==0:
							self._gcount += 1
							if cline: del cline[0]
							if sline: CNC.vars["errline"] = sline.pop(0)
							if not self._alarm: self._posUpdate = True
							self._alarm = True
							CNC.vars["state"] = line
							if self.running:
								self.emptyQueue()
								# Dangerous calling state of Tk if not reentrant
								self.runEnded()
								tosend = None
								del cline[:]
								del sline[:]

						elif line.find("ok")>=0:
							self._gcount += 1
							if cline: del cline[0]
							if sline: del sline[0]

			# Received external message to stop
			if self._stop:
				self.emptyQueue()
				tosend = None
				del cline[:]
				del sline[:]
				self._stop = False

			#print "tosend='%s'"%(repr(tosend)),"stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
			if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
#				if isinstance(tosend, list):
#					self.serial.write(str(tosend.pop(0)))
#					if not tosend: tosend = None

				#print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
				self.serial.write(bytes(tosend))
#				self.serial.flush()

				tosend = None
				if not self.running and t-tg > G_POLL:
					tosend = b"$G\n"
					sline.append(tosend)
					cline.append(len(tosend))
					tg = t
Esempio n. 11
0
	def serialIO(self):
		cline  = []		# length of pipeline commands
		sline  = []		# pipeline commands
		wait   = False		# wait for commands to complete (status change to Idle)
		tosend = None		# next string to send
		status = False		# waiting for status <...> report
		tr = tg = time.time()	# last time a ? or $G was send to grbl

		while self.thread:
			t = time.time()
			# refresh machine position?
			if t-tr > SERIAL_POLL:
				self.serial.write(b"?")
				status = True
				tr = t

				#If Override change, attach feed
				if CNC.vars["_OvChanged"] and self.controller == Utils.GRBL1:
					CNC.vars["_OvChanged"] = False	# Temporary
					# Check feed
					diff = CNC.vars["_OvFeed"] - CNC.vars["OvFeed"]
					if diff==0:
						pass
					elif CNC.vars["_OvFeed"] == 100:
						self.serial.write(OV_FEED_100)
					elif diff >= 10:
						self.serial.write(OV_FEED_i10)
						CNC.vars["_OvChanged"] = diff>10
					elif diff <= -10:
						self.serial.write(OV_FEED_d10)
						CNC.vars["_OvChanged"] = diff<-10
					elif diff >= 1:
						self.serial.write(OV_FEED_i1)
						CNC.vars["_OvChanged"] = diff>1
					elif diff <= -1:
						self.serial.write(OV_FEED_d1)
						CNC.vars["_OvChanged"] = diff<-1
					# Check rapid
					target  = CNC.vars["_OvRapid"]
					current = CNC.vars["OvRapid"]
					if target == current:
						pass
					elif target == 100:
						self.serial.write(OV_RAPID_100)
					elif target == 75:
						self.serial.write(OV_RAPID_50)	# FIXME
					elif target == 50:
						self.serial.write(OV_RAPID_50)
					elif target == 25:
						self.serial.write(OV_RAPID_25)
					# Check Spindle
					diff = CNC.vars["_OvSpindle"] - CNC.vars["OvSpindle"]
					if diff==0:
						pass
					elif CNC.vars["_OvSpindle"] == 100:
						self.serial.write(OV_SPINDLE_100)
					elif diff >= 10:
						self.serial.write(OV_SPINDLE_i10)
						CNC.vars["_OvChanged"] = diff>10
					elif diff <= -10:
						self.serial.write(OV_SPINDLE_d10)
						CNC.vars["_OvChanged"] = diff<-10
					elif diff >= 1:
						self.serial.write(OV_SPINDLE_i1)
						CNC.vars["_OvChanged"] = diff>1
					elif diff <= -1:
						self.serial.write(OV_SPINDLE_d1)
						CNC.vars["_OvChanged"] = diff<-1

			# Fetch new command to send if...
			if tosend is None and not wait and not self._pause and self.queue.qsize()>0:
				try:
					tosend = self.queue.get_nowait()
					#print "+++",repr(tosend)
					if isinstance(tosend, tuple):
						#print "gcount tuple=",self._gcount
						# wait to empty the grbl buffer and status is Idle
						if tosend[0] == WAIT:
							# Don't count WAIT until we are idle!
							wait = True
							#print "+++ WAIT ON"
							#print "gcount=",self._gcount, self._runLines
						elif tosend[0] == MSG:
							# Count executed commands as well
							self._gcount += 1
							if tosend[1] is not None:
								# show our message on machine status
								self._msg = tosend[1]
						elif tosend[0] == UPDATE:
							# Count executed commands as well
							self._gcount += 1
							self._update = tosend[1]
						else:
							# Count executed commands as well
							self._gcount += 1
						tosend = None

					elif not isinstance(tosend,str) and not isinstance(tosend,unicode):
						try:
							tosend = self.gcode.evaluate(tosend)
#							if isinstance(tosend, list):
#								cline.append(len(tosend[0]))
#								sline.append(tosend[0])
							if isinstance(tosend,str) or isinstance(tosend,unicode):
								tosend += "\n"
							else:
								# Count executed commands as well
								self._gcount += 1
								#print "gcount str=",self._gcount
							#print "+++ eval=",repr(tosend),type(tosend)
						except:
							for s in str(sys.exc_info()[1]).splitlines():
								self.log.put((Sender.MSG_ERROR,s))
							self._gcount += 1
							tosend = None
				except Empty:
					break

				if tosend is not None:
					# All modification in tosend should be
					# done before adding it to cline
					if isinstance(tosend, unicode):
						tosend = tosend.encode("ascii","replace")

					# Keep track of last feed
					pat = FEEDPAT.match(tosend)
					if pat is not None:
						self._lastFeed = pat.group(2)

					if self.controller in (Utils.GRBL0, Utils.SMOOTHIE):
						if CNC.vars["_OvChanged"]:
							CNC.vars["_OvChanged"] = False
							self._newFeed = float(self._lastFeed)*CNC.vars["_OvFeed"]/100.0
							if pat is None and self._newFeed!=0 \
							   and not tosend.startswith("$"):
								tosend = "f%g%s" % (self._newFeed, tosend)

						# Apply override Feed
						if CNC.vars["_OvFeed"] != 100 and self._newFeed != 0:
							pat = FEEDPAT.match(tosend)
							if pat is not None:
								try:
									tosend = "%sf%g%s\n" % \
										(pat.group(1),
										 self._newFeed,
										 pat.group(3))
								except:
									pass

					# Bookkeeping of the buffers
					sline.append(tosend)
					cline.append(len(tosend))

			# Anything to receive?
			if self.serial.inWaiting() or tosend is None:
				try:
					line = str(self.serial.readline()).strip()
				except:
					self.log.put((Sender.MSG_RECEIVE, str(sys.exc_info()[1])))
					self.emptyQueue()
					self.close()
					return

				#print "<R<",repr(line)
				#print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
				if not line:
					pass

				elif line[0]=="<":
					if not status:
						self.log.put((Sender.MSG_RECEIVE, line))

					elif self.controller == Utils.GRBL1:
						status = False
						fields = line[1:-1].split("|")
						if not self._alarm:
							CNC.vars["state"] = fields[0]
						for field in fields[1:]:
							word = SPLITPAT.split(field)
							if word[0] == "MPos":
								try:
									CNC.vars["mx"] = float(word[1])
									CNC.vars["my"] = float(word[2])
									CNC.vars["mz"] = float(word[3])
									CNC.vars["wx"] = round(CNC.vars["mx"]-CNC.vars["wcox"], CNC.digits)
									CNC.vars["wy"] = round(CNC.vars["my"]-CNC.vars["wcoy"], CNC.digits)
									CNC.vars["wz"] = round(CNC.vars["mz"]-CNC.vars["wcoz"], CNC.digits)
									self._posUpdate = True
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "F":
								try:
									CNC.vars["curfeed"] = float(word[1])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "FS":
								try:
									CNC.vars["curfeed"]    = float(word[1])
									CNC.vars["curspindle"] = float(word[2])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "Bf":
								try:
									CNC.vars["planner"] = int(word[1])
									CNC.vars["rxbytes"] = int(word[2])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "Ov":
								try:
									CNC.vars["OvFeed"]    = int(word[1])
									CNC.vars["OvRapid"]   = int(word[2])
									CNC.vars["OvSpindle"] = int(word[3])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "WCO":
								try:
									CNC.vars["wcox"] = float(word[1])
									CNC.vars["wcoy"] = float(word[2])
									CNC.vars["wcoz"] = float(word[3])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break

						# Machine is Idle buffer is empty stop waiting and go on
						if wait and not cline and fields[0] in ("Idle","Check"):
							wait = False
							self._gcount += 1

					else:
						status = False
						pat = STATUSPAT.match(line)
						if pat:
							if not self._alarm:
								CNC.vars["state"] = pat.group(1)
							CNC.vars["mx"] = float(pat.group(2))
							CNC.vars["my"] = float(pat.group(3))
							CNC.vars["mz"] = float(pat.group(4))
							CNC.vars["wx"] = float(pat.group(5))
							CNC.vars["wy"] = float(pat.group(6))
							CNC.vars["wz"] = float(pat.group(7))
							CNC.vars["wcox"] = CNC.vars["mx"] - CNC.vars["wx"]
							CNC.vars["wcoy"] = CNC.vars["my"] - CNC.vars["wy"]
							CNC.vars["wcoz"] = CNC.vars["mz"] - CNC.vars["wz"]
							self._posUpdate = True
							if pat.group(1)[:4] != "Hold" and self._msg:
								self._msg = None

							# Machine is Idle buffer is empty
							# stop waiting and go on
							#print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
							#print ">>>", line
							if wait and not cline and pat.group(1) in ("Idle","Check"):
								#print ">>>",line
								wait = False
								#print "<<< NO MORE WAIT"
								self._gcount += 1
						else:
							self.log.put((Sender.MSG_RECEIVE, line))

				elif line[0]=="[":
					self.log.put((Sender.MSG_RECEIVE, line))
					if self.controller == Utils.GRBL1:
						word = SPLITPAT.split(line[1:-1])
						#print word
						if word[0] == "PRB":
							CNC.vars["prbx"] = float(word[1])
							CNC.vars["prby"] = float(word[2])
							CNC.vars["prbz"] = float(word[3])
							#if self.running:
							self.gcode.probe.add(
								 CNC.vars["prbx"]-CNC.vars["wcox"],
								 CNC.vars["prby"]-CNC.vars["wcoy"],
								 CNC.vars["prbz"]-CNC.vars["wcoz"])
							self._probeUpdate = True
							CNC.vars[word[0]] = word[1:]
						elif word[0] == "GC":
							CNC.vars["G"] = word[1].split()
							CNC.updateG()
							self._gUpdate = True
						elif word[0] == "TLO":
							CNC.vars[word[0]] = word[1]
							self._probeUpdate = True
						else:
							CNC.vars[word[0]] = word[1:]
					else:
						pat = POSPAT.match(line)
						if pat:
							if pat.group(1) == "PRB":
								CNC.vars["prbx"] = float(pat.group(2))
								CNC.vars["prby"] = float(pat.group(3))
								CNC.vars["prbz"] = float(pat.group(4))
								#if self.running:
								self.gcode.probe.add(
									 CNC.vars["prbx"]
									+CNC.vars["wx"]
									-CNC.vars["mx"],
									 CNC.vars["prby"]
									+CNC.vars["wy"]
									-CNC.vars["my"],
									 CNC.vars["prbz"]
									+CNC.vars["wz"]
									-CNC.vars["mz"])
								self._probeUpdate = True
							CNC.vars[pat.group(1)] = \
								[float(pat.group(2)),
								 float(pat.group(3)),
								 float(pat.group(4))]
						else:
							pat = TLOPAT.match(line)
							if pat:
								CNC.vars[pat.group(1)] = pat.group(2)
								self._probeUpdate = True
							elif DOLLARPAT.match(line):
								CNC.vars["G"] = line[1:-1].split()
								CNC.updateG()
								self._gUpdate = True

				elif "error:" in line or "ALARM:" in line:
					self.log.put((Sender.MSG_ERROR, line))
					self._gcount += 1
					#print "gcount ERROR=",self._gcount
					if cline: del cline[0]
					if sline: CNC.vars["errline"] = sline.pop(0)
					if not self._alarm: self._posUpdate = True
					self._alarm = True
					CNC.vars["state"] = line
					if self.running:
						self._stop = True

				elif line.find("ok")>=0:
					self.log.put((Sender.MSG_OK, line))
					self._gcount += 1
					if cline: del cline[0]
					if sline: del sline[0]
					#print "SLINE:",sline
#					if  self._alarm and not self.running:
#						# turn off alarm for connected status once
#						# a valid gcode event occurs
#						self._alarm = False

				elif line[0] == "$":
					self.log.put((Sender.MSG_RECEIVE, line))
					pat = VARPAT.match(line)
					if pat:
						CNC.vars["grbl_%s"%(pat.group(1))] = pat.group(2)

				elif line[:4]=="Grbl" or line[:13]=="CarbideMotion": # and self.running:
					tg = time.time()
					self.log.put((Sender.MSG_RECEIVE, line))
					self._stop = True
					del cline[:]	# After reset clear the buffer counters
					del sline[:]
					CNC.vars["version"] = line.split()[1]
					# Detect controller
					if self.controller in (Utils.GRBL0, Utils.GRBL1):
						self.controller = int(CNC.vars["version"][0])

				else:
					self.log.put((Sender.MSG_RECEIVE, line))

			# Received external message to stop
			if self._stop:
				self.emptyQueue()
				tosend = None
				self.log.put((Sender.MSG_CLEAR, ""))
				# WARNING if runLines==maxint then it means we are
				# still preparing/sending lines from from bCNC.run(),
				# so don't stop
				if self._runLines != sys.maxint:
					self._stop = False

			#print "tosend='%s'"%(repr(tosend)),"stack=",sline,
			#	"sum=",sum(cline),"wait=",wait,"pause=",self._pause
			if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
				self._sumcline = sum(cline)
#				if isinstance(tosend, list):
#					self.serial.write(str(tosend.pop(0)))
#					if not tosend: tosend = None

				#print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
				if self.controller==Utils.SMOOTHIE: tosend = tosend.upper()
				self.serial.write(bytes(tosend))
				#self.serial.write(tosend.encode("utf8"))
				#self.serial.flush()
				self.log.put((Sender.MSG_BUFFER,tosend))

				tosend = None
				if not self.running and t-tg > G_POLL:
					tosend = b"$G\n"
					sline.append(tosend)
					cline.append(len(tosend))
					tg = t
Esempio n. 12
0
    def serialIO(self):
        cline = []  # length of pipeline commands
        sline = []  # pipeline commands
        wait = False  # wait for commands to complete
        tosend = None  # next string to send
        status = False  # waiting for status <...> report
        tr = tg = time.time()  # last time a ? or $G was send to grbl

        while self.thread:
            t = time.time()

            # refresh machine position?
            if t - tr > SERIAL_POLL:
                self.serial.write(b"?")
                status = True
                tr = t

            # Fetch new command to send if...
            if tosend is None and not wait and not self._pause and self.queue.qsize(
            ) > 0:
                try:
                    tosend = self.queue.get_nowait()
                    #print "+++",repr(tosend)

                    if isinstance(tosend, tuple):
                        #print "gcount tuple=",self._gcount
                        # wait to empty the grbl buffer
                        if tosend[0] == WAIT:
                            # Don't count WAIT until we are idle!
                            wait = True
                            #print "+++ WAIT ON"
                            #print "gcount=",self._gcount, self._runLines
                        elif tosend[0] == MSG:
                            # Count executed commands as well
                            self._gcount += 1
                            if tosend[1] is not None:
                                # show our message on machine status
                                self._msg = tosend[1]
                        elif tosend[0] == UPDATE:
                            # Count executed commands as well
                            self._gcount += 1
                            self._update = tosend[1]
                        else:
                            # Count executed commands as well
                            self._gcount += 1
                        tosend = None

                    elif not isinstance(tosend, str) and not isinstance(
                            tosend, unicode):
                        try:
                            tosend = self.gcode.evaluate(tosend)
                            #							if isinstance(tosend, list):
                            #								cline.append(len(tosend[0]))
                            #								sline.append(tosend[0])
                            if isinstance(tosend, str) or isinstance(
                                    tosend, unicode):
                                tosend += "\n"
                            else:
                                # Count executed commands as well
                                self._gcount += 1
                                #print "gcount str=",self._gcount
                            #print "+++ eval=",repr(tosend),type(tosend)
                        except:
                            for s in str(sys.exc_info()[1]).splitlines():
                                self.log.put((Sender.MSG_ERROR, s))
                            self._gcount += 1
                            tosend = None
                except Empty:
                    break

                if tosend is not None:
                    # All modification in tosend should be
                    # done before adding it to cline
                    if isinstance(tosend, unicode):
                        tosend = tosend.encode("ascii", "replace")

                    #Keep track of last feed
                    pat = FEEDPAT.match(tosend)
                    if pat is not None:
                        self._lastFeed = pat.group(2)

                    #If Override change, attach feed
                    if CNC.vars["overrideChanged"]:
                        CNC.vars["overrideChanged"] = False
                        self._newFeed = float(
                            self._lastFeed) * CNC.vars["override"] / 100.0
                        if pat is None and self._newFeed != 0:
                            tosend = "f%g" % (self._newFeed) + tosend

                    #Apply override Feed
                    if CNC.vars["override"] != 100 and self._newFeed != 0:
                        pat = FEEDPAT.match(tosend)
                        if pat is not None:
                            try:
                                tosend = "%sf%g%s\n" % \
                                 (pat.group(1),
                                  self._newFeed,
                                  pat.group(3))
                            except:
                                pass

                    # Bookkeeping of the buffers
                    sline.append(tosend)
                    cline.append(len(tosend))

            # Anything to receive?
            if self.serial.inWaiting() or tosend is None:
                line = str(self.serial.readline()).strip()
                #print "<R<",repr(line)
                #print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
                if not line:
                    pass

                elif line[0] == "<":
                    if not status:
                        self.log.put((Sender.MSG_RECEIVE, line))

                    elif self.controller == Utils.GRBL1:
                        status = False
                        fields = line[1:-1].split("|")
                        #print fields
                        if not self._alarm:
                            CNC.vars["state"] = fields[0]
                        for field in fields[1:]:
                            word = SPLITPAT.split(field)
                            if word[0] == "MPos":
                                CNC.vars["mx"] = float(word[1])
                                CNC.vars["my"] = float(word[2])
                                CNC.vars["mz"] = float(word[3])
                                CNC.vars["wx"] = round(
                                    CNC.vars["mx"] - CNC.vars["wcox"],
                                    CNC.digits)
                                CNC.vars["wy"] = round(
                                    CNC.vars["my"] - CNC.vars["wcoy"],
                                    CNC.digits)
                                CNC.vars["wz"] = round(
                                    CNC.vars["mz"] - CNC.vars["wcoz"],
                                    CNC.digits)
                                self._posUpdate = True

                            elif word[0] == "F":
                                CNC.vars["curfeed"] = float(word[1])
                            elif word[0] == "Bf":
                                CNC.vars["planner"] = int(word[1])
                                CNC.vars["rxbytes"] = int(word[2])
                            elif word[0] == "Ov":
                                CNC.vars["Ovfeed"] = int(word[1])
                                CNC.vars["Ovrapid"] = int(word[2])
                                CNC.vars["Ovspindle"] = int(word[2])
                            elif word[0] == "WCO":
                                CNC.vars["wcox"] = float(word[1])
                                CNC.vars["wcoy"] = float(word[2])
                                CNC.vars["wcoz"] = float(word[3])

                    else:
                        status = False
                        pat = STATUSPAT.match(line)
                        if pat:
                            if not self._alarm:
                                CNC.vars["state"] = pat.group(1)
                            CNC.vars["mx"] = float(pat.group(2))
                            CNC.vars["my"] = float(pat.group(3))
                            CNC.vars["mz"] = float(pat.group(4))

                            CNC.vars["wx"] = float(pat.group(5))
                            CNC.vars["wy"] = float(pat.group(6))
                            CNC.vars["wz"] = float(pat.group(7))

                            CNC.vars["wcox"] = CNC.vars["mx"] - CNC.vars["wx"]
                            CNC.vars["wcoy"] = CNC.vars["my"] - CNC.vars["wy"]
                            CNC.vars["wcoz"] = CNC.vars["mz"] - CNC.vars["wz"]

                            self._posUpdate = True
                            if pat.group(1) != "Hold" and self._msg:
                                self._msg = None

                            # Machine is Idle buffer is empty
                            # stop waiting and go on
                            #print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
                            #print ">>>", line
                            if wait and not cline and pat.group(1) == "Idle":
                                #print ">>>",line
                                wait = False
                                #print "<<< NO MORE WAIT"
                                self._gcount += 1
                        else:
                            self.log.put((Sender.MSG_RECEIVE, line))

                elif line[0] == "[":
                    self.log.put((Sender.MSG_RECEIVE, line))
                    if self.controller == Utils.GRBL1:
                        word = SPLITPAT.split(line[1:-1])
                        #print word
                        if word[0] == "PRB":
                            CNC.vars["prbx"] = float(word[1])
                            CNC.vars["prby"] = float(word[2])
                            CNC.vars["prbz"] = float(word[3])
                            #if self.running:
                            self.gcode.probe.add(
                                CNC.vars["prbx"] - CNC.vars["wcox"],
                                CNC.vars["prby"] - CNC.vars["wcoy"],
                                CNC.vars["prbz"] - CNC.vars["wcoy"])
                            self._probeUpdate = True
                            CNC.vars[word[0]] = word[1:]
                        elif word[0] == "GC":
                            CNC.vars["G"] = word[1:]
                            CNC.updateG()
                            self._gUpdate = True
                        elif word[0] == "TLO":
                            CNC.vars[word[0]] = word[1]
                            self._probeUpdate = True
                        else:
                            CNC.vars[word[0]] = word[1:]
                    else:
                        pat = POSPAT.match(line)
                        if pat:
                            if pat.group(1) == "PRB":
                                CNC.vars["prbx"] = float(pat.group(2))
                                CNC.vars["prby"] = float(pat.group(3))
                                CNC.vars["prbz"] = float(pat.group(4))
                                #if self.running:
                                self.gcode.probe.add(
                                    CNC.vars["prbx"] + CNC.vars["wx"] -
                                    CNC.vars["mx"], CNC.vars["prby"] +
                                    CNC.vars["wy"] - CNC.vars["my"],
                                    CNC.vars["prbz"] + CNC.vars["wz"] -
                                    CNC.vars["mz"])
                                self._probeUpdate = True
                            CNC.vars[pat.group(1)] = \
                             [float(pat.group(2)),
                              float(pat.group(3)),
                              float(pat.group(4))]
                        else:
                            pat = TLOPAT.match(line)
                            if pat:
                                CNC.vars[pat.group(1)] = pat.group(2)
                                self._probeUpdate = True
                            elif DOLLARPAT.match(line):
                                CNC.vars["G"] = line[1:-1].split()
                                CNC.updateG()
                                self._gUpdate = True

                elif "error:" in line or "ALARM:" in line:
                    self.log.put((Sender.MSG_ERROR, line))
                    self._gcount += 1
                    #print "gcount ERROR=",self._gcount
                    if cline: del cline[0]
                    if sline: CNC.vars["errline"] = sline.pop(0)
                    if not self._alarm: self._posUpdate = True
                    self._alarm = True
                    CNC.vars["state"] = line
                    if self.running:
                        self._stop = True
                        self.runEnded()

                elif line[:4] == "Grbl":  # and self.running:
                    tg = time.time()
                    self.log.put((Sender.MSG_RECEIVE, line))
                    self._stop = True
                    del cline[:]  # After reset clear the buffer counters
                    del sline[:]
                    self.runEnded()
                    CNC.vars["version"] = line.split()[1]
                    # Detect controller
                    if self.controller in (Utils.GRBL0, Utils.GRBL1):
                        self.controller = int(CNC.vars["version"][0])

                elif line.find("ok") >= 0:
                    self.log.put((Sender.MSG_OK, line))
                    self._gcount += 1
                    if cline: del cline[0]
                    if sline: del sline[0]
                    #print "gcount OK=",self._gcount
                    #print "SLINE:",sline
                    if self._alarm and not self.running:
                        # turn off alarm for connected status once
                        # a valid gcode event occurs
                        self._alarm = False

                else:
                    self.log.put((Sender.MSG_RECEIVE, line))

            # Received external message to stop
            if self._stop:
                self.emptyQueue()
                tosend = None
                self.log.put((Sender.MSG_CLEAR, ""))
                # WARNING if maxint then it means we are still preparing/sending
                # lines from from bCNC.run(), so don't stop
                if self._runLines != sys.maxint:
                    self._stop = False

            #print "tosend='%s'"%(repr(tosend)),"stack=",sline,
            #	"sum=",sum(cline),"wait=",wait,"pause=",self._pause
            if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
                self._sumcline = sum(cline)
                #				if isinstance(tosend, list):
                #					self.serial.write(str(tosend.pop(0)))
                #					if not tosend: tosend = None

                #print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
                if self.controller == Utils.SMOOTHIE: tosend = tosend.upper()
                self.serial.write(bytes(tosend))
                #self.serial.write(tosend.encode("utf8"))
                #self.serial.flush()
                self.log.put((Sender.MSG_BUFFER, tosend))

                tosend = None
                if not self.running and t - tg > G_POLL:
                    tosend = b"$G\n"
                    sline.append(tosend)
                    cline.append(len(tosend))
                    tg = t
Esempio n. 13
0
File: Sender.py Progetto: Sci33/bCNC
	def serialIO(self):
		cline = []
		sline = []
		tosend = None
		self.wait = False
		tr = tg = time.time()
		while self.thread:
			t = time.time()
			if t-tr > SERIAL_POLL:
				# Send one ?
				self.serial.write(b"?")
				tr = t

			if tosend is None and not self.wait and not self._pause and self.queue.qsize()>0:
				try:
					tosend = self.queue.get_nowait()

					if isinstance(tosend, tuple):
						# Count commands as well
						self._gcount += 1
						# wait to empty the grbl buffer
						if tosend[0] == WAIT:
							self.wait = True
						elif tosend[0] == PAUSE:
							if tosend[1] is not None:
								self._msg = tosend[1]
							# Feed hold
							self.serial.write(b"!")
						elif tosend[0] == UPDATE:
							self._update = tosend[1]
						tosend = None

					elif not isinstance(tosend, str):
						try:
							tosend = self.gcode.evaluate(tosend)
#							if isinstance(tosend, list):
#								cline.append(len(tosend[0]))
#								sline.append(tosend[0])
#								self.log.put((True,tosend[0]))
							if isinstance(tosend,str):
								tosend += "\n"
							else:
								# Count commands as well
								self._gcount += 1
						except:
							self.log.put((True,sys.exc_info()[1]))
							tosend = None
				except Empty:
					break

				if tosend is not None:
					# All modification in tosend should be
					# done before adding it to cline
					if isinstance(tosend, unicode):
						tosend = tosend.encode("ascii","replace")

					# FIXME should be smarter and apply the feed override
					# also on cards with out feed (the first time only)
					# I should track the feed rate for every card
					# and when it is changed apply a F### command
					# even if it is not there
					if CNC.vars["override"] != 100:
						pat = FEEDPAT.match(tosend)
						if pat is not None:
							try:
								tosend = "%sf%g%s\n" % \
									(pat.group(1),
									 float(pat.group(2))*CNC.vars["override"]/100.0,
									 pat.group(3))
							except:
								pass

					# Bookkeeping of the buffers
					sline.append(tosend)
					cline.append(len(tosend))
					self.log.put((True,tosend))

			# Anything to receive?
			if tosend is None or self.serial.inWaiting():
				line = str(self.serial.readline()).strip()
				if line:
					if line[0]=="<":
						pat = STATUSPAT.match(line)
						if pat:
							if not self._alarm:
								CNC.vars["state"] = pat.group(1)
							CNC.vars["mx"] = float(pat.group(2))
							CNC.vars["my"] = float(pat.group(3))
							CNC.vars["mz"] = float(pat.group(4))
							CNC.vars["wx"] = float(pat.group(5))
							CNC.vars["wy"] = float(pat.group(6))
							CNC.vars["wz"] = float(pat.group(7))
							self._posUpdate = True

							if pat.group(1) != "Hold" and self._msg:
								self._msg = None

							# Machine is Idle buffer is empty
							# stop waiting and go on
							if self.wait and not cline and pat.group(1)=="Idle":
								self.wait = False
						else:
							self.log.put((False, line+"\n"))

					elif line[0]=="[":
						self.log.put((False, line+"\n"))
						pat = POSPAT.match(line)
						if pat:
							if pat.group(1) == "PRB":
								CNC.vars["prbx"] = float(pat.group(2))
								CNC.vars["prby"] = float(pat.group(3))
								CNC.vars["prbz"] = float(pat.group(4))
								if self.running:
									self.gcode.probe.add(
										 float(pat.group(2))
											+CNC.vars["wx"]
											-CNC.vars["mx"],
										 float(pat.group(3))
											+CNC.vars["wy"]
											-CNC.vars["my"],
										 float(pat.group(4))
											+CNC.vars["wz"]
											-CNC.vars["mz"])
								self._probeUpdate = True
							CNC.vars[pat.group(1)] = \
								[float(pat.group(2)),
								 float(pat.group(3)),
								 float(pat.group(4))]
						else:
							pat = TLOPAT.match(line)
							if pat:
								CNC.vars[pat.group(1)] = pat.group(2)
							else:
								CNC.vars["G"] = line[1:-1].split()
								CNC.updateG()
								self._gUpdate = True

					else:
						self.log.put((False, line+"\n"))
						uline = line.upper()
						if uline.find("ERROR")==0 or uline.find("ALARM")==0:
							self._gcount += 1
							if cline: del cline[0]
							if sline: CNC.vars["errline"] = sline.pop(0)
							if not self._alarm: self._posUpdate = True
							self._alarm = True
							CNC.vars["state"] = line
							if self.running:
								self.emptyQueue()
								# Dangerous calling state of Tk if not reentrant
								self.runEnded()
								tosend = None
								del cline[:]
								del sline[:]

						elif line.find("ok")>=0:
							self._gcount += 1
							if cline: del cline[0]
							if sline: del sline[0]

			# Message came to stop
			if self._stop:
				self.emptyQueue()
				tosend = None
				del cline[:]
				del sline[:]
				self._stop = False

			if tosend is not None and sum(cline) <= RX_BUFFER_SIZE-2:
#				if isinstance(tosend, list):
#					self.serial.write(str(tosend.pop(0)))
#					if not tosend: tosend = None

				self.serial.write(bytes(tosend))
				tosend = None
				if not self.running and t-tg > G_POLL:
					tosend = b"$G\n"
					sline.append(tosend)
					cline.append(len(tosend))
					tg = t
Esempio n. 14
0
	def serialIO(self):
		cline  = []		# length of pipeline commands
		sline  = []		# pipeline commands
		wait   = False		# wait for commands to complete
		tosend = None		# next string to send
		status = False		# waiting for status <...> report
		tr = tg = time.time()	# last time a ? or $G was send to grbl

		while self.thread:
			t = time.time()

			# refresh machine position?
			if t-tr > SERIAL_POLL:
				# Send one ?
				self.serial.write(b"?")
				status = True
				#print ">S> ?"
				tr = t

			# Fetch new command to send if...
			if tosend is None and not wait and not self._pause and self.queue.qsize()>0:
				try:
					tosend = self.queue.get_nowait()
					#print "+++",repr(tosend)

					if isinstance(tosend, tuple):
						#print "gcount tuple=",self._gcount
						# wait to empty the grbl buffer
						if tosend[0] == WAIT:
							# Don't count WAIT until we are idle!
							wait = True
							#print "+++ WAIT ON"
							#print "gcount=",self._gcount, self._runLines
						elif tosend[0] == MSG:
							# Count executed commands as well
							self._gcount += 1
							if tosend[1] is not None:
								# show our message on machine status
								self._msg = tosend[1]
						elif tosend[0] == UPDATE:
							# Count executed commands as well
							self._gcount += 1
							self._update = tosend[1]
						else:
							# Count executed commands as well
							self._gcount += 1
						tosend = None

					elif not isinstance(tosend,str) and not isinstance(tosend,unicode):
						try:
							tosend = self.gcode.evaluate(tosend)
#							if isinstance(tosend, list):
#								cline.append(len(tosend[0]))
#								sline.append(tosend[0])
#								self.log.put((True,tosend[0]))
							if isinstance(tosend,str) or isinstance(tosend,unicode):
								tosend += "\n"
							else:
								# Count executed commands as well
								self._gcount += 1
								#print "gcount str=",self._gcount
							#print "+++ eval=",repr(tosend),type(tosend)
						except:
							self.log.put((True,sys.exc_info()[1]))
							tosend = None
				except Empty:
					break

				if tosend is not None:
					# All modification in tosend should be
					# done before adding it to cline
					if isinstance(tosend, unicode):
						tosend = tosend.encode("ascii","replace")

					#Keep track of last feed
					pat = FEEDPAT.match(tosend)
					if pat is not None:
						self._lastFeed = pat.group(2)

					#If Override change, attach feed
					if CNC.vars["overrideChanged"]:
						CNC.vars["overrideChanged"] = False
						self._newFeed = float(self._lastFeed)*CNC.vars["override"]/100.0
						if pat is None and self._newFeed!=0:
							tosend = "f%g" % (self._newFeed) + tosend
							#print tosend

					#Apply override Feed
					if CNC.vars["override"] != 100 and self._newFeed!=0:
						pat = FEEDPAT.match(tosend)
						if pat is not None:
							try:
								tosend = "%sf%g%s\n" % \
									(pat.group(1),
									 self._newFeed,
									 pat.group(3))
							except:
								pass

					# Bookkeeping of the buffers
					sline.append(tosend)
					cline.append(len(tosend))
					self.log.put((True,tosend))

			# Anything to receive?
			if self.serial.inWaiting() or tosend is None:
				line = str(self.serial.readline()).strip()
				#print "<R<",repr(line)
				#print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
				if line:
					if line[0]=="<":
						pat = STATUSPAT.match(line)
						if pat:
							if not status: self.log.put((False, line+"\n"))
							status = False
							if not self._alarm:
								CNC.vars["state"] = pat.group(1)
							CNC.vars["mx"] = float(pat.group(2))
							CNC.vars["my"] = float(pat.group(3))
							CNC.vars["mz"] = float(pat.group(4))
							CNC.vars["wx"] = float(pat.group(5))
							CNC.vars["wy"] = float(pat.group(6))
							CNC.vars["wz"] = float(pat.group(7))
							self._posUpdate = True
							if pat.group(1) != "Hold" and self._msg:
								self._msg = None

							# Machine is Idle buffer is empty
							# stop waiting and go on
							#print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
							#print ">>>", line
							if wait and not cline and pat.group(1)=="Idle":
								#print ">>>",line
								wait = False
								#print "<<< NO MORE WAIT"
								self._gcount += 1
						else:
							self.log.put((False, line+"\n"))

					elif line[0]=="[":
						self.log.put((False, line+"\n"))
						pat = POSPAT.match(line)
						if pat:
							if pat.group(1) == "PRB":
								CNC.vars["prbx"] = float(pat.group(2))
								CNC.vars["prby"] = float(pat.group(3))
								CNC.vars["prbz"] = float(pat.group(4))
								#if self.running:
								self.gcode.probe.add(
									 CNC.vars["prbx"]
									+CNC.vars["wx"]
									-CNC.vars["mx"],

									 CNC.vars["prby"]
									+CNC.vars["wy"]
									-CNC.vars["my"],

									 CNC.vars["prbz"]
									+CNC.vars["wz"]
									-CNC.vars["mz"])
								self._probeUpdate = True
							CNC.vars[pat.group(1)] = \
								[float(pat.group(2)),
								 float(pat.group(3)),
								 float(pat.group(4))]
						else:
							pat = TLOPAT.match(line)
							if pat:
								CNC.vars[pat.group(1)] = pat.group(2)
								self._probeUpdate = True
							elif DOLLARPAT.match(line):
								CNC.vars["G"] = line[1:-1].split()
								CNC.updateG()
								self._gUpdate = True

					else:
						#print "<r<",repr(line)
						self.log.put((False, line+"\n"))
						uline = line.upper()
						if uline.find("ERROR")==0 or uline.find("ALARM")==0:
							self._gcount += 1
							#print "gcount ERROR=",self._gcount
							if cline: del cline[0]
							if sline: CNC.vars["errline"] = sline.pop(0)
							if not self._alarm: self._posUpdate = True
							self._alarm = True
							CNC.vars["state"] = line
							if self.running:
								self._stop = True
								#self.emptyQueue()
								# Dangerous calling state of Tk if not reentrant
								self.runEnded()
								#tosend = None
								#del cline[:]
								#del sline[:]

						elif line.find("ok")>=0:
							self._gcount += 1
							#print "gcount OK=",self._gcount
							if cline: del cline[0]
							if sline: del sline[0]
							#print "SLINE:",sline

			# Received external message to stop
			if self._stop:
				self.emptyQueue()
				tosend = None
				del cline[:]
				del sline[:]
				# WARNING if maxint then it means we are still preparing/sending
				# lines from from bCNC.run(), so don't stop
				if self._runLines != sys.maxint:
					self._stop = False

			#print "tosend='%s'"%(repr(tosend)),"stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
			if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
				self._sumcline = sum(cline)
#				if isinstance(tosend, list):
#					self.serial.write(str(tosend.pop(0)))
#					if not tosend: tosend = None

				#print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
				if self.controller==Utils.SMOOTHIE: tosend = tosend.upper()
				self.serial.write(bytes(tosend))
#				self.serial.write(tosend.encode("utf8"))
#				self.serial.flush()

				tosend = None
				if not self.running and t-tg > G_POLL:
					tosend = b"$G\n"
					sline.append(tosend)
					cline.append(len(tosend))
					tg = t
Esempio n. 15
0
	def serialIO(self):
		cline  = []		# length of pipeline commands
		sline  = []		# pipeline commands
		wait   = False		# wait for commands to complete (status change to Idle)
		tosend = None		# next string to send
		status = False		# waiting for status <...> report
		tr = tg = time.time()	# last time a ? or $G was send to grbl

		while self.thread:
			t = time.time()
			# refresh machine position?
			if t-tr > SERIAL_POLL:
				self.serial.write(b"?")
				status = True
				tr = t

				#If Override change, attach feed
				if CNC.vars["_OvChanged"] and self.controller == Utils.GRBL1:
					CNC.vars["_OvChanged"] = False	# Temporary
					# Check feed
					diff = CNC.vars["_OvFeed"] - CNC.vars["OvFeed"]
					if diff==0:
						pass
					elif CNC.vars["_OvFeed"] == 100:
						self.serial.write(OV_FEED_100)
					elif diff >= 10:
						self.serial.write(OV_FEED_i10)
						CNC.vars["_OvChanged"] = diff>10
					elif diff <= -10:
						self.serial.write(OV_FEED_d10)
						CNC.vars["_OvChanged"] = diff<-10
					elif diff >= 1:
						self.serial.write(OV_FEED_i1)
						CNC.vars["_OvChanged"] = diff>1
					elif diff <= -1:
						self.serial.write(OV_FEED_d1)
						CNC.vars["_OvChanged"] = diff<-1
					# Check rapid
					target  = CNC.vars["_OvRapid"]
					current = CNC.vars["OvRapid"]
					if target == current:
						pass
					elif target == 100:
						self.serial.write(OV_RAPID_100)
					elif target == 75:
						self.serial.write(OV_RAPID_50)	# FIXME
					elif target == 50:
						self.serial.write(OV_RAPID_50)
					elif target == 25:
						self.serial.write(OV_RAPID_25)
					# Check Spindle
					diff = CNC.vars["_OvSpindle"] - CNC.vars["OvSpindle"]
					if diff==0:
						pass
					elif CNC.vars["_OvSpindle"] == 100:
						self.serial.write(OV_SPINDLE_100)
					elif diff >= 10:
						self.serial.write(OV_SPINDLE_i10)
						CNC.vars["_OvChanged"] = diff>10
					elif diff <= -10:
						self.serial.write(OV_SPINDLE_d10)
						CNC.vars["_OvChanged"] = diff<-10
					elif diff >= 1:
						self.serial.write(OV_SPINDLE_i1)
						CNC.vars["_OvChanged"] = diff>1
					elif diff <= -1:
						self.serial.write(OV_SPINDLE_d1)
						CNC.vars["_OvChanged"] = diff<-1

			# Fetch new command to send if...
			if tosend is None and not wait and not self._pause and self.queue.qsize()>0:
				try:
					tosend = self.queue.get_nowait()
					#print "+++",repr(tosend)
					if isinstance(tosend, tuple):
						#print "gcount tuple=",self._gcount
						# wait to empty the grbl buffer and status is Idle
						if tosend[0] == WAIT:
							# Don't count WAIT until we are idle!
							wait = True
							#print "+++ WAIT ON"
							#print "gcount=",self._gcount, self._runLines
						elif tosend[0] == MSG:
							# Count executed commands as well
							self._gcount += 1
							if tosend[1] is not None:
								# show our message on machine status
								self._msg = tosend[1]
						elif tosend[0] == UPDATE:
							# Count executed commands as well
							self._gcount += 1
							self._update = tosend[1]
						else:
							# Count executed commands as well
							self._gcount += 1
						tosend = None

					elif not isinstance(tosend,str) and not isinstance(tosend,unicode):
						try:
							tosend = self.gcode.evaluate(tosend)
#							if isinstance(tosend, list):
#								cline.append(len(tosend[0]))
#								sline.append(tosend[0])
							if isinstance(tosend,str) or isinstance(tosend,unicode):
								tosend += "\n"
							else:
								# Count executed commands as well
								self._gcount += 1
								#print "gcount str=",self._gcount
							#print "+++ eval=",repr(tosend),type(tosend)
						except:
							for s in str(sys.exc_info()[1]).splitlines():
								self.log.put((Sender.MSG_ERROR,s))
							self._gcount += 1
							tosend = None
				except Empty:
					break

				if tosend is not None:
					# All modification in tosend should be
					# done before adding it to cline
					if isinstance(tosend, unicode):
						tosend = tosend.encode("ascii","replace")

					# Keep track of last feed
					pat = FEEDPAT.match(tosend)
					if pat is not None:
						self._lastFeed = pat.group(2)

					if self.controller in (Utils.GRBL0, Utils.SMOOTHIE):
						if CNC.vars["_OvChanged"]:
							CNC.vars["_OvChanged"] = False
							self._newFeed = float(self._lastFeed)*CNC.vars["_OvFeed"]/100.0
							if pat is None and self._newFeed!=0 \
							   and not tosend.startswith("$"):
								tosend = "f%g%s" % (self._newFeed, tosend)

						# Apply override Feed
						if CNC.vars["_OvFeed"] != 100 and self._newFeed != 0:
							pat = FEEDPAT.match(tosend)
							if pat is not None:
								try:
									tosend = "%sf%g%s\n" % \
										(pat.group(1),
										 self._newFeed,
										 pat.group(3))
								except:
									pass

					# Bookkeeping of the buffers
					sline.append(tosend)
					cline.append(len(tosend))

			# Anything to receive?
			if self.serial.inWaiting() or tosend is None:
				try:
					line = str(self.serial.readline()).strip()
				except:
					self.log.put((Sender.MSG_RECEIVE, str(sys.exc_info()[1])))
					self.emptyQueue()
					self.close()
					return

				#print "<R<",repr(line)
				#print "*-* stack=",sline,"sum=",sum(cline),"wait=",wait,"pause=",self._pause
				if not line:
					pass

				elif line[0]=="<":
					if not status:
						self.log.put((Sender.MSG_RECEIVE, line))

					elif self.controller == Utils.GRBL1:
						status = False
						fields = line[1:-1].split("|")
						if not self._alarm:
							CNC.vars["state"] = fields[0]
						for field in fields[1:]:
							word = SPLITPAT.split(field)
							if word[0] == "MPos":
								try:
									CNC.vars["mx"] = float(word[1])
									CNC.vars["my"] = float(word[2])
									CNC.vars["mz"] = float(word[3])
									CNC.vars["wx"] = round(CNC.vars["mx"]-CNC.vars["wcox"], CNC.digits)
									CNC.vars["wy"] = round(CNC.vars["my"]-CNC.vars["wcoy"], CNC.digits)
									CNC.vars["wz"] = round(CNC.vars["mz"]-CNC.vars["wcoz"], CNC.digits)
									self._posUpdate = True
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "F":
								try:
									CNC.vars["curfeed"] = float(word[1])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "FS":
								try:
									CNC.vars["curfeed"]    = float(word[1])
									CNC.vars["curspindle"] = float(word[2])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "Bf":
								try:
									CNC.vars["planner"] = int(word[1])
									CNC.vars["rxbytes"] = int(word[2])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "Ov":
								try:
									CNC.vars["OvFeed"]    = int(word[1])
									CNC.vars["OvRapid"]   = int(word[2])
									CNC.vars["OvSpindle"] = int(word[3])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break
							elif word[0] == "WCO":
								try:
									CNC.vars["wcox"] = float(word[1])
									CNC.vars["wcoy"] = float(word[2])
									CNC.vars["wcoz"] = float(word[3])
								except (ValueError,IndexError):
									CNC.vars["state"] = "Garbage receive %s: %s"%(word[0],line)
									self.log.put((Sender.MSG_RECEIVE, CNC.vars["state"]))
									break

						# Machine is Idle buffer is empty stop waiting and go on
						if wait and not cline and fields[0] in ("Idle","Check"):
							wait = False
							self._gcount += 1

					elif self.controller == Utils.SMOOTHIE:
							# <Idle|MPos:68.9980,-49.9240,40.0000,12.3456|WPos:68.9980,-49.9240,40.0000|F:12345.12|S:1.2>
							ln= line[1:-1] # strip off < .. >

							# split fields
							l= ln.split('|')

							# strip off status
							CNC.vars["state"]= l[0]

							# strip of rest into a dict of name: [values,...,]
							d= { a: [float(y) for y in b.split(',')] for a, b in [x.split(':') for x in l[1:]] }
							CNC.vars["mx"] = float(d['MPos'][0])
							CNC.vars["my"] = float(d['MPos'][1])
							CNC.vars["mz"] = float(d['MPos'][2])
							CNC.vars["wx"] = float(d['WPos'][0])
							CNC.vars["wy"] = float(d['WPos'][1])
							CNC.vars["wz"] = float(d['WPos'][2])
							CNC.vars["wcox"] = CNC.vars["mx"] - CNC.vars["wx"]
							CNC.vars["wcoy"] = CNC.vars["my"] - CNC.vars["wy"]
							CNC.vars["wcoz"] = CNC.vars["mz"] - CNC.vars["wz"]
							if 'F' in d:
							        CNC.vars["curfeed"] = float(d['F'][0])
							self._posUpdate = True

							# Machine is Idle buffer is empty
							# stop waiting and go on
							if wait and not cline and l[0] in ("Idle","Check"):
							        wait = False
							        self._gcount += 1

					else:
						status = False
						pat = STATUSPAT.match(line)
						if pat:
							if not self._alarm:
								CNC.vars["state"] = pat.group(1)
							CNC.vars["mx"] = float(pat.group(2))
							CNC.vars["my"] = float(pat.group(3))
							CNC.vars["mz"] = float(pat.group(4))
							CNC.vars["wx"] = float(pat.group(5))
							CNC.vars["wy"] = float(pat.group(6))
							CNC.vars["wz"] = float(pat.group(7))
							CNC.vars["wcox"] = CNC.vars["mx"] - CNC.vars["wx"]
							CNC.vars["wcoy"] = CNC.vars["my"] - CNC.vars["wy"]
							CNC.vars["wcoz"] = CNC.vars["mz"] - CNC.vars["wz"]
							self._posUpdate = True
							if pat.group(1)[:4] != "Hold" and self._msg:
								self._msg = None

							# Machine is Idle buffer is empty
							# stop waiting and go on
							#print "<<< WAIT=",wait,sline,pat.group(1),sum(cline)
							#print ">>>", line
							if wait and not cline and pat.group(1) in ("Idle","Check"):
								#print ">>>",line
								wait = False
								#print "<<< NO MORE WAIT"
								self._gcount += 1
						else:
							self.log.put((Sender.MSG_RECEIVE, line))

				elif line[0]=="[":
					self.log.put((Sender.MSG_RECEIVE, line))
					if self.controller == Utils.GRBL1:
						word = SPLITPAT.split(line[1:-1])
						#print word
						if word[0] == "PRB":
							CNC.vars["prbx"] = float(word[1])
							CNC.vars["prby"] = float(word[2])
							CNC.vars["prbz"] = float(word[3])
							#if self.running:
							self.gcode.probe.add(
								 CNC.vars["prbx"]-CNC.vars["wcox"],
								 CNC.vars["prby"]-CNC.vars["wcoy"],
								 CNC.vars["prbz"]-CNC.vars["wcoz"])
							self._probeUpdate = True
							CNC.vars[word[0]] = word[1:]
						elif word[0] == "GC":
							CNC.vars["G"] = word[1].split()
							CNC.updateG()
							self._gUpdate = True
						elif word[0] == "TLO":
							CNC.vars[word[0]] = word[1]
							self._probeUpdate = True
						else:
							CNC.vars[word[0]] = word[1:]
					else:
						pat = POSPAT.match(line)
						if pat:
							if pat.group(1) == "PRB":
								CNC.vars["prbx"] = float(pat.group(2))
								CNC.vars["prby"] = float(pat.group(3))
								CNC.vars["prbz"] = float(pat.group(4))
								#if self.running:
								self.gcode.probe.add(
									 CNC.vars["prbx"]
									+CNC.vars["wx"]
									-CNC.vars["mx"],
									 CNC.vars["prby"]
									+CNC.vars["wy"]
									-CNC.vars["my"],
									 CNC.vars["prbz"]
									+CNC.vars["wz"]
									-CNC.vars["mz"])
								self._probeUpdate = True
							CNC.vars[pat.group(1)] = \
								[float(pat.group(2)),
								 float(pat.group(3)),
								 float(pat.group(4))]
						else:
							pat = TLOPAT.match(line)
							if pat:
								CNC.vars[pat.group(1)] = pat.group(2)
								self._probeUpdate = True
							elif DOLLARPAT.match(line):
								CNC.vars["G"] = line[1:-1].split()
								CNC.updateG()
								self._gUpdate = True

				elif "error:" in line or "ALARM:" in line:
					self.log.put((Sender.MSG_ERROR, line))
					self._gcount += 1
					#print "gcount ERROR=",self._gcount
					if cline: del cline[0]
					if sline: CNC.vars["errline"] = sline.pop(0)
					if not self._alarm: self._posUpdate = True
					self._alarm = True
					CNC.vars["state"] = line
					if self.running:
						self._stop = True

				elif line.find("ok")>=0:
					self.log.put((Sender.MSG_OK, line))
					self._gcount += 1
					if cline: del cline[0]
					if sline: del sline[0]
					#print "SLINE:",sline
#					if  self._alarm and not self.running:
#						# turn off alarm for connected status once
#						# a valid gcode event occurs
#						self._alarm = False

				elif line[0] == "$":
					self.log.put((Sender.MSG_RECEIVE, line))
					pat = VARPAT.match(line)
					if pat:
						CNC.vars["grbl_%s"%(pat.group(1))] = pat.group(2)

				elif line[:4]=="Grbl" or line[:13]=="CarbideMotion": # and self.running:
					tg = time.time()
					self.log.put((Sender.MSG_RECEIVE, line))
					self._stop = True
					del cline[:]	# After reset clear the buffer counters
					del sline[:]
					CNC.vars["version"] = line.split()[1]
					# Detect controller
					if self.controller in (Utils.GRBL0, Utils.GRBL1):
						self.controller = int(CNC.vars["version"][0])

				else:
					self.log.put((Sender.MSG_RECEIVE, line))

			# Received external message to stop
			if self._stop:
				self.emptyQueue()
				tosend = None
				self.log.put((Sender.MSG_CLEAR, ""))
				# WARNING if runLines==maxint then it means we are
				# still preparing/sending lines from from bCNC.run(),
				# so don't stop
				if self._runLines != sys.maxint:
					self._stop = False

			#print "tosend='%s'"%(repr(tosend)),"stack=",sline,
			#	"sum=",sum(cline),"wait=",wait,"pause=",self._pause
			if tosend is not None and sum(cline) < RX_BUFFER_SIZE:
				self._sumcline = sum(cline)
#				if isinstance(tosend, list):
#					self.serial.write(str(tosend.pop(0)))
#					if not tosend: tosend = None

				#print ">S>",repr(tosend),"stack=",sline,"sum=",sum(cline)
				if self.controller==Utils.SMOOTHIE: tosend = tosend.upper()
				self.serial.write(bytes(tosend))
				#self.serial.write(tosend.encode("utf8"))
				#self.serial.flush()
				self.log.put((Sender.MSG_BUFFER,tosend))

				tosend = None
				if not self.running and t-tg > G_POLL:
					tosend = b"$G\n"
					sline.append(tosend)
					cline.append(len(tosend))
					tg = t