From c7c668685bcfc5e02715fe8e036962c41bb07524 Mon Sep 17 00:00:00 2001 From: daid303 Date: Wed, 3 Oct 2012 15:11:35 +0200 Subject: [PATCH] Add a retraction enable setting. Add extrusion/retraction buttons in printer interface. (still needs images) Update the printer interface GUI with the actual temperture from the GCode when a temp change is send. --- Cura/cura_sf/fabmetheus_utilities/settings.py | 2 +- Cura/gui/configWizard.py | 2 +- Cura/gui/mainWindow.py | 1 + Cura/gui/printWindow.py | 68 +++++++++++-------- Cura/gui/simpleMode.py | 11 +-- Cura/util/machineCom.py | 45 +++++++++--- Cura/util/profile.py | 5 +- 7 files changed, 85 insertions(+), 49 deletions(-) diff --git a/Cura/cura_sf/fabmetheus_utilities/settings.py b/Cura/cura_sf/fabmetheus_utilities/settings.py index b504c159..c460b6f1 100644 --- a/Cura/cura_sf/fabmetheus_utilities/settings.py +++ b/Cura/cura_sf/fabmetheus_utilities/settings.py @@ -384,7 +384,7 @@ def getProfileInformation(): 'Maximum_E_Value_before_Reset_float': DEFSET, 'Minimum_Travel_for_Retraction_millimeters': storedSettingFloat("retraction_min_travel"), 'Retract_Within_Island': storedSettingInvertBoolean("retract_on_jumps_only"), - 'Retraction_Distance_millimeters': storedSettingFloat('retraction_amount'), + 'Retraction_Distance_millimeters': lambda setting: profile.getProfileSettingFloat('retraction_amount') if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'), },'alteration': { 'Activate_Alteration': storedSetting('add_start_end_gcode'), diff --git a/Cura/gui/configWizard.py b/Cura/gui/configWizard.py index 105e77f8..b1e64747 100644 --- a/Cura/gui/configWizard.py +++ b/Cura/gui/configWizard.py @@ -334,7 +334,7 @@ class UltimakerCheckupPage(InfoPage): def mcLog(self, message): pass - def mcTempUpdate(self, temp, bedTemp): + def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp): if self.checkupState == 0: self.tempCheckTimeout = 20 if temp > 70: diff --git a/Cura/gui/mainWindow.py b/Cura/gui/mainWindow.py index 39e733a3..925cced9 100644 --- a/Cura/gui/mainWindow.py +++ b/Cura/gui/mainWindow.py @@ -124,6 +124,7 @@ class mainWindow(configBase.configWindowBase): c = configBase.SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.') validators.validFloat(c, 0.0001) validators.wallThicknessValidator(c) + c = configBase.SettingRow(left, "Enable retraction", 'retraction_enable', False, 'Retract the filament when the nozzle is moving over a none-printed area. Details about the retraction can be configured in the advanced tab.') configBase.TitleRow(left, "Fill") c = configBase.SettingRow(left, "Bottom/Top thickness (mm)", 'solid_layer_thickness', '0.6', 'This controls the thickness of the bottom and top layers, the amount of solid layers put down is calculated by the layer thickness and this value.\nHaving this value a multiply of the layer thickness makes sense. And keep it near your wall thickness to make an evenly strong part.') diff --git a/Cura/gui/printWindow.py b/Cura/gui/printWindow.py index 4eb91444..e2df8b2e 100644 --- a/Cura/gui/printWindow.py +++ b/Cura/gui/printWindow.py @@ -55,11 +55,11 @@ class printProcessMonitor(): self.thread = None class PrintCommandButton(buttons.GenBitmapButton): - def __init__(self, parent, command, bitmapFilename, size=(20,20)): + def __init__(self, parent, commandList, bitmapFilename, size=(20,20)): self.bitmap = toolbarUtil.getBitmapImage(bitmapFilename) super(PrintCommandButton, self).__init__(parent.directControlPanel, -1, self.bitmap, size=size) - self.command = command + self.commandList = commandList self.parent = parent self.SetBezelWidth(1) @@ -70,11 +70,8 @@ class PrintCommandButton(buttons.GenBitmapButton): def OnClick(self, e): if self.parent.machineCom == None or self.parent.machineCom.isPrinting(): return; - if self.command.startswith('G1'): - self.parent.machineCom.sendCommand("G91") - self.parent.machineCom.sendCommand(self.command) - if self.command.startswith('G1'): - self.parent.machineCom.sendCommand("G90") + for cmd in self.commandList: + self.parent.machineCom.sendCommand(cmd) e.Skip() class printWindow(wx.Frame): @@ -163,33 +160,36 @@ class printWindow(wx.Frame): sizer = wx.GridBagSizer(2, 2) self.directControlPanel.SetSizer(sizer) - sizer.Add(PrintCommandButton(self, 'G1 Y100 F6000', 'print-move-y100.png'), pos=(0,3)) - sizer.Add(PrintCommandButton(self, 'G1 Y10 F6000', 'print-move-y10.png'), pos=(1,3)) - sizer.Add(PrintCommandButton(self, 'G1 Y1 F6000', 'print-move-y1.png'), pos=(2,3)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y100 F6000', 'G90'], 'print-move-y100.png'), pos=(0,3)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y10 F6000', 'G90'], 'print-move-y10.png'), pos=(1,3)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y1 F6000', 'G90'], 'print-move-y1.png'), pos=(2,3)) - sizer.Add(PrintCommandButton(self, 'G1 Y-1 F6000', 'print-move-y-1.png'), pos=(4,3)) - sizer.Add(PrintCommandButton(self, 'G1 Y-10 F6000', 'print-move-y-10.png'), pos=(5,3)) - sizer.Add(PrintCommandButton(self, 'G1 Y-100 F6000', 'print-move-y-100.png'), pos=(6,3)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y-1 F6000', 'G90'], 'print-move-y-1.png'), pos=(4,3)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y-10 F6000', 'G90'], 'print-move-y-10.png'), pos=(5,3)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y-100 F6000', 'G90'], 'print-move-y-100.png'), pos=(6,3)) - sizer.Add(PrintCommandButton(self, 'G1 X-100 F6000', 'print-move-x-100.png'), pos=(3,0)) - sizer.Add(PrintCommandButton(self, 'G1 X-10 F6000', 'print-move-x-10.png'), pos=(3,1)) - sizer.Add(PrintCommandButton(self, 'G1 X-1 F6000', 'print-move-x-1.png'), pos=(3,2)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 X-100 F6000', 'G90'], 'print-move-x-100.png'), pos=(3,0)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 X-10 F6000', 'G90'], 'print-move-x-10.png'), pos=(3,1)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 X-1 F6000', 'G90'], 'print-move-x-1.png'), pos=(3,2)) - sizer.Add(PrintCommandButton(self, 'G28 X0 Y0', 'print-move-home.png'), pos=(3,3)) + sizer.Add(PrintCommandButton(self, ['G28 X0 Y0'], 'print-move-home.png'), pos=(3,3)) - sizer.Add(PrintCommandButton(self, 'G1 X1 F6000', 'print-move-x1.png'), pos=(3,4)) - sizer.Add(PrintCommandButton(self, 'G1 X10 F6000', 'print-move-x10.png'), pos=(3,5)) - sizer.Add(PrintCommandButton(self, 'G1 X100 F6000', 'print-move-x100.png'), pos=(3,6)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 X1 F6000', 'G90'], 'print-move-x1.png'), pos=(3,4)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 X10 F6000', 'G90'], 'print-move-x10.png'), pos=(3,5)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 X100 F6000', 'G90'], 'print-move-x100.png'), pos=(3,6)) - sizer.Add(PrintCommandButton(self, 'G1 Z10 F200', 'print-move-z10.png'), pos=(0,8)) - sizer.Add(PrintCommandButton(self, 'G1 Z1 F200', 'print-move-z1.png'), pos=(1,8)) - sizer.Add(PrintCommandButton(self, 'G1 Z0.1 F200', 'print-move-z0.1.png'), pos=(2,8)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z10 F200', 'G90'], 'print-move-z10.png'), pos=(0,8)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z1 F200', 'G90'], 'print-move-z1.png'), pos=(1,8)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z0.1 F200', 'G90'], 'print-move-z0.1.png'), pos=(2,8)) - sizer.Add(PrintCommandButton(self, 'G28 Z0', 'print-move-home.png'), pos=(3,8)) + sizer.Add(PrintCommandButton(self, ['G28 Z0'], 'print-move-home.png'), pos=(3,8)) - sizer.Add(PrintCommandButton(self, 'G1 Z-0.1 F200', 'print-move-z-0.1.png'), pos=(4,8)) - sizer.Add(PrintCommandButton(self, 'G1 Z-1 F200', 'print-move-z-1.png'), pos=(5,8)) - sizer.Add(PrintCommandButton(self, 'G1 Z-10 F200', 'print-move-z-10.png'), pos=(6,8)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-0.1 F200', 'G90'], 'print-move-z-0.1.png'), pos=(4,8)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-1 F200', 'G90'], 'print-move-z-1.png'), pos=(5,8)) + sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-10 F200', 'G90'], 'print-move-z-10.png'), pos=(6,8)) + + sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E2 F120'], 'question.png'), pos=(8,1)) + sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-2 F120'], 'question.png'), pos=(8,2)) nb.AddPage(self.directControlPanel, 'Jog') @@ -248,11 +248,13 @@ class printWindow(wx.Frame): sizer.Add(self.timelapsEnable, pos=(0,0), span=(1,2), flag=wx.EXPAND) pages = self.cam.propertyPages() + self.cam.buttons = [self.timelapsEnable] for page in pages: button = wx.Button(self.camPage, -1, page) button.index = pages.index(page) sizer.Add(button, pos=(1, pages.index(page))) button.Bind(wx.EVT_BUTTON, self.OnPropertyPageButton) + self.cam.buttons.append(button) self.camPreview = wx.Panel(self.camPage) sizer.Add(self.camPreview, pos=(2,0), span=(1,2), flag=wx.EXPAND) @@ -330,6 +332,9 @@ class printWindow(wx.Frame): self.bedTemperatureSelect.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()) + if self.cam: + for button in self.cam.buttons: + button.Enable(self.machineCom == None or not self.machineCom.isPrinting()) def UpdateProgress(self): status = "" @@ -485,6 +490,7 @@ class printWindow(wx.Frame): wx.CallAfter(self.progress.SetRange, len(gcodeList)) wx.CallAfter(self.UpdateButtonStates) wx.CallAfter(self.UpdateProgress) + wx.CallAfter(self.SetTitle, 'Printing: %s' % (filename)) def sendLine(self, lineNr): if lineNr >= len(self.gcodeList): @@ -507,8 +513,12 @@ class printWindow(wx.Frame): #print message pass - def mcTempUpdate(self, temp, bedTemp): - self.temperatureGraph.addPoint(temp, self.temperatureSelect.GetValue(), bedTemp, self.bedTemperatureSelect.GetValue()) + def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp): + self.temperatureGraph.addPoint(temp, targetTemp, bedTemp, bedTargetTemp) + if self.temperatureSelect.GetValue() != targetTemp: + wx.CallAfter(self.temperatureSelect.SetValue, targetTemp) + if self.bedTemperatureSelect.GetValue() != bedTargetTemp: + wx.CallAfter(self.bedTemperatureSelect.SetValue, bedTargetTemp) def mcStateChange(self, state): if self.machineCom != None and state == self.machineCom.STATE_OPERATIONAL and self.cam != None: diff --git a/Cura/gui/simpleMode.py b/Cura/gui/simpleMode.py index acabd652..8e5b4823 100644 --- a/Cura/gui/simpleMode.py +++ b/Cura/gui/simpleMode.py @@ -39,7 +39,7 @@ class simpleModeWindow(configBase.configWindowBase): toolsMenu = wx.Menu() i = toolsMenu.Append(-1, 'Switch to Normal mode...') self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i) - menubar.Append(toolsMenu, 'Tools') + menubar.Append(toolsMenu, 'Normal mode') helpMenu = wx.Menu() i = helpMenu.Append(-1, 'Online documentation...') @@ -180,10 +180,11 @@ class simpleModeWindow(configBase.configWindowBase): put('support', 'None') #put('machine_center_x', '100') #put('machine_center_y', '100') - #put('retraction_min_travel', '5.0') - #put('retraction_speed', '13.5') - #put('retraction_amount', '0.0') - #put('retraction_extra', '0.0') + put('retraction_enable', 'True') + put('retraction_min_travel', '5.0') + put('retraction_speed', '13.5') + put('retraction_amount', '4.5') + put('retraction_extra', '0.0') put('travel_speed', '150') put('max_z_speed', '3.0') put('bottom_layer_speed', '25') diff --git a/Cura/util/machineCom.py b/Cura/util/machineCom.py index 3e3b1f7e..6ea4ad0a 100644 --- a/Cura/util/machineCom.py +++ b/Cura/util/machineCom.py @@ -62,12 +62,12 @@ class VirtualPrinter(): #print "Send: %s" % (data.rstrip()) if 'M104' in data or 'M109' in data: try: - self.targetTemp = float(data[data.find('S')+1:]) + self.targetTemp = float(re.search('S([0-9]+)', cmd).group(1)) except: pass if 'M140' in data or 'M190' in data: try: - self.bedTargetTemp = float(data[data.find('S')+1:]) + self.bedTargetTemp = float(re.search('S([0-9]+)', cmd).group(1)) except: pass if 'M105' in data: @@ -103,7 +103,7 @@ class MachineComPrintCallback(object): def mcLog(self, message): pass - def mcTempUpdate(self, temp, bedTemp): + def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp): pass def mcStateChange(self, state): @@ -151,6 +151,8 @@ class MachineCom(object): self._baudrateDetectRetry = 0 self._temp = 0 self._bedTemp = 0 + self._targetTemp = 0 + self._bedTargetTemp = 0 self._gcodeList = None self._gcodePos = 0 self._commandQueue = queue.Queue() @@ -287,20 +289,24 @@ class MachineCom(object): break #No matter the state, if we see an error, goto the error state and store the error for reference. - if line.startswith('Error: '): + if line.startswith('Error:'): #Oh YEAH, consistency. - # Marlin reports an MIN/MAX temp error as "Error: x\n: Extruder switched off. MAXTEMP triggered !\n" + # Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n" # But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!" # So we can have an extra newline in the most common case. Awesome work people. - if re.match('Error: [0-9]\n', line): + if re.match('Error:[0-9]\n', line): line = line.rstrip() + self._readline() - self._errorValue = line - self._changeState(self.STATE_ERROR) + #Skip the communication errors, as those get corrected. + if 'checksum mismatch' in line or 'Line Number is not Last Line Number' in line or 'No Line Number with checksum' in line: + pass + else: + self._errorValue = line[6:] + self._changeState(self.STATE_ERROR) 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) + self._callback.mcTempUpdate(self._temp, self._bedTemp, self._targetTemp, self._bedTargetTemp) #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() @@ -331,6 +337,7 @@ class MachineCom(object): except: self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, getExceptionString())) elif 'ok' in line: + self._sendCommand("M999") self._serial.timeout = 2 profile.putPreference('serial_baud_auto', self._serial.baudrate) self._changeState(self.STATE_OPERATIONAL) @@ -410,11 +417,27 @@ class MachineCom(object): return if 'M109' in cmd or 'M190' in cmd: self._heatupWaitStartTime = time.time() + if 'M104' in cmd or 'M109' in cmd: + try: + self._targetTemp = float(re.search('S([0-9]+)', cmd).group(1)) + except: + pass + if 'M140' in cmd or 'M190' in cmd: + try: + self._bedTargetTemp = float(re.search('S([0-9]+)').group(1)) + except: + pass 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. - # Oddly enough, the write timeout is not even set and thus we should not get a write timeout. self._serial.write(cmd + '\n') + except SerialTimeoutException: + self._log("Serial timeout while writing to serial port, trying again.") + try: + self._serial.write(cmd + '\n') + except: + self._log("Unexpected error while writing serial port: %s" % (getExceptionString())) + self._errorValue = getExceptionString() + self.close(True) except: self._log("Unexpected error while writing serial port: %s" % (getExceptionString())) self._errorValue = getExceptionString() diff --git a/Cura/util/profile.py b/Cura/util/profile.py index c0f6a745..a528c1eb 100644 --- a/Cura/util/profile.py +++ b/Cura/util/profile.py @@ -23,7 +23,7 @@ profileDefaultSettings = { 'skirt_line_count': '1', 'skirt_gap': '3.0', 'print_speed': '50', - 'print_temperature': '230', + 'print_temperature': '220', 'print_bed_temperature': '70', 'support': 'None', 'filament_diameter': '2.89', @@ -31,8 +31,9 @@ profileDefaultSettings = { 'machine_center_x': '100', 'machine_center_y': '100', 'retraction_min_travel': '5.0', + 'retraction_enable': 'False', 'retraction_speed': '40.0', - 'retraction_amount': '0.0', + 'retraction_amount': '4.5', 'retraction_extra': '0.0', 'retract_on_jumps_only': 'True', 'travel_speed': '150', -- 2.30.2