chiark / gitweb /
Open the serial port in the thread, so it no longer blocks the GUI during auto-detect...
authordaid303 <daid303@gmail.com>
Tue, 2 Oct 2012 08:58:57 +0000 (10:58 +0200)
committerdaid303 <daid303@gmail.com>
Tue, 2 Oct 2012 08:58:57 +0000 (10:58 +0200)
Cura/avr_isp/stk500v2.py
Cura/gui/printWindow.py
Cura/gui/simpleMode.py
Cura/util/machineCom.py

index bfdcb4e48f0a31673662bdb7e4401c90dab0f4c3..245db8e4df6e1cf20c125e0979f722a3740b3c7f 100644 (file)
@@ -15,7 +15,7 @@ class Stk500v2(ispBase.IspBase):
                if self.serial != None:\r
                        self.close()\r
                try:\r
-                       self.serial = Serial(port, speed, timeout=1)\r
+                       self.serial = Serial(port, speed, timeout=1, writeTimeout=10000)\r
                except SerialException as e:\r
                        raise ispBase.IspError("Failed to open serial port")\r
                except:\r
index 83642b18dc4a81221ba72bfed01d31f2cb6532bf..9cf502893f95e73a5d3b0eeff6870987409eaca2 100644 (file)
@@ -328,7 +328,7 @@ class printWindow(wx.Frame):
                self.cancelButton.Enable(self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused()))\r
                self.temperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational())\r
                self.bedTemperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational())\r
-               self.directControlPanel.Enable(self.machineCom != None and self.machineCom.isOperational())\r
+               self.directControlPanel.Enable(self.machineCom != None and self.machineCom.isOperational() and not self.machineCom.isPrinting())\r
                self.machineLogButton.Show(self.machineCom != None and self.machineCom.isError())\r
        \r
        def UpdateProgress(self):\r
@@ -349,8 +349,9 @@ class printWindow(wx.Frame):
                        printTime = self.machineCom.getPrintTime() / 60\r
                        printTimeTotal = printTime * len(self.gcodeList) / self.machineCom.getPrintPos()\r
                        printTimeLeft = printTimeTotal - printTime\r
-                       status += 'Line: %d/%d\n' % (self.machineCom.getPrintPos(), len(self.gcodeList))\r
-                       status += 'Height: %f\n' % (self.currentZ)\r
+                       status += 'Line: %d/%d %d%%\n' % (self.machineCom.getPrintPos(), len(self.gcodeList), self.machineCom.getPrintPos() * 100 / len(self.gcodeList))\r
+                       if self.currentZ > 0:\r
+                               status += 'Height: %0.1f\n' % (self.currentZ)\r
                        status += 'Print time: %02d:%02d\n' % (int(printTime / 60), int(printTime % 60))\r
                        status += 'Print time left: %02d:%02d\n' % (int(printTimeLeft / 60), int(printTimeLeft % 60))\r
                        self.progress.SetValue(self.machineCom.getPrintPos())\r
@@ -558,11 +559,6 @@ class temperatureGraph(wx.Panel):
                dc.SelectObject(self.backBuffer)\r
                dc.Clear()\r
                w, h = self.GetSizeTuple()\r
-               x0 = 0\r
-               t0 = 0\r
-               bt0 = 0\r
-               tSP0 = 0\r
-               btSP0 = 0\r
                bgLinePen = wx.Pen('#A0A0A0')\r
                tempPen = wx.Pen('#FF4040')\r
                tempSPPen = wx.Pen('#FFA0A0')\r
@@ -570,6 +566,28 @@ class temperatureGraph(wx.Panel):
                bedTempPen = wx.Pen('#4040FF')\r
                bedTempSPPen = wx.Pen('#A0A0FF')\r
                bedTempPenBG = wx.Pen('#D0D0FF')\r
+\r
+               x0 = 0\r
+               t0 = 0\r
+               bt0 = 0\r
+               tSP0 = 0\r
+               btSP0 = 0\r
+               for temp, tempSP, bedTemp, bedTempSP, t in self.points:\r
+                       x1 = int(w - (now - t))\r
+                       for x in xrange(x0, x1 + 1):\r
+                               t = float(x - x0) / float(x1 - x0 + 1) * (temp - t0) + t0\r
+                               bt = float(x - x0) / float(x1 - x0 + 1) * (bedTemp - bt0) + bt0\r
+                               dc.SetPen(tempPenBG)\r
+                               dc.DrawLine(x, h, x, h - (t * h / 300))\r
+                               dc.SetPen(bedTempPenBG)\r
+                               dc.DrawLine(x, h, x, h - (bt * h / 300))\r
+                       t0 = temp\r
+                       bt0 = bedTemp\r
+                       tSP0 = tempSP\r
+                       btSP0 = bedTempSP\r
+                       x0 = x1 + 1\r
+\r
+               #Draw the grid\r
                for x in xrange(w, 0, -30):\r
                        dc.SetPen(bgLinePen)\r
                        dc.DrawLine(x, 0, x, h)\r
@@ -579,6 +597,11 @@ class temperatureGraph(wx.Panel):
                dc.DrawLine(0, 0, w, 0)\r
                dc.DrawLine(0, 0, 0, h)\r
                \r
+               x0 = 0\r
+               t0 = 0\r
+               bt0 = 0\r
+               tSP0 = 0\r
+               btSP0 = 0\r
                for temp, tempSP, bedTemp, bedTempSP, t in self.points:\r
                        x1 = int(w - (now - t))\r
                        for x in xrange(x0, x1 + 1):\r
@@ -586,10 +609,6 @@ class temperatureGraph(wx.Panel):
                                bt = float(x - x0) / float(x1 - x0 + 1) * (bedTemp - bt0) + bt0\r
                                tSP = float(x - x0) / float(x1 - x0 + 1) * (tempSP - tSP0) + tSP0\r
                                btSP = float(x - x0) / float(x1 - x0 + 1) * (bedTempSP - btSP0) + btSP0\r
-                               dc.SetPen(tempPenBG)\r
-                               dc.DrawLine(x, h, x, h - (t * h / 300))\r
-                               dc.SetPen(bedTempPenBG)\r
-                               dc.DrawLine(x, h, x, h - (bt * h / 300))\r
                                dc.SetPen(tempSPPen)\r
                                dc.DrawPoint(x, h - (tSP * h / 300))\r
                                dc.SetPen(bedTempSPPen)\r
index c9890748a0bb3cc3257535f8b0b071f858918675..acabd652cc96d36b1faef80d0f4f1a2d32194344 100644 (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')
index 2be74533084bc494271f387742da0d0612a2ca95..521804e530b5d62834c2a3ed4c69049308cc2423 100644 (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.