+
+class bedLevelFirstPage(InfoPage):
+ def __init__(self, parent):
+ super(bedLevelFirstPage, self).__init__(parent, "Bed leveling wizard")
+ self.AddText('This wizard will help you in leveling your printer bed')
+ self.AddSeperator()
+ self.AddText('It will do the following steps')
+ self.AddText('* Move the printer head to each corner')
+ self.AddText(' and let you adjust the height of the bed to the nozzle')
+ self.AddText('* Print a line around the bed to check if it is level')
+
+class bedLevelWizardMain(InfoPage):
+ def __init__(self, parent):
+ super(bedLevelWizardMain, self).__init__(parent, "Bed leveling wizard")
+
+ self.connectButton = self.AddButton('Connect to printer')
+ self.comm = None
+
+ self.infoBox = self.AddInfoBox()
+ self.resumeButton = self.AddButton('Resume')
+ self.resumeButton.Enable(False)
+
+ self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
+ self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
+
+ def OnConnect(self, e = None):
+ if self.comm is not None:
+ self.comm.close()
+ del self.comm
+ self.comm = None
+ wx.CallAfter(self.OnConnect)
+ return
+ self.connectButton.Enable(False)
+ self.comm = machineCom.MachineCom(callbackObject=self)
+ self.infoBox.SetBusy('Connecting to machine.')
+ self._wizardState = 0
+
+ def AllowNext(self):
+ return False
+
+ def OnResume(self, e):
+ feedZ = profile.getProfileSettingFloat('max_z_speed') * 60
+ feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
+ if self._wizardState == 2:
+ wx.CallAfter(self.infoBox.SetBusy, 'Moving head to back left corner...')
+ self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
+ self.comm.sendCommand('G1 X%d Y%d F%d' % (0, profile.getPreferenceFloat('machine_depth'), feedTravel))
+ self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
+ self.comm.sendCommand('M400')
+ self._wizardState = 3
+ elif self._wizardState == 4:
+ wx.CallAfter(self.infoBox.SetBusy, 'Moving head to back right corner...')
+ self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
+ self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth') - 20, feedTravel))
+ self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
+ self.comm.sendCommand('M400')
+ self._wizardState = 5
+ elif self._wizardState == 6:
+ wx.CallAfter(self.infoBox.SetBusy, 'Moving head to front right corner...')
+ self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
+ self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getPreferenceFloat('machine_width'), 20, feedTravel))
+ self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
+ self.comm.sendCommand('M400')
+ self._wizardState = 7
+ elif self._wizardState == 8:
+ wx.CallAfter(self.infoBox.SetBusy, 'Heating up printer...')
+ self.comm.sendCommand('G1 Z15 F%d' % (feedZ))
+ self.comm.sendCommand('M104 S%d' % (profile.getProfileSettingFloat('print_temperature')))
+ self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel))
+ self._wizardState = 9
+ self.resumeButton.Enable(False)
+
+ def mcLog(self, message):
+ print 'Log:', message
+
+ def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
+ if self._wizardState == 1:
+ self._wizardState = 2
+ wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.')
+ wx.CallAfter(self.resumeButton.Enable, True)
+ elif self._wizardState == 3:
+ self._wizardState = 4
+ wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.')
+ wx.CallAfter(self.resumeButton.Enable, True)
+ elif self._wizardState == 5:
+ self._wizardState = 6
+ wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.')
+ wx.CallAfter(self.resumeButton.Enable, True)
+ elif self._wizardState == 7:
+ self._wizardState = 8
+ wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.')
+ wx.CallAfter(self.resumeButton.Enable, True)
+ elif self._wizardState == 9:
+ if temp < profile.getProfileSettingFloat('print_temperature') - 5:
+ wx.CallAfter(self.infoBox.SetInfo, 'Heating up printer: %d/%d' % (temp, profile.getProfileSettingFloat('print_temperature')))
+ else:
+ self._wizardState = 10
+ wx.CallAfter(self.infoBox.SetInfo, 'Printing a square on the printer bed at 0.3mm height.')
+ feedZ = profile.getProfileSettingFloat('max_z_speed') * 60
+ feedPrint = profile.getProfileSettingFloat('print_speed') * 60
+ feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
+ w = profile.getPreferenceFloat('machine_width')
+ d = profile.getPreferenceFloat('machine_depth')
+ filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
+ filamentArea = math.pi * filamentRadius * filamentRadius
+ ePerMM = (profile.calculateEdgeWidth() * 0.3) / filamentArea
+ eValue = 0.0
+
+ gcodeList = [
+ 'G1 Z2 F%d' % (feedZ),
+ 'G92 E0',
+ 'G1 X%d Y%d F%d' % (5, 5, feedTravel),
+ 'G1 Z0.3 F%d' % (feedZ)]
+ eValue += (d - 10) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (5, d - 5, eValue, feedPrint))
+ eValue += (w - 10) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (w - 5, d - 5, eValue, feedPrint))
+ eValue += (d - 10) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (w - 5, 5, eValue, feedPrint))
+ eValue += (w - 10) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (5, 5, eValue, feedPrint))
+
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (5.4, 5.4, eValue, feedTravel))
+ eValue += (d - 10.8) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (5.4, d - 5.4, eValue, feedPrint))
+ eValue += (w - 10.8) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (w - 5.4, d - 5.4, eValue, feedPrint))
+ eValue += (d - 10.8) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (w - 5.4, 5.4, eValue, feedPrint))
+ eValue += (w - 10.8) * ePerMM
+ gcodeList.append('G1 X%d Y%d E%f F%d' % (5.4, 5.4, eValue, feedPrint))
+ self.comm.printGCode(gcodeList)
+
+ def mcStateChange(self, state):
+ if self.comm is None:
+ return
+ if self.comm.isOperational():
+ if self._wizardState == 0:
+ wx.CallAfter(self.infoBox.SetInfo, 'Homing printer...')
+ self.comm.sendCommand('G28')
+ self._wizardState = 1
+ elif self._wizardState == 10 and not self.comm.isPrinting():
+ self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('max_z_speed') * 60))
+ self.comm.sendCommand('M104 S0')
+ wx.CallAfter(self.infoBox.SetInfo, 'Calibration finished.\nThe two squares on the bed should slightly touch each other.')
+ wx.CallAfter(self.infoBox.SetReadyIndicator)
+ wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
+ self._wizardState = 11
+ elif self.comm.isError():
+ wx.CallAfter(self.infoBox.SetError, 'Failed to establish connection with the printer.', 'http://wiki.ultimaker.com/Cura:_Connection_problems')
+
+ def mcMessage(self, message):
+ pass
+
+ def mcProgress(self, lineNr):
+ pass
+
+ def mcZChange(self, newZ):
+ pass
+
+class bedLevelWizard(wx.wizard.Wizard):
+ def __init__(self):
+ super(bedLevelWizard, self).__init__(None, -1, "Bed leveling wizard")
+
+ self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
+ self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
+
+ self.firstInfoPage = bedLevelFirstPage(self)
+ self.mainPage = bedLevelWizardMain(self)
+
+ wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.mainPage)
+
+ self.FitToPage(self.firstInfoPage)
+ self.GetPageAreaSizer().Add(self.firstInfoPage)
+
+ self.RunWizard(self.firstInfoPage)
+ self.Destroy()
+
+ def OnPageChanging(self, e):
+ e.GetPage().StoreData()
+
+ def OnPageChanged(self, e):
+ if e.GetPage().AllowNext():
+ self.FindWindowById(wx.ID_FORWARD).Enable()
+ else:
+ self.FindWindowById(wx.ID_FORWARD).Disable()
+ self.FindWindowById(wx.ID_BACKWARD).Disable()