chiark / gitweb /
Add temperature graph to printer interface.
authordaid <daid303@gmail.com>
Tue, 10 Jul 2012 15:04:37 +0000 (17:04 +0200)
committerdaid <daid303@gmail.com>
Tue, 10 Jul 2012 15:04:37 +0000 (17:04 +0200)
Cura/gui/printWindow.py
Cura/util/machineCom.py

index ad6b9c2e56bda10e11a3300ac7ed954c3957c8ad..94d8fc0d1827e187ba7e0dfba77c6109cc38bb56 100644 (file)
@@ -1,7 +1,7 @@
 from __future__ import absolute_import\r
 import __init__\r
 \r
-import wx, threading, re, subprocess, sys, os\r
+import wx, threading, re, subprocess, sys, os, time\r
 from wx.lib import buttons\r
 \r
 from gui import icon\r
@@ -140,10 +140,15 @@ class printWindow(wx.Frame):
                self.bedTemperatureLabel.Show(False)\r
                self.bedTemperatureSelect.Show(False)\r
                \r
+               self.temperatureGraph = temperatureGraph(self.temperaturePanel)\r
+               \r
                sizer.Add(wx.StaticText(self.temperaturePanel, -1, "Temp:"), pos=(0,0))\r
                sizer.Add(self.temperatureSelect, pos=(0,1))\r
                sizer.Add(self.bedTemperatureLabel, pos=(1,0))\r
                sizer.Add(self.bedTemperatureSelect, pos=(1,1))\r
+               sizer.Add(self.temperatureGraph, pos=(2,0), span=(1,2), flag=wx.EXPAND)\r
+               sizer.AddGrowableRow(2)\r
+               sizer.AddGrowableCol(0)\r
 \r
                nb.AddPage(self.temperaturePanel, 'Temp')\r
 \r
@@ -289,7 +294,7 @@ class printWindow(wx.Frame):
                        self.bedTemperatureSelect.Show(True)\r
                        self.temperaturePanel.Layout()\r
                self.statsText.SetLabel(status.strip())\r
-               self.Layout()\r
+               #self.Layout()\r
        \r
        def OnConnect(self, e):\r
                if self.machineCom != None:\r
@@ -417,17 +422,26 @@ class printWindow(wx.Frame):
                if lineNr >= len(self.gcodeList):\r
                        return False\r
                line = self.gcodeList[lineNr]\r
-               if line == 'M0' or line == 'M1':\r
-                       self.OnPause(None)\r
-                       line = 'M105'\r
-               if self.typeList[lineNr] == 'WALL-OUTER':\r
-                       line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioOuterWall)), line)\r
-               if self.typeList[lineNr] == 'WALL-INNER':\r
-                       line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioInnerWall)), line)\r
-               if self.typeList[lineNr] == 'FILL':\r
-                       line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioFill)), line)\r
-               if self.typeList[lineNr] == 'SUPPORT':\r
-                       line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioSupport)), line)\r
+               try:\r
+                       if line == 'M0' or line == 'M1':\r
+                               self.OnPause(None)\r
+                               line = 'M105'\r
+                       if ('M104' in line or 'M109' in line) and 'S' in line:\r
+                               n = int(re.search('S([0-9]*)', line).group(1))\r
+                               wx.CallAfter(self.temperatureSelect.SetValue, n)\r
+                       if ('M140' in line or 'M190' in line) and 'S' in line:\r
+                               n = int(re.search('S([0-9]*)', line).group(1))\r
+                               wx.CallAfter(self.bedTemperatureSelect.SetValue, n)\r
+                       if self.typeList[lineNr] == 'WALL-OUTER':\r
+                               line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioOuterWall)), line)\r
+                       if self.typeList[lineNr] == 'WALL-INNER':\r
+                               line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioInnerWall)), line)\r
+                       if self.typeList[lineNr] == 'FILL':\r
+                               line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioFill)), line)\r
+                       if self.typeList[lineNr] == 'SUPPORT':\r
+                               line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioSupport)), line)\r
+               except:\r
+                       print "Unexpected error:", sys.exc_info()\r
                checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (lineNr, line)))\r
                self.machineCom.sendCommand("N%d%s*%d" % (lineNr, line, checksum))\r
                return True\r
@@ -442,6 +456,9 @@ class printWindow(wx.Frame):
                        if line == '':  #When we have a communication "timeout" and we're not sending gcode, then read the temperature.\r
                                if self.printIdx == None or self.pause:\r
                                        self.machineCom.sendCommand("M105")\r
+                               else:\r
+                                       wx.CallAfter(self.AddTermLog, '!!Comm timeout, forcing next line!!\n')\r
+                                       line = 'ok'\r
                        if self.machineConnected:\r
                                while self.sendCnt > 0 and not self.pause:\r
                                        self.sendLine(self.printIdx)\r
@@ -454,6 +471,7 @@ class printWindow(wx.Frame):
                                self.temp = float(re.search("[0-9\.]*", line.split('T:')[1]).group(0))\r
                                if 'B:' in line:\r
                                        self.bedTemp = float(re.search("[0-9\.]*", line.split('B:')[1]).group(0))\r
+                               self.temperatureGraph.addPoint(self.temp, self.temperatureSelect.GetValue(), self.bedTemp, self.bedTemperatureSelect.GetValue())\r
                                wx.CallAfter(self.UpdateProgress)\r
                        elif line.strip() != 'ok':\r
                                wx.CallAfter(self.AddTermLog, line)\r
@@ -479,3 +497,83 @@ class printWindow(wx.Frame):
                                        self.printIdx = lineNr\r
                                        #we should actually resend the line here, but we also get an "ok" for each error from Marlin. And thus we'll resend on the OK.\r
 \r
+class temperatureGraph(wx.Panel):\r
+       def __init__(self, parent):\r
+               super(temperatureGraph, self).__init__(parent)\r
+               \r
+               self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)\r
+               self.Bind(wx.EVT_SIZE, self.OnSize)\r
+               self.Bind(wx.EVT_PAINT, self.OnDraw)\r
+               \r
+               self.lastDraw = time.time() - 1.0\r
+               self.points = []\r
+               self.backBuffer = None\r
+               self.addPoint(0,0,0,0)\r
+       \r
+       def OnEraseBackground(self, e):\r
+               pass\r
+       \r
+       def OnSize(self, e):\r
+               if self.backBuffer == None or self.GetSize() != self.backBuffer.GetSize():\r
+                       self.backBuffer = wx.EmptyBitmap(*self.GetSizeTuple())\r
+                       self.UpdateDrawing(True)\r
+       \r
+       def OnDraw(self, e):\r
+               dc = wx.BufferedPaintDC(self, self.backBuffer)\r
+       \r
+       def UpdateDrawing(self, force = False):\r
+               now = time.time()\r
+               if not force and now - self.lastDraw < 1.0:\r
+                       return\r
+               self.lastDraw = now\r
+               dc = wx.MemoryDC()\r
+               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
+               tempPen = wx.Pen('#FF4040')\r
+               tempSPPen = wx.Pen('#FFA0A0')\r
+               tempPenBG = wx.Pen('#FFD0D0')\r
+               bedTempPen = wx.Pen('#4040FF')\r
+               bedTempSPPen = wx.Pen('#A0A0FF')\r
+               bedTempPenBG = wx.Pen('#D0D0FF')\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
+                               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
+                               dc.DrawPoint(x, h - (btSP * h / 300))\r
+                               dc.SetPen(tempPen)\r
+                               dc.DrawPoint(x, h - (t * h / 300))\r
+                               dc.SetPen(bedTempPen)\r
+                               dc.DrawPoint(x, h - (bt * h / 300))\r
+                       t0 = temp\r
+                       bt0 = bedTemp\r
+                       tSP0 = tempSP\r
+                       btSP0 = bedTempSP\r
+                       x0 = x1 + 1\r
+               \r
+               del dc\r
+               self.Refresh(eraseBackground=False)\r
+               self.Update()\r
+               \r
+               if len(self.points) > 0 and (time.time() - self.points[0][4]) > w + 20:\r
+                       self.points.pop(0)\r
+\r
+       def addPoint(self, temp, tempSP, bedTemp, bedTempSP):\r
+               self.points.append((temp, tempSP, bedTemp, bedTempSP, time.time()))\r
+               wx.CallAfter(self.UpdateDrawing)\r
+\r
index 79ef9aaf27db3780859f756e94cb0f6ba0f37b1b..c7d285d5e91dcb3f9993f1ee97677eed1c163867 100644 (file)
@@ -1,7 +1,7 @@
 from __future__ import absolute_import
 import __init__
 
-import os, glob, sys, time
+import os, glob, sys, time, math
 
 from serial import Serial
 
@@ -37,6 +37,7 @@ class VirtualPrinter():
                self.readList = ['start\n', 'Marlin: Virtual Marlin!\n']
                self.temp = 0.0
                self.targetTemp = 0.0
+               self.lastTempAt = time.time()
                self.bedTemp = 1.0
                self.bedTargetTemp = 1.0
        
@@ -63,8 +64,12 @@ class VirtualPrinter():
                if self.readList == None:
                        return ''
                n = 0
-               self.temp = (self.temp + self.targetTemp) / 2
-               self.bedTemp = (self.bedTemp + self.bedTargetTemp) / 2
+               timeDiff = self.lastTempAt - time.time()
+               self.lastTempAt = time.time()
+               if abs(self.temp - self.targetTemp) > 1:
+                       self.temp += math.copysign(timeDiff, self.targetTemp - self.temp)
+               if abs(self.bedTemp - self.bedTargetTemp) > 1:
+                       self.bedTemp += math.copysign(timeDiff, self.bedTargetTemp - self.bedTemp)
                while len(self.readList) < 1:
                        time.sleep(0.1)
                        n += 1