Open the serial port in the thread, so it no longer blocks the GUI during auto-detection. Add a 10 second write timeout, so we no longer get timeouts under windows. Remove the M109/M190 heatup wait time from the total printing time.

master
daid303 2012-10-02 10:58:57 +02:00
parent b9a80ba0fa
commit e49bc2c77f
4 changed files with 107 additions and 65 deletions

View File

@ -15,7 +15,7 @@ class Stk500v2(ispBase.IspBase):
if self.serial != None:
self.close()
try:
self.serial = Serial(port, speed, timeout=1)
self.serial = Serial(port, speed, timeout=1, writeTimeout=10000)
except SerialException as e:
raise ispBase.IspError("Failed to open serial port")
except:

View File

@ -328,7 +328,7 @@ class printWindow(wx.Frame):
self.cancelButton.Enable(self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused()))
self.temperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational())
self.bedTemperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational())
self.directControlPanel.Enable(self.machineCom != None and self.machineCom.isOperational())
self.directControlPanel.Enable(self.machineCom != None and self.machineCom.isOperational() and not self.machineCom.isPrinting())
self.machineLogButton.Show(self.machineCom != None and self.machineCom.isError())
def UpdateProgress(self):
@ -349,8 +349,9 @@ class printWindow(wx.Frame):
printTime = self.machineCom.getPrintTime() / 60
printTimeTotal = printTime * len(self.gcodeList) / self.machineCom.getPrintPos()
printTimeLeft = printTimeTotal - printTime
status += 'Line: %d/%d\n' % (self.machineCom.getPrintPos(), len(self.gcodeList))
status += 'Height: %f\n' % (self.currentZ)
status += 'Line: %d/%d %d%%\n' % (self.machineCom.getPrintPos(), len(self.gcodeList), self.machineCom.getPrintPos() * 100 / len(self.gcodeList))
if self.currentZ > 0:
status += 'Height: %0.1f\n' % (self.currentZ)
status += 'Print time: %02d:%02d\n' % (int(printTime / 60), int(printTime % 60))
status += 'Print time left: %02d:%02d\n' % (int(printTimeLeft / 60), int(printTimeLeft % 60))
self.progress.SetValue(self.machineCom.getPrintPos())
@ -558,11 +559,6 @@ class temperatureGraph(wx.Panel):
dc.SelectObject(self.backBuffer)
dc.Clear()
w, h = self.GetSizeTuple()
x0 = 0
t0 = 0
bt0 = 0
tSP0 = 0
btSP0 = 0
bgLinePen = wx.Pen('#A0A0A0')
tempPen = wx.Pen('#FF4040')
tempSPPen = wx.Pen('#FFA0A0')
@ -570,6 +566,28 @@ class temperatureGraph(wx.Panel):
bedTempPen = wx.Pen('#4040FF')
bedTempSPPen = wx.Pen('#A0A0FF')
bedTempPenBG = wx.Pen('#D0D0FF')
x0 = 0
t0 = 0
bt0 = 0
tSP0 = 0
btSP0 = 0
for temp, tempSP, bedTemp, bedTempSP, t in self.points:
x1 = int(w - (now - t))
for x in xrange(x0, x1 + 1):
t = float(x - x0) / float(x1 - x0 + 1) * (temp - t0) + t0
bt = float(x - x0) / float(x1 - x0 + 1) * (bedTemp - bt0) + bt0
dc.SetPen(tempPenBG)
dc.DrawLine(x, h, x, h - (t * h / 300))
dc.SetPen(bedTempPenBG)
dc.DrawLine(x, h, x, h - (bt * h / 300))
t0 = temp
bt0 = bedTemp
tSP0 = tempSP
btSP0 = bedTempSP
x0 = x1 + 1
#Draw the grid
for x in xrange(w, 0, -30):
dc.SetPen(bgLinePen)
dc.DrawLine(x, 0, x, h)
@ -579,6 +597,11 @@ class temperatureGraph(wx.Panel):
dc.DrawLine(0, 0, w, 0)
dc.DrawLine(0, 0, 0, h)
x0 = 0
t0 = 0
bt0 = 0
tSP0 = 0
btSP0 = 0
for temp, tempSP, bedTemp, bedTempSP, t in self.points:
x1 = int(w - (now - t))
for x in xrange(x0, x1 + 1):
@ -586,10 +609,6 @@ class temperatureGraph(wx.Panel):
bt = float(x - x0) / float(x1 - x0 + 1) * (bedTemp - bt0) + bt0
tSP = float(x - x0) / float(x1 - x0 + 1) * (tempSP - tSP0) + tSP0
btSP = float(x - x0) / float(x1 - x0 + 1) * (bedTempSP - btSP0) + btSP0
dc.SetPen(tempPenBG)
dc.DrawLine(x, h, x, h - (t * h / 300))
dc.SetPen(bedTempPenBG)
dc.DrawLine(x, h, x, h - (bt * h / 300))
dc.SetPen(tempSPPen)
dc.DrawPoint(x, h - (tSP * h / 300))
dc.SetPen(bedTempSPPen)

View File

@ -176,7 +176,7 @@ class simpleModeWindow(configBase.configWindowBase):
put('skirt_line_count', '1')
put('skirt_gap', '6.0')
put('print_speed', '50')
put('print_temperature', '230')
put('print_temperature', '220')
put('support', 'None')
#put('machine_center_x', '100')
#put('machine_center_y', '100')
@ -229,7 +229,7 @@ class simpleModeWindow(configBase.configWindowBase):
put('print_speed', '80')
put('bottom_layer_speed', '40')
elif self.printTypeHigh.GetValue():
put('wall_thickness', nozzle_size * 3.0)
put('wall_thickness', nozzle_size * 2.0)
put('layer_height', '0.1')
put('fill_density', '30')
put('bottom_layer_speed', '15')

View File

@ -120,14 +120,16 @@ class MachineComPrintCallback(object):
class MachineCom(object):
STATE_NONE = 0
STATE_DETECT_BAUDRATE = 1
STATE_CONNECTING = 2
STATE_OPERATIONAL = 3
STATE_PRINTING = 4
STATE_PAUSED = 5
STATE_CLOSED = 6
STATE_ERROR = 7
STATE_CLOSED_WITH_ERROR = 8
STATE_OPEN_SERIAL = 1
STATE_DETECT_SERIAL = 2
STATE_DETECT_BAUDRATE = 3
STATE_CONNECTING = 4
STATE_OPERATIONAL = 5
STATE_PRINTING = 6
STATE_PAUSED = 7
STATE_CLOSED = 8
STATE_ERROR = 9
STATE_CLOSED_WITH_ERROR = 10
def __init__(self, port = None, baudrate = None, callbackObject = None):
if port == None:
@ -140,6 +142,8 @@ class MachineCom(object):
if callbackObject == None:
callbackObject = MachineComPrintCallback()
self._port = port
self._baudrate = baudrate
self._callback = callbackObject
self._state = self.STATE_NONE
self._serial = None
@ -153,44 +157,9 @@ class MachineCom(object):
self._logQueue = queue.Queue(256)
self._feedRateModifier = {}
self._currentZ = -1
self._heatupWaitStartTime = 0
self._heatupWaitTimeLost = 0.0
if port == 'AUTO':
programmer = stk500v2.Stk500v2()
self._log("Serial port list: %s" % (str(serialList())))
for p in serialList():
try:
self._log("Connecting to: %s" % (p))
programmer.connect(p)
self._serial = programmer.leaveISP()
profile.putPreference('serial_port_auto', p)
break
except ispBase.IspError as (e):
self._log("Error while connecting to %s: %s" % (p, str(e)))
pass
except:
self._log("Unexpected error while connecting to serial port: %s %s" % (p, getExceptionString()))
programmer.close()
elif port == 'VIRTUAL':
self._serial = VirtualPrinter()
else:
try:
self._log("Connecting to: %s" % (port))
if baudrate == 0:
self._serial = Serial(port, 115200, timeout=0.1)
else:
self._serial = Serial(port, baudrate, timeout=2)
except:
self._log("Unexpected error while connecting to serial port: %s %s" % (port, getExceptionString()))
if self._serial == None:
self._log("Failed to open serial port (%s)" % (port))
self._errorValue = 'Failed to autodetect serial port.'
self._changeState(self.STATE_ERROR)
return
self._log("Connected to: %s, starting monitor" % (self._serial))
if baudrate == 0:
self._changeState(self.STATE_DETECT_BAUDRATE)
else:
self._changeState(self.STATE_CONNECTING)
self.thread = threading.Thread(target=self._monitor)
self.thread.daemon = True
self.thread.start()
@ -209,8 +178,12 @@ class MachineCom(object):
def getStateString(self):
if self._state == self.STATE_NONE:
return "Offline"
if self._state == self.STATE_OPEN_SERIAL:
return "Opening serial port"
if self._state == self.STATE_DETECT_SERIAL:
return "Detecting serial port"
if self._state == self.STATE_DETECT_BAUDRATE:
return "Detect baudrate"
return "Detecting baudrate"
if self._state == self.STATE_CONNECTING:
return "Connecting"
if self._state == self.STATE_OPERATIONAL:
@ -243,7 +216,7 @@ class MachineCom(object):
return self._gcodePos
def getPrintTime(self):
return time.time() - self._printStartTime
return time.time() - self._printStartTime - self._heatupWaitTimeLost
def isPaused(self):
return self._state == self.STATE_PAUSED
@ -263,6 +236,49 @@ class MachineCom(object):
return ret
def _monitor(self):
#Open the serial port.
if self._port == 'AUTO':
self._changeState(self.STATE_DETECT_SERIAL)
programmer = stk500v2.Stk500v2()
self._log("Serial port list: %s" % (str(serialList())))
for p in serialList():
try:
self._log("Connecting to: %s" % (p))
programmer.connect(p)
self._serial = programmer.leaveISP()
profile.putPreference('serial_port_auto', p)
break
except ispBase.IspError as (e):
self._log("Error while connecting to %s: %s" % (p, str(e)))
pass
except:
self._log("Unexpected error while connecting to serial port: %s %s" % (p, getExceptionString()))
programmer.close()
elif self._port == 'VIRTUAL':
self._changeState(self.STATE_OPEN_SERIAL)
self._serial = VirtualPrinter()
else:
self._changeState(self.STATE_OPEN_SERIAL)
try:
self._log("Connecting to: %s" % (self._port))
if self._baudrate == 0:
self._serial = Serial(self._port, 115200, timeout=0.1, writeTimeout=10000)
else:
self._serial = Serial(self._port, self._baudrate, timeout=2, writeTimeout=10000)
except:
self._log("Unexpected error while connecting to serial port: %s %s" % (self._port, getExceptionString()))
if self._serial == None:
self._log("Failed to open serial port (%s)" % (self._port))
self._errorValue = 'Failed to autodetect serial port.'
self._changeState(self.STATE_ERROR)
return
self._log("Connected to: %s, starting monitor" % (self._serial))
if self._baudrate == 0:
self._changeState(self.STATE_DETECT_BAUDRATE)
else:
self._changeState(self.STATE_CONNECTING)
#Start monitoring the serial port.
timeout = time.time() + 5
tempRequestTimeout = timeout
while True:
@ -280,12 +296,17 @@ class MachineCom(object):
line = line.rstrip() + self._readline()
self._errorValue = line
self._changeState(self.STATE_ERROR)
if ' T:' in line:
self._temp = float(re.search("[0-9\.]*", line.split(' T:')[1]).group(0))
if ' T:' in line or line.startswith('T:'):
self._temp = float(re.search("[0-9\.]*", line.split('T:')[1]).group(0))
if ' B:' in line:
self._bedTemp = float(re.search("[0-9\.]*", line.split(' B:')[1]).group(0))
self._callback.mcTempUpdate(self._temp, self._bedTemp)
elif line.strip() != 'ok':
#If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
if not 'ok' in line and self._heatupWaitStartTime != 0:
t = time.time()
self._heatupWaitTimeLost = t - self._heatupWaitStartTime
self._heatupWaitStartTime = t
elif line.strip() != 'ok' and self.isOperational():
self._callback.mcMessage(line)
if self._state == self.STATE_DETECT_BAUDRATE:
@ -387,6 +408,8 @@ class MachineCom(object):
def _sendCommand(self, cmd):
if self._serial == None:
return
if 'M109' in cmd or 'M190' in cmd:
self._heatupWaitStartTime = time.time()
self._log('Send: %s' % (cmd))
try:
#TODO: This can throw a write timeout exception, but we do not want timeout on writes. Find a fix for this.