2 from __future__ import absolute_import
11 from gui import firmwareInstall
12 from gui import toolbarUtil
13 from util import machineCom
14 from util import profile
15 from util.resources import getPathForImage
17 class InfoBox(wx.Panel):
18 def __init__(self, parent):
19 super(InfoBox, self).__init__(parent)
20 self.SetBackgroundColour('#FFFF80')
22 self.sizer = wx.GridBagSizer(5, 5)
23 self.SetSizer(self.sizer)
25 self.attentionBitmap = wx.Bitmap(getPathForImage('attention.png'))
26 self.errorBitmap = wx.Bitmap(getPathForImage('error.png'))
27 self.readyBitmap = wx.Bitmap(getPathForImage('ready.png'))
29 wx.Bitmap(getPathForImage('busy-0.png')),
30 wx.Bitmap(getPathForImage('busy-1.png')),
31 wx.Bitmap(getPathForImage('busy-2.png')),
32 wx.Bitmap(getPathForImage('busy-3.png'))
35 self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1))
36 self.text = wx.StaticText(self, -1, '')
37 self.sizer.Add(self.bitmap, pos=(0, 0), flag=wx.ALL, border=5)
38 self.sizer.Add(self.text, pos=(0, 1), flag=wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, border=5)
41 self.timer = wx.Timer(self)
42 self.Bind(wx.EVT_TIMER, self.doBusyUpdate, self.timer)
45 def SetInfo(self, info):
46 self.SetBackgroundColour('#FFFF80')
47 self.text.SetLabel(info)
50 def SetError(self, info):
51 self.SetBackgroundColour('#FF8080')
52 self.text.SetLabel(info)
53 self.SetErrorIndicator()
56 def SetAttention(self, info):
57 self.SetBackgroundColour('#FFFF80')
58 self.text.SetLabel(info)
59 self.SetAttentionIndicator()
62 def SetBusyIndicator(self):
64 self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
66 def doBusyUpdate(self, e):
67 if self.busyState == None:
70 if self.busyState >= len(self.busyBitmap):
72 self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
74 def SetReadyIndicator(self):
76 self.bitmap.SetBitmap(self.readyBitmap)
78 def SetErrorIndicator(self):
80 self.bitmap.SetBitmap(self.errorBitmap)
82 def SetAttentionIndicator(self):
84 self.bitmap.SetBitmap(self.attentionBitmap)
87 class InfoPage(wx.wizard.WizardPageSimple):
88 def __init__(self, parent, title):
89 wx.wizard.WizardPageSimple.__init__(self, parent)
91 sizer = wx.GridBagSizer(5, 5)
95 title = wx.StaticText(self, -1, title)
96 title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
97 sizer.Add(title, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL)
98 sizer.Add(wx.StaticLine(self, -1), pos=(1, 0), span=(1, 2), flag=wx.EXPAND | wx.ALL)
99 sizer.AddGrowableCol(1)
103 def AddText(self, info):
104 text = wx.StaticText(self, -1, info)
105 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT | wx.RIGHT)
109 def AddSeperator(self):
110 self.GetSizer().Add(wx.StaticLine(self, -1), pos=(self.rowNr, 0), span=(1, 2), flag=wx.EXPAND | wx.ALL)
113 def AddHiddenSeperator(self):
116 def AddInfoBox(self):
117 infoBox = InfoBox(self)
118 self.GetSizer().Add(infoBox, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT | wx.RIGHT | wx.EXPAND)
122 def AddRadioButton(self, label, style=0):
123 radio = wx.RadioButton(self, -1, label, style=style)
124 self.GetSizer().Add(radio, pos=(self.rowNr, 0), span=(1, 2), flag=wx.EXPAND | wx.ALL)
128 def AddCheckbox(self, label, checked=False):
129 check = wx.CheckBox(self, -1)
130 text = wx.StaticText(self, -1, label)
131 check.SetValue(checked)
132 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
133 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1, 2), flag=wx.ALL)
137 def AddButton(self, label):
138 button = wx.Button(self, -1, label)
139 self.GetSizer().Add(button, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT)
143 def AddDualButton(self, label1, label2):
144 button1 = wx.Button(self, -1, label1)
145 self.GetSizer().Add(button1, pos=(self.rowNr, 0), flag=wx.RIGHT)
146 button2 = wx.Button(self, -1, label2)
147 self.GetSizer().Add(button2, pos=(self.rowNr, 1))
149 return button1, button2
151 def AddTextCtrl(self, value):
152 ret = wx.TextCtrl(self, -1, value)
153 self.GetSizer().Add(ret, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT)
157 def AddLabelTextCtrl(self, info, value):
158 text = wx.StaticText(self, -1, info)
159 ret = wx.TextCtrl(self, -1, value)
160 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT)
161 self.GetSizer().Add(ret, pos=(self.rowNr, 1), span=(1, 1), flag=wx.LEFT)
165 def AddTextCtrlButton(self, value, buttonText):
166 text = wx.TextCtrl(self, -1, value)
167 button = wx.Button(self, -1, buttonText)
168 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT)
169 self.GetSizer().Add(button, pos=(self.rowNr, 1), span=(1, 1), flag=wx.LEFT)
173 def AddBitmap(self, bitmap):
174 bitmap = wx.StaticBitmap(self, -1, bitmap)
175 self.GetSizer().Add(bitmap, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT | wx.RIGHT)
179 def AddCheckmark(self, label, bitmap):
180 check = wx.StaticBitmap(self, -1, bitmap)
181 text = wx.StaticText(self, -1, label)
182 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
183 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1, 1), flag=wx.ALL)
194 class FirstInfoPage(InfoPage):
195 def __init__(self, parent):
196 super(FirstInfoPage, self).__init__(parent, "First time run wizard")
197 self.AddText('Welcome, and thanks for trying Cura!')
199 self.AddText('This wizard will help you with the following steps:')
200 self.AddText('* Configure Cura for your machine')
201 self.AddText('* Upgrade your firmware')
202 self.AddText('* Check if your machine is working safely')
204 #self.AddText('* Calibrate your machine')
205 #self.AddText('* Do your first print')
208 class RepRapInfoPage(InfoPage):
209 def __init__(self, parent):
210 super(RepRapInfoPage, self).__init__(parent, "RepRap information")
212 'RepRap machines are vastly different, and there is no\ndefault configuration in Cura for any of them.')
213 self.AddText('If you like a default profile for your machine added,\nthen make an issue on github.')
215 self.AddText('You will have to manually install Marlin or Sprinter firmware.')
217 self.machineWidth = self.AddLabelTextCtrl('Machine width (mm)', '80')
218 self.machineDepth = self.AddLabelTextCtrl('Machine depth (mm)', '80')
219 self.machineHeight = self.AddLabelTextCtrl('Machine height (mm)', '60')
220 self.nozzleSize = self.AddLabelTextCtrl('Nozzle size (mm)', '0.5')
221 self.heatedBed = self.AddCheckbox('Heated bed')
224 profile.putPreference('machine_width', self.machineWidth.GetValue())
225 profile.putPreference('machine_depth', self.machineDepth.GetValue())
226 profile.putPreference('machine_height', self.machineHeight.GetValue())
227 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
228 profile.putProfileSetting('machine_center_x', profile.getPreferenceFloat('machine_width') / 2)
229 profile.putProfileSetting('machine_center_y', profile.getPreferenceFloat('machine_depth') / 2)
230 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
231 profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
234 class MachineSelectPage(InfoPage):
235 def __init__(self, parent):
236 super(MachineSelectPage, self).__init__(parent, "Select your machine")
237 self.AddText('What kind of machine do you have:')
239 self.UltimakerRadio = self.AddRadioButton("Ultimaker", style=wx.RB_GROUP)
240 self.UltimakerRadio.SetValue(True)
241 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)
242 self.OtherRadio = self.AddRadioButton("Other (Ex: RepRap)")
243 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
245 def OnUltimakerSelect(self, e):
246 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
248 def OnOtherSelect(self, e):
249 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().repRapInfoPage)
252 if self.UltimakerRadio.GetValue():
253 profile.putPreference('machine_width', '205')
254 profile.putPreference('machine_depth', '205')
255 profile.putPreference('machine_height', '200')
256 profile.putPreference('machine_type', 'ultimaker')
257 profile.putProfileSetting('nozzle_size', '0.4')
258 profile.putProfileSetting('machine_center_x', '100')
259 profile.putProfileSetting('machine_center_y', '100')
261 profile.putPreference('machine_width', '80')
262 profile.putPreference('machine_depth', '80')
263 profile.putPreference('machine_height', '60')
264 profile.putPreference('machine_type', 'reprap')
265 profile.putPreference('startMode', 'Normal')
266 profile.putProfileSetting('nozzle_size', '0.5')
267 profile.putProfileSetting('machine_center_x', '40')
268 profile.putProfileSetting('machine_center_y', '40')
269 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
272 class FirmwareUpgradePage(InfoPage):
273 def __init__(self, parent):
274 super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")
276 'Firmware is the piece of software running directly on your 3D printer.\nThis firmware controls the step motors, regulates the temperature\nand ultimately makes your printer work.')
277 self.AddHiddenSeperator()
279 'The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')
280 self.AddHiddenSeperator()
282 'Cura requires these new features and thus\nyour firmware will most likely need to be upgraded.\nYou will get the chance to do so now.')
283 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
284 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
285 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
286 self.AddHiddenSeperator()
287 self.AddText('Do not upgrade to this firmware if:')
288 self.AddText('* You have an older machine based on ATMega1280')
289 self.AddText('* Have other changes in the firmware')
290 button = self.AddButton('Goto this page for a custom firmware')
291 button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
296 def OnUpgradeClick(self, e):
297 if firmwareInstall.InstallFirmware():
298 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
300 def OnSkipClick(self, e):
301 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
303 def OnUrlClick(self, e):
304 webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')
307 class UltimakerCheckupPage(InfoPage):
308 def __init__(self, parent):
309 super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")
311 self.checkBitmap = wx.Bitmap(getPathForImage('checkmark.png'))
312 self.crossBitmap = wx.Bitmap(getPathForImage('cross.png'))
313 self.unknownBitmap = wx.Bitmap(getPathForImage('question.png'))
314 self.endStopNoneBitmap = wx.Bitmap(getPathForImage('endstop_none.png'))
315 self.endStopXMinBitmap = wx.Bitmap(getPathForImage('endstop_xmin.png'))
316 self.endStopXMaxBitmap = wx.Bitmap(getPathForImage('endstop_xmax.png'))
317 self.endStopYMinBitmap = wx.Bitmap(getPathForImage('endstop_ymin.png'))
318 self.endStopYMaxBitmap = wx.Bitmap(getPathForImage('endstop_ymax.png'))
319 self.endStopZMinBitmap = wx.Bitmap(getPathForImage('endstop_zmin.png'))
320 self.endStopZMaxBitmap = wx.Bitmap(getPathForImage('endstop_zmax.png'))
323 'It is a good idea to do a few sanity checks now on your Ultimaker.\nYou can skip these if you know your machine is functional.')
324 b1, b2 = self.AddDualButton('Run checks', 'Skip checks')
325 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
326 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
328 self.commState = self.AddCheckmark('Communication:', self.unknownBitmap)
329 self.tempState = self.AddCheckmark('Temperature:', self.unknownBitmap)
330 self.stopState = self.AddCheckmark('Endstops:', self.unknownBitmap)
332 self.infoBox = self.AddInfoBox()
333 self.machineState = self.AddText('')
334 self.temperatureLabel = self.AddText('')
336 self.endstopBitmap = self.AddBitmap(self.endStopNoneBitmap)
338 self.xMinStop = False
339 self.xMaxStop = False
340 self.yMinStop = False
341 self.yMaxStop = False
342 self.zMinStop = False
343 self.zMaxStop = False
346 if self.comm != None:
350 self.endstopBitmap.Show(False)
353 def OnSkipClick(self, e):
354 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
356 def OnCheckClick(self, e=None):
357 if self.comm != None:
361 wx.CallAfter(self.OnCheckClick)
363 self.infoBox.SetInfo('Connecting to machine.')
364 self.infoBox.SetBusyIndicator()
365 self.commState.SetBitmap(self.unknownBitmap)
366 self.tempState.SetBitmap(self.unknownBitmap)
367 self.stopState.SetBitmap(self.unknownBitmap)
368 self.checkupState = 0
369 self.comm = machineCom.MachineCom(callbackObject=self)
371 def mcLog(self, message):
374 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
375 if not self.comm.isOperational():
377 if self.checkupState == 0:
378 self.tempCheckTimeout = 20
380 self.checkupState = 1
381 wx.CallAfter(self.infoBox.SetInfo, 'Cooldown before temperature check.')
382 self.comm.sendCommand('M104 S0')
383 self.comm.sendCommand('M104 S0')
385 self.startTemp = temp
386 self.checkupState = 2
387 wx.CallAfter(self.infoBox.SetInfo, 'Checking the heater and temperature sensor.')
388 self.comm.sendCommand('M104 S200')
389 self.comm.sendCommand('M104 S200')
390 elif self.checkupState == 1:
392 self.startTemp = temp
393 self.checkupState = 2
394 wx.CallAfter(self.infoBox.SetInfo, 'Checking the heater and temperature sensor.')
395 self.comm.sendCommand('M104 S200')
396 self.comm.sendCommand('M104 S200')
397 elif self.checkupState == 2:
398 #print "WARNING, TEMPERATURE TEST DISABLED FOR TESTING!"
399 if temp > self.startTemp + 40:
400 self.checkupState = 3
401 wx.CallAfter(self.infoBox.SetAttention, 'Please make sure none of the endstops are pressed.')
402 wx.CallAfter(self.endstopBitmap.Show, True)
403 wx.CallAfter(self.Layout)
404 self.comm.sendCommand('M104 S0')
405 self.comm.sendCommand('M104 S0')
406 self.comm.sendCommand('M119')
407 wx.CallAfter(self.tempState.SetBitmap, self.checkBitmap)
409 self.tempCheckTimeout -= 1
410 if self.tempCheckTimeout < 1:
411 self.checkupState = -1
412 wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap)
413 wx.CallAfter(self.infoBox.SetError, 'Temperature measurement FAILED!')
414 self.comm.sendCommand('M104 S0')
415 self.comm.sendCommand('M104 S0')
416 wx.CallAfter(self.temperatureLabel.SetLabel, 'Head temperature: %d' % (temp))
418 def mcStateChange(self, state):
419 if self.comm == None:
421 if self.comm.isOperational():
422 wx.CallAfter(self.commState.SetBitmap, self.checkBitmap)
423 elif self.comm.isError():
424 wx.CallAfter(self.commState.SetBitmap, self.crossBitmap)
425 wx.CallAfter(self.infoBox.SetError, 'Failed to establish connection with the printer.')
426 wx.CallAfter(self.endstopBitmap.Show, False)
427 wx.CallAfter(self.machineState.SetLabel, 'Communication State: %s' % (self.comm.getStateString()))
429 def mcMessage(self, message):
430 if self.checkupState >= 3 and self.checkupState < 10 and 'x_min' in message:
431 for data in message.split(' '):
433 tag, value = data.split(':', 2)
435 self.xMinStop = (value == 'H')
437 self.xMaxStop = (value == 'H')
439 self.yMinStop = (value == 'H')
441 self.yMaxStop = (value == 'H')
443 self.zMinStop = (value == 'H')
445 self.zMaxStop = (value == 'H')
446 self.comm.sendCommand('M119')
448 if self.checkupState == 3:
449 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
450 self.checkupState = 4
451 wx.CallAfter(self.infoBox.SetAttention, 'Please press the right X endstop.')
452 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMaxBitmap)
453 elif self.checkupState == 4:
454 if not self.xMinStop and self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
455 self.checkupState = 5
456 wx.CallAfter(self.infoBox.SetAttention, 'Please press the left X endstop.')
457 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
458 elif self.checkupState == 5:
459 if self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
460 self.checkupState = 6
461 wx.CallAfter(self.infoBox.SetAttention, 'Please press the front Y endstop.')
462 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMinBitmap)
463 elif self.checkupState == 6:
464 if not self.xMinStop and not self.xMaxStop and self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
465 self.checkupState = 7
466 wx.CallAfter(self.infoBox.SetAttention, 'Please press the back Y endstop.')
467 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMaxBitmap)
468 elif self.checkupState == 7:
469 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and self.yMaxStop and not self.zMinStop and not self.zMaxStop:
470 self.checkupState = 8
471 wx.CallAfter(self.infoBox.SetAttention, 'Please press the top Z endstop.')
472 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
473 elif self.checkupState == 8:
474 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and self.zMinStop and not self.zMaxStop:
475 self.checkupState = 9
476 wx.CallAfter(self.infoBox.SetAttention, 'Please press the bottom Z endstop.')
477 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMaxBitmap)
478 elif self.checkupState == 9:
479 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and self.zMaxStop:
480 self.checkupState = 10
482 wx.CallAfter(self.infoBox.SetInfo, 'Checkup finished')
483 wx.CallAfter(self.infoBox.SetReadyIndicator)
484 wx.CallAfter(self.endstopBitmap.Show, False)
485 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
486 wx.CallAfter(self.OnSkipClick, None)
488 def mcProgress(self, lineNr):
491 def mcZChange(self, newZ):
495 class UltimakerCalibrationPage(InfoPage):
496 def __init__(self, parent):
497 super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")
499 self.AddText("Your Ultimaker requires some calibration.")
500 self.AddText("This calibration is needed for a proper extrusion amount.")
502 self.AddText("The following values are needed:")
503 self.AddText("* Diameter of filament")
504 self.AddText("* Number of steps per mm of filament extrusion")
506 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
508 self.AddText("First we need the diameter of your filament:")
509 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
511 "If you do not own digital Calipers that can measure\nat least 2 digits then use 2.89mm.\nWhich is the average diameter of most filament.")
512 self.AddText("Note: This value can be changed later at any time.")
515 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
518 class UltimakerCalibrateStepsPerEPage(InfoPage):
519 def __init__(self, parent):
520 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")
522 if profile.getPreference('steps_per_e') == '0':
523 profile.putPreference('steps_per_e', '865.888')
525 self.AddText("Calibrating the Steps Per E requires some manual actions.")
526 self.AddText("First remove any filament from your machine.")
527 self.AddText("Next put in your filament so the tip is aligned with the\ntop of the extruder drive.")
528 self.AddText("We'll push the filament 100mm")
529 self.extrudeButton = self.AddButton("Extrude 100mm filament")
530 self.AddText("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)")
531 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton('100', 'Save')
532 self.AddText("This results in the following steps per E:")
533 self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e'))
534 self.AddText("You can repeat these steps to get better calibration.")
537 "If you still have filament in your printer which needs\nheat to remove, press the heat up button below:")
538 self.heatButton = self.AddButton("Heatup for filament removal")
540 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
541 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
542 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
544 def OnSaveLengthClick(self, e):
545 currentEValue = float(self.stepsPerEInput.GetValue())
546 realExtrudeLength = float(self.lengthInput.GetValue())
547 newEValue = currentEValue * 100 / realExtrudeLength
548 self.stepsPerEInput.SetValue(str(newEValue))
549 self.lengthInput.SetValue("100")
551 def OnExtrudeClick(self, e):
552 threading.Thread(target=self.OnExtrudeRun).start()
554 def OnExtrudeRun(self):
555 self.heatButton.Enable(False)
556 self.extrudeButton.Enable(False)
557 currentEValue = float(self.stepsPerEInput.GetValue())
558 self.comm = machineCom.MachineCom()
559 if not self.comm.isOpen():
561 "Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable",
562 'Printer error', wx.OK | wx.ICON_INFORMATION)
563 self.heatButton.Enable(True)
564 self.extrudeButton.Enable(True)
567 line = self.comm.readline()
572 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
575 self.sendGCommand('M302') #Disable cold extrusion protection
576 self.sendGCommand("M92 E%f" % (currentEValue))
577 self.sendGCommand("G92 E0")
578 self.sendGCommand("G1 E100 F600")
581 self.extrudeButton.Enable()
582 self.heatButton.Enable()
584 def OnHeatClick(self, e):
585 threading.Thread(target=self.OnHeatRun).start()
588 self.heatButton.Enable(False)
589 self.extrudeButton.Enable(False)
590 self.comm = machineCom.MachineCom()
591 if not self.comm.isOpen():
593 "Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable",
594 'Printer error', wx.OK | wx.ICON_INFORMATION)
595 self.heatButton.Enable(True)
596 self.extrudeButton.Enable(True)
599 line = self.comm.readline()
601 self.heatButton.Enable(True)
602 self.extrudeButton.Enable(True)
606 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
609 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
611 'Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)',
612 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
613 self.sendGCommand('M104 S0')
616 self.heatButton.Enable(True)
617 self.extrudeButton.Enable(True)
619 def sendGCommand(self, cmd):
620 self.comm.sendCommand(cmd) #Disable cold extrusion protection
622 line = self.comm.readline()
625 if line.startswith('ok'):
629 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
632 class configWizard(wx.wizard.Wizard):
634 super(configWizard, self).__init__(None, -1, "Configuration Wizard")
636 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
637 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
639 self.firstInfoPage = FirstInfoPage(self)
640 self.machineSelectPage = MachineSelectPage(self)
641 self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)
642 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
643 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
644 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
645 self.repRapInfoPage = RepRapInfoPage(self)
647 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
648 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage)
649 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
650 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage)
651 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
653 self.FitToPage(self.firstInfoPage)
654 self.GetPageAreaSizer().Add(self.firstInfoPage)
656 self.RunWizard(self.firstInfoPage)
659 def OnPageChanging(self, e):
660 e.GetPage().StoreData()
662 def OnPageChanged(self, e):
663 if e.GetPage().AllowNext():
664 self.FindWindowById(wx.ID_FORWARD).Enable()
666 self.FindWindowById(wx.ID_FORWARD).Disable()
667 self.FindWindowById(wx.ID_BACKWARD).Disable()