From 34c6be63bdc40cc8d949f153da46894d2f215346 Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 10 Jul 2012 17:04:37 +0200 Subject: [PATCH] Add temperature graph to printer interface. --- Cura/gui/printWindow.py | 124 +++++++++++++++++++++++++++++++++++----- Cura/util/machineCom.py | 11 +++- 2 files changed, 119 insertions(+), 16 deletions(-) diff --git a/Cura/gui/printWindow.py b/Cura/gui/printWindow.py index ad6b9c2..94d8fc0 100644 --- a/Cura/gui/printWindow.py +++ b/Cura/gui/printWindow.py @@ -1,7 +1,7 @@ from __future__ import absolute_import import __init__ -import wx, threading, re, subprocess, sys, os +import wx, threading, re, subprocess, sys, os, time from wx.lib import buttons from gui import icon @@ -140,10 +140,15 @@ class printWindow(wx.Frame): self.bedTemperatureLabel.Show(False) self.bedTemperatureSelect.Show(False) + self.temperatureGraph = temperatureGraph(self.temperaturePanel) + sizer.Add(wx.StaticText(self.temperaturePanel, -1, "Temp:"), pos=(0,0)) sizer.Add(self.temperatureSelect, pos=(0,1)) sizer.Add(self.bedTemperatureLabel, pos=(1,0)) sizer.Add(self.bedTemperatureSelect, pos=(1,1)) + sizer.Add(self.temperatureGraph, pos=(2,0), span=(1,2), flag=wx.EXPAND) + sizer.AddGrowableRow(2) + sizer.AddGrowableCol(0) nb.AddPage(self.temperaturePanel, 'Temp') @@ -289,7 +294,7 @@ class printWindow(wx.Frame): self.bedTemperatureSelect.Show(True) self.temperaturePanel.Layout() self.statsText.SetLabel(status.strip()) - self.Layout() + #self.Layout() def OnConnect(self, e): if self.machineCom != None: @@ -417,17 +422,26 @@ class printWindow(wx.Frame): if lineNr >= len(self.gcodeList): return False line = self.gcodeList[lineNr] - if line == 'M0' or line == 'M1': - self.OnPause(None) - line = 'M105' - if self.typeList[lineNr] == 'WALL-OUTER': - line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioOuterWall)), line) - if self.typeList[lineNr] == 'WALL-INNER': - line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioInnerWall)), line) - if self.typeList[lineNr] == 'FILL': - line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioFill)), line) - if self.typeList[lineNr] == 'SUPPORT': - line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioSupport)), line) + try: + if line == 'M0' or line == 'M1': + self.OnPause(None) + line = 'M105' + if ('M104' in line or 'M109' in line) and 'S' in line: + n = int(re.search('S([0-9]*)', line).group(1)) + wx.CallAfter(self.temperatureSelect.SetValue, n) + if ('M140' in line or 'M190' in line) and 'S' in line: + n = int(re.search('S([0-9]*)', line).group(1)) + wx.CallAfter(self.bedTemperatureSelect.SetValue, n) + if self.typeList[lineNr] == 'WALL-OUTER': + line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioOuterWall)), line) + if self.typeList[lineNr] == 'WALL-INNER': + line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioInnerWall)), line) + if self.typeList[lineNr] == 'FILL': + line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioFill)), line) + if self.typeList[lineNr] == 'SUPPORT': + line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self.feedrateRatioSupport)), line) + except: + print "Unexpected error:", sys.exc_info() checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (lineNr, line))) self.machineCom.sendCommand("N%d%s*%d" % (lineNr, line, checksum)) return True @@ -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. if self.printIdx == None or self.pause: self.machineCom.sendCommand("M105") + else: + wx.CallAfter(self.AddTermLog, '!!Comm timeout, forcing next line!!\n') + line = 'ok' if self.machineConnected: while self.sendCnt > 0 and not self.pause: self.sendLine(self.printIdx) @@ -454,6 +471,7 @@ class printWindow(wx.Frame): 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.temperatureGraph.addPoint(self.temp, self.temperatureSelect.GetValue(), self.bedTemp, self.bedTemperatureSelect.GetValue()) wx.CallAfter(self.UpdateProgress) elif line.strip() != 'ok': wx.CallAfter(self.AddTermLog, line) @@ -479,3 +497,83 @@ class printWindow(wx.Frame): self.printIdx = lineNr #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. +class temperatureGraph(wx.Panel): + def __init__(self, parent): + super(temperatureGraph, self).__init__(parent) + + self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) + self.Bind(wx.EVT_SIZE, self.OnSize) + self.Bind(wx.EVT_PAINT, self.OnDraw) + + self.lastDraw = time.time() - 1.0 + self.points = [] + self.backBuffer = None + self.addPoint(0,0,0,0) + + def OnEraseBackground(self, e): + pass + + def OnSize(self, e): + if self.backBuffer == None or self.GetSize() != self.backBuffer.GetSize(): + self.backBuffer = wx.EmptyBitmap(*self.GetSizeTuple()) + self.UpdateDrawing(True) + + def OnDraw(self, e): + dc = wx.BufferedPaintDC(self, self.backBuffer) + + def UpdateDrawing(self, force = False): + now = time.time() + if not force and now - self.lastDraw < 1.0: + return + self.lastDraw = now + dc = wx.MemoryDC() + dc.SelectObject(self.backBuffer) + dc.Clear() + w, h = self.GetSizeTuple() + x0 = 0 + t0 = 0 + bt0 = 0 + tSP0 = 0 + btSP0 = 0 + tempPen = wx.Pen('#FF4040') + tempSPPen = wx.Pen('#FFA0A0') + tempPenBG = wx.Pen('#FFD0D0') + bedTempPen = wx.Pen('#4040FF') + bedTempSPPen = wx.Pen('#A0A0FF') + bedTempPenBG = wx.Pen('#D0D0FF') + 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 + 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) + dc.DrawPoint(x, h - (btSP * h / 300)) + dc.SetPen(tempPen) + dc.DrawPoint(x, h - (t * h / 300)) + dc.SetPen(bedTempPen) + dc.DrawPoint(x, h - (bt * h / 300)) + t0 = temp + bt0 = bedTemp + tSP0 = tempSP + btSP0 = bedTempSP + x0 = x1 + 1 + + del dc + self.Refresh(eraseBackground=False) + self.Update() + + if len(self.points) > 0 and (time.time() - self.points[0][4]) > w + 20: + self.points.pop(0) + + def addPoint(self, temp, tempSP, bedTemp, bedTempSP): + self.points.append((temp, tempSP, bedTemp, bedTempSP, time.time())) + wx.CallAfter(self.UpdateDrawing) + diff --git a/Cura/util/machineCom.py b/Cura/util/machineCom.py index 79ef9aa..c7d285d 100644 --- a/Cura/util/machineCom.py +++ b/Cura/util/machineCom.py @@ -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