1 from __future__ import absolute_import
\r
4 import wx, os, platform, types, webbrowser, threading, time, re
\r
7 from gui import firmwareInstall
\r
8 from gui import toolbarUtil
\r
9 from util import machineCom
\r
10 from util import profile
\r
12 class InfoBox(wx.Panel):
\r
13 def __init__(self, parent):
\r
14 super(InfoBox, self).__init__(parent)
\r
15 self.SetBackgroundColour('#FFFF80')
\r
17 self.sizer = wx.GridBagSizer(5, 5)
\r
18 self.SetSizer(self.sizer)
\r
20 self.attentionBitmap = toolbarUtil.getBitmapImage('attention.png')
\r
21 self.errorBitmap = toolbarUtil.getBitmapImage('error.png')
\r
22 self.readyBitmap = toolbarUtil.getBitmapImage('ready.png')
\r
23 self.busyBitmap = [toolbarUtil.getBitmapImage('busy-0.png'), toolbarUtil.getBitmapImage('busy-1.png'), toolbarUtil.getBitmapImage('busy-2.png'), toolbarUtil.getBitmapImage('busy-3.png')]
\r
25 self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1))
\r
26 self.text = wx.StaticText(self, -1, '')
\r
27 self.sizer.Add(self.bitmap, pos=(0,0), flag=wx.ALL, border=5)
\r
28 self.sizer.Add(self.text, pos=(0,1), flag=wx.TOP|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, border=5)
\r
30 self.busyState = None
\r
31 self.timer = wx.Timer(self)
\r
32 self.Bind(wx.EVT_TIMER, self.doBusyUpdate, self.timer)
\r
33 self.timer.Start(100)
\r
35 def SetInfo(self, info):
\r
36 self.SetBackgroundColour('#FFFF80')
\r
37 self.text.SetLabel(info)
\r
40 def SetError(self, info):
\r
41 self.SetBackgroundColour('#FF8080')
\r
42 self.text.SetLabel(info)
\r
43 self.SetErrorIndicator()
\r
46 def SetAttention(self, info):
\r
47 self.SetBackgroundColour('#FFFF80')
\r
48 self.text.SetLabel(info)
\r
49 self.SetAttentionIndicator()
\r
52 def SetBusyIndicator(self):
\r
54 self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
\r
56 def doBusyUpdate(self, e):
\r
57 if self.busyState == None:
\r
60 if self.busyState >= len(self.busyBitmap):
\r
62 self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
\r
64 def SetReadyIndicator(self):
\r
65 self.busyState = None
\r
66 self.bitmap.SetBitmap(self.readyBitmap)
\r
68 def SetErrorIndicator(self):
\r
69 self.busyState = None
\r
70 self.bitmap.SetBitmap(self.errorBitmap)
\r
72 def SetAttentionIndicator(self):
\r
73 self.busyState = None
\r
74 self.bitmap.SetBitmap(self.attentionBitmap)
\r
76 class InfoPage(wx.wizard.WizardPageSimple):
\r
77 def __init__(self, parent, title):
\r
78 wx.wizard.WizardPageSimple.__init__(self, parent)
\r
80 sizer = wx.GridBagSizer(5, 5)
\r
82 self.SetSizer(sizer)
\r
84 title = wx.StaticText(self, -1, title)
\r
85 title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
\r
86 sizer.Add(title, pos=(0, 0), span=(1,2), flag=wx.ALIGN_CENTRE|wx.ALL)
\r
87 sizer.Add(wx.StaticLine(self, -1), pos=(1,0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
88 sizer.AddGrowableCol(1)
\r
92 def AddText(self,info):
\r
93 text = wx.StaticText(self, -1, info)
\r
94 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT|wx.RIGHT)
\r
98 def AddSeperator(self):
\r
99 self.GetSizer().Add(wx.StaticLine(self, -1), pos=(self.rowNr, 0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
102 def AddHiddenSeperator(self):
\r
105 def AddInfoBox(self):
\r
106 infoBox = InfoBox(self)
\r
107 self.GetSizer().Add(infoBox, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT|wx.RIGHT|wx.EXPAND)
\r
111 def AddRadioButton(self, label, style = 0):
\r
112 radio = wx.RadioButton(self, -1, label, style=style)
\r
113 self.GetSizer().Add(radio, pos=(self.rowNr, 0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
117 def AddCheckbox(self, label, checked = False):
\r
118 check = wx.CheckBox(self, -1)
\r
119 text = wx.StaticText(self, -1, label)
\r
120 check.SetValue(checked)
\r
121 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT|wx.RIGHT)
\r
122 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1,2), flag=wx.ALL)
\r
126 def AddButton(self, label):
\r
127 button = wx.Button(self, -1, label)
\r
128 self.GetSizer().Add(button, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT)
\r
132 def AddDualButton(self, label1, label2):
\r
133 button1 = wx.Button(self, -1, label1)
\r
134 self.GetSizer().Add(button1, pos=(self.rowNr, 0), flag=wx.RIGHT)
\r
135 button2 = wx.Button(self, -1, label2)
\r
136 self.GetSizer().Add(button2, pos=(self.rowNr, 1))
\r
138 return button1, button2
\r
140 def AddTextCtrl(self, value):
\r
141 ret = wx.TextCtrl(self, -1, value)
\r
142 self.GetSizer().Add(ret, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT)
\r
146 def AddLabelTextCtrl(self, info, value):
\r
147 text = wx.StaticText(self, -1, info)
\r
148 ret = wx.TextCtrl(self, -1, value)
\r
149 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT)
\r
150 self.GetSizer().Add(ret, pos=(self.rowNr, 1), span=(1,1), flag=wx.LEFT)
\r
154 def AddTextCtrlButton(self, value, buttonText):
\r
155 text = wx.TextCtrl(self, -1, value)
\r
156 button = wx.Button(self, -1, buttonText)
\r
157 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT)
\r
158 self.GetSizer().Add(button, pos=(self.rowNr, 1), span=(1,1), flag=wx.LEFT)
\r
160 return text, button
\r
162 def AddCheckmark(self, label, bitmap):
\r
163 check = wx.StaticBitmap(self, -1, bitmap)
\r
164 text = wx.StaticText(self, -1, label)
\r
165 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT|wx.RIGHT)
\r
166 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1,2), flag=wx.ALL)
\r
170 def AllowNext(self):
\r
173 def StoreData(self):
\r
176 class FirstInfoPage(InfoPage):
\r
177 def __init__(self, parent):
\r
178 super(FirstInfoPage, self).__init__(parent, "First time run wizard")
\r
179 self.AddText('Welcome, and thanks for trying Cura!')
\r
180 self.AddSeperator()
\r
181 self.AddText('This wizard will help you with the following steps:')
\r
182 self.AddText('* Configure Cura for your machine')
\r
183 self.AddText('* Upgrade your firmware')
\r
184 self.AddText('* Check if your machine is working safely')
\r
185 #self.AddText('* Calibrate your machine')
\r
186 #self.AddText('* Do your first print')
\r
188 class RepRapInfoPage(InfoPage):
\r
189 def __init__(self, parent):
\r
190 super(RepRapInfoPage, self).__init__(parent, "RepRap information")
\r
191 self.AddText('RepRap machines are vastly different, and there is no\ndefault configuration in Cura for any of them.')
\r
192 self.AddText('If you like a default profile for your machine added,\nthen make an issue on github.')
\r
193 self.AddSeperator()
\r
194 self.AddText('You will have to manually install Marlin or Sprinter firmware.')
\r
195 self.AddSeperator()
\r
196 self.machineWidth = self.AddLabelTextCtrl('Machine width (mm)', '80')
\r
197 self.machineDepth = self.AddLabelTextCtrl('Machine depth (mm)', '80')
\r
198 self.machineHeight = self.AddLabelTextCtrl('Machine height (mm)', '60')
\r
199 self.nozzleSize = self.AddLabelTextCtrl('Nozzle size (mm)', '0.5')
\r
200 self.heatedBed = self.AddCheckbox('Heated bed')
\r
202 def StoreData(self):
\r
203 profile.putPreference('machine_width', self.machineWidth.GetValue())
\r
204 profile.putPreference('machine_depth', self.machineDepth.GetValue())
\r
205 profile.putPreference('machine_height', self.machineHeight.GetValue())
\r
206 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
\r
207 profile.putProfileSetting('machine_center_x', profile.getPreferenceFloat('machine_width') / 2)
\r
208 profile.putProfileSetting('machine_center_y', profile.getPreferenceFloat('machine_depth') / 2)
\r
209 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
\r
210 profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
\r
212 class MachineSelectPage(InfoPage):
\r
213 def __init__(self, parent):
\r
214 super(MachineSelectPage, self).__init__(parent, "Select your machine")
\r
215 self.AddText('What kind of machine do you have:')
\r
217 self.UltimakerRadio = self.AddRadioButton("Ultimaker", style=wx.RB_GROUP)
\r
218 self.UltimakerRadio.SetValue(True)
\r
219 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)
\r
220 self.OtherRadio = self.AddRadioButton("Other (Ex: RepRap)")
\r
221 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
\r
223 def OnUltimakerSelect(self, e):
\r
224 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
\r
226 def OnOtherSelect(self, e):
\r
227 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().repRapInfoPage)
\r
229 def StoreData(self):
\r
230 if self.UltimakerRadio.GetValue():
\r
231 profile.putPreference('machine_width', '205')
\r
232 profile.putPreference('machine_depth', '205')
\r
233 profile.putPreference('machine_height', '200')
\r
234 profile.putPreference('machine_type', 'ultimaker')
\r
235 profile.putProfileSetting('nozzle_size', '0.4')
\r
236 profile.putProfileSetting('machine_center_x', '100')
\r
237 profile.putProfileSetting('machine_center_y', '100')
\r
239 profile.putPreference('machine_width', '80')
\r
240 profile.putPreference('machine_depth', '80')
\r
241 profile.putPreference('machine_height', '60')
\r
242 profile.putPreference('machine_type', 'reprap')
\r
243 profile.putProfileSetting('nozzle_size', '0.5')
\r
244 profile.putProfileSetting('machine_center_x', '40')
\r
245 profile.putProfileSetting('machine_center_y', '40')
\r
246 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
\r
248 class FirmwareUpgradePage(InfoPage):
\r
249 def __init__(self, parent):
\r
250 super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")
\r
251 self.AddText('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.')
\r
252 self.AddHiddenSeperator()
\r
253 self.AddText('The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')
\r
254 self.AddHiddenSeperator()
\r
255 self.AddText('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.')
\r
256 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
\r
257 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
\r
258 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
\r
259 self.AddHiddenSeperator()
\r
260 self.AddText('Do not upgrade to this firmware if:')
\r
261 self.AddText('* You have an older machine based on ATMega1280')
\r
262 self.AddText('* Have other changes in the firmware')
\r
263 button = self.AddButton('Goto this page for a custom firmware')
\r
264 button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
\r
266 def AllowNext(self):
\r
269 def OnUpgradeClick(self, e):
\r
270 if firmwareInstall.InstallFirmware():
\r
271 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
273 def OnSkipClick(self, e):
\r
274 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
276 def OnUrlClick(self, e):
\r
277 webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')
\r
279 class UltimakerCheckupPage(InfoPage):
\r
280 def __init__(self, parent):
\r
281 super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")
\r
282 self.AddText('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.')
\r
283 b1, b2 = self.AddDualButton('Run checks', 'Skip checks')
\r
284 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
\r
285 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
\r
286 self.AddSeperator()
\r
287 self.checkBitmap = toolbarUtil.getBitmapImage('checkmark.png')
\r
288 self.crossBitmap = toolbarUtil.getBitmapImage('cross.png')
\r
289 self.unknownBitmap = toolbarUtil.getBitmapImage('question.png')
\r
290 self.commState = self.AddCheckmark('Communication:', self.unknownBitmap)
\r
291 self.tempState = self.AddCheckmark('Temperature:', self.unknownBitmap)
\r
292 self.stopState = self.AddCheckmark('Endstops:', self.unknownBitmap)
\r
293 self.AddSeperator()
\r
294 self.infoBox = self.AddInfoBox()
\r
295 self.machineState = self.AddText('')
\r
296 self.temperatureLabel = self.AddText('')
\r
297 self.AddSeperator()
\r
298 self.xMinState = self.AddCheckmark('X stop left:', self.unknownBitmap)
\r
299 self.xMaxState = self.AddCheckmark('X stop right:', self.unknownBitmap)
\r
300 self.yMinState = self.AddCheckmark('Y stop front:', self.unknownBitmap)
\r
301 self.yMaxState = self.AddCheckmark('Y stop back:', self.unknownBitmap)
\r
302 self.zMinState = self.AddCheckmark('Z stop top:', self.unknownBitmap)
\r
303 self.zMaxState = self.AddCheckmark('Z stop bottom:', self.unknownBitmap)
\r
305 self.xMinStop = False
\r
306 self.xMaxStop = False
\r
307 self.yMinStop = False
\r
308 self.yMaxStop = False
\r
309 self.zMinStop = False
\r
310 self.zMaxStop = False
\r
313 if self.comm != None:
\r
316 def AllowNext(self):
\r
319 def OnSkipClick(self, e):
\r
320 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
322 def OnCheckClick(self, e):
\r
323 if self.comm != None:
\r
326 self.infoBox.SetInfo('Connecting to machine.')
\r
327 self.infoBox.SetBusyIndicator()
\r
328 self.commState.SetBitmap(self.unknownBitmap)
\r
329 self.tempState.SetBitmap(self.unknownBitmap)
\r
330 self.stopState.SetBitmap(self.unknownBitmap)
\r
331 self.checkupState = 0
\r
332 self.comm = machineCom.MachineCom(callbackObject=self)
\r
334 def mcLog(self, message):
\r
337 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
\r
338 if self.checkupState == 0:
\r
339 self.tempCheckTimeout = 20
\r
341 self.checkupState = 1
\r
342 wx.CallAfter(self.infoBox.SetInfo, 'Cooldown before temperature check.')
\r
343 self.comm.sendCommand('M104 S0')
\r
344 self.comm.sendCommand('M104 S0')
\r
346 self.startTemp = temp
\r
347 self.checkupState = 2
\r
348 wx.CallAfter(self.infoBox.SetInfo, 'Checking the heater and temperature sensor.')
\r
349 self.comm.sendCommand('M104 S200')
\r
350 self.comm.sendCommand('M104 S200')
\r
351 elif self.checkupState == 1:
\r
353 self.startTemp = temp
\r
354 self.checkupState = 2
\r
355 wx.CallAfter(self.infoBox.SetInfo, 'Checking the heater and temperature sensor.')
\r
356 self.comm.sendCommand('M104 S200')
\r
357 self.comm.sendCommand('M104 S200')
\r
358 elif self.checkupState == 2:
\r
359 print "WARNING, TEMPERATURE TEST DISABLED FOR TESTING!"
\r
360 if temp > self.startTemp:# + 40:
\r
361 self.checkupState = 3
\r
362 wx.CallAfter(self.infoBox.SetAttention, 'Please make sure none of the endstops are pressed.')
\r
363 self.comm.sendCommand('M104 S0')
\r
364 self.comm.sendCommand('M104 S0')
\r
365 self.comm.sendCommand('M119')
\r
366 wx.CallAfter(self.tempState.SetBitmap, self.checkBitmap)
\r
368 self.tempCheckTimeout -= 1
\r
369 if self.tempCheckTimeout < 1:
\r
370 self.checkupState = -1
\r
371 wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap)
\r
372 wx.CallAfter(self.infoBox.SetError, 'Temperature measurement FAILED!')
\r
373 self.comm.sendCommand('M104 S0')
\r
374 self.comm.sendCommand('M104 S0')
\r
375 wx.CallAfter(self.temperatureLabel.SetLabel, 'Head temperature: %d' % (temp))
\r
377 def mcStateChange(self, state):
\r
378 if self.comm == None:
\r
380 if self.comm.isOperational():
\r
381 wx.CallAfter(self.commState.SetBitmap, self.checkBitmap)
\r
382 elif self.comm.isError():
\r
383 wx.CallAfter(self.commState.SetBitmap, self.crossBitmap)
\r
384 wx.CallAfter(self.infoBox.SetError, 'Failed to establish connection with the printer.')
\r
385 wx.CallAfter(self.machineState.SetLabel, 'Communication State: %s' % (self.comm.getStateString()))
\r
387 def mcMessage(self, message):
\r
388 if self.checkupState >= 3 and self.checkupState < 10 and 'x_min' in message:
\r
389 for data in message.split(' '):
\r
391 tag, value = data.split(':', 2)
\r
393 self.xMinStop = (value == 'H')
\r
395 self.xMaxStop = (value == 'H')
\r
397 self.yMinStop = (value == 'H')
\r
399 self.yMaxStop = (value == 'H')
\r
401 self.zMinStop = (value == 'H')
\r
403 self.zMaxStop = (value == 'H')
\r
404 self.comm.sendCommand('M119')
\r
407 self.xMinState.SetBitmap(self.checkBitmap)
\r
409 self.xMinState.SetBitmap(self.crossBitmap)
\r
411 self.xMaxState.SetBitmap(self.checkBitmap)
\r
413 self.xMaxState.SetBitmap(self.crossBitmap)
\r
415 self.yMinState.SetBitmap(self.checkBitmap)
\r
417 self.yMinState.SetBitmap(self.crossBitmap)
\r
419 self.yMaxState.SetBitmap(self.checkBitmap)
\r
421 self.yMaxState.SetBitmap(self.crossBitmap)
\r
423 self.zMinState.SetBitmap(self.checkBitmap)
\r
425 self.zMinState.SetBitmap(self.crossBitmap)
\r
427 self.zMaxState.SetBitmap(self.checkBitmap)
\r
429 self.zMaxState.SetBitmap(self.crossBitmap)
\r
431 if self.checkupState == 3:
\r
432 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
\r
433 self.checkupState = 4
\r
434 wx.CallAfter(self.infoBox.SetAttention, 'Please press the left X endstop.')
\r
435 elif self.checkupState == 4:
\r
436 if self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
\r
437 self.checkupState = 5
\r
438 wx.CallAfter(self.infoBox.SetAttention, 'Please press the right X endstop.')
\r
439 elif self.checkupState == 5:
\r
440 if not self.xMinStop and self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
\r
441 self.checkupState = 6
\r
442 wx.CallAfter(self.infoBox.SetAttention, 'Please press the front Y endstop.')
\r
443 elif self.checkupState == 6:
\r
444 if not self.xMinStop and not self.xMaxStop and self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
\r
445 self.checkupState = 7
\r
446 wx.CallAfter(self.infoBox.SetAttention, 'Please press the back Y endstop.')
\r
447 elif self.checkupState == 7:
\r
448 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and self.yMaxStop and not self.zMinStop and not self.zMaxStop:
\r
449 self.checkupState = 8
\r
450 wx.CallAfter(self.infoBox.SetAttention, 'Please press the top Z endstop.')
\r
451 elif self.checkupState == 8:
\r
452 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and self.zMinStop and not self.zMaxStop:
\r
453 self.checkupState = 9
\r
454 wx.CallAfter(self.infoBox.SetAttention, 'Please press the bottom Z endstop.')
\r
455 elif self.checkupState == 9:
\r
456 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and self.zMaxStop:
\r
457 self.checkupState = 10
\r
459 wx.CallAfter(self.infoBox.SetInfo, 'Checkup finished')
\r
460 wx.CallAfter(self.infoBox.SetReadyIndicator)
\r
461 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
\r
462 wx.CallAfter(self.OnSkipClick, None)
\r
464 def mcProgress(self, lineNr):
\r
467 def mcZChange(self, newZ):
\r
470 class UltimakerCalibrationPage(InfoPage):
\r
471 def __init__(self, parent):
\r
472 super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")
\r
474 self.AddText("Your Ultimaker requires some calibration.")
\r
475 self.AddText("This calibration is needed for a proper extrusion amount.")
\r
476 self.AddSeperator()
\r
477 self.AddText("The following values are needed:")
\r
478 self.AddText("* Diameter of filament")
\r
479 self.AddText("* Number of steps per mm of filament extrusion")
\r
480 self.AddSeperator()
\r
481 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
\r
482 self.AddSeperator()
\r
483 self.AddText("First we need the diameter of your filament:")
\r
484 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
\r
485 self.AddText("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.")
\r
486 self.AddText("Note: This value can be changed later at any time.")
\r
488 def StoreData(self):
\r
489 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
\r
491 class UltimakerCalibrateStepsPerEPage(InfoPage):
\r
492 def __init__(self, parent):
\r
493 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")
\r
495 if profile.getPreference('steps_per_e') == '0':
\r
496 profile.putPreference('steps_per_e', '865.888')
\r
498 self.AddText("Calibrating the Steps Per E requires some manual actions.")
\r
499 self.AddText("First remove any filament from your machine.")
\r
500 self.AddText("Next put in your filament so the tip is aligned with the\ntop of the extruder drive.")
\r
501 self.AddText("We'll push the filament 100mm")
\r
502 self.extrudeButton = self.AddButton("Extrude 100mm filament")
\r
503 self.AddText("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)")
\r
504 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton('100', 'Save')
\r
505 self.AddText("This results in the following steps per E:")
\r
506 self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e'))
\r
507 self.AddText("You can repeat these steps to get better calibration.")
\r
508 self.AddSeperator()
\r
509 self.AddText("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:")
\r
510 self.heatButton = self.AddButton("Heatup for filament removal")
\r
512 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
\r
513 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
\r
514 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
\r
516 def OnSaveLengthClick(self, e):
\r
517 currentEValue = float(self.stepsPerEInput.GetValue())
\r
518 realExtrudeLength = float(self.lengthInput.GetValue())
\r
519 newEValue = currentEValue * 100 / realExtrudeLength
\r
520 self.stepsPerEInput.SetValue(str(newEValue))
\r
521 self.lengthInput.SetValue("100")
\r
523 def OnExtrudeClick(self, e):
\r
524 threading.Thread(target=self.OnExtrudeRun).start()
\r
526 def OnExtrudeRun(self):
\r
527 self.heatButton.Enable(False)
\r
528 self.extrudeButton.Enable(False)
\r
529 currentEValue = float(self.stepsPerEInput.GetValue())
\r
530 self.comm = machineCom.MachineCom()
\r
531 if not self.comm.isOpen():
\r
532 wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION)
\r
533 self.heatButton.Enable(True)
\r
534 self.extrudeButton.Enable(True)
\r
537 line = self.comm.readline()
\r
540 if 'start' in line:
\r
542 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
\r
545 self.sendGCommand('M302') #Disable cold extrusion protection
\r
546 self.sendGCommand("M92 E%f" % (currentEValue))
\r
547 self.sendGCommand("G92 E0")
\r
548 self.sendGCommand("G1 E100 F600")
\r
551 self.extrudeButton.Enable()
\r
552 self.heatButton.Enable()
\r
554 def OnHeatClick(self, e):
\r
555 threading.Thread(target=self.OnHeatRun).start()
\r
557 def OnHeatRun(self):
\r
558 self.heatButton.Enable(False)
\r
559 self.extrudeButton.Enable(False)
\r
560 self.comm = machineCom.MachineCom()
\r
561 if not self.comm.isOpen():
\r
562 wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION)
\r
563 self.heatButton.Enable(True)
\r
564 self.extrudeButton.Enable(True)
\r
567 line = self.comm.readline()
\r
569 self.heatButton.Enable(True)
\r
570 self.extrudeButton.Enable(True)
\r
572 if 'start' in line:
\r
574 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
\r
577 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
\r
578 wx.MessageBox('Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)', 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
\r
579 self.sendGCommand('M104 S0')
\r
582 self.heatButton.Enable(True)
\r
583 self.extrudeButton.Enable(True)
\r
585 def sendGCommand(self, cmd):
\r
586 self.comm.sendCommand(cmd) #Disable cold extrusion protection
\r
588 line = self.comm.readline()
\r
591 if line.startswith('ok'):
\r
594 def StoreData(self):
\r
595 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
\r
597 class configWizard(wx.wizard.Wizard):
\r
598 def __init__(self):
\r
599 super(configWizard, self).__init__(None, -1, "Configuration Wizard")
\r
601 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
\r
602 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
\r
604 self.firstInfoPage = FirstInfoPage(self)
\r
605 self.machineSelectPage = MachineSelectPage(self)
\r
606 self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)
\r
607 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
\r
608 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
\r
609 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
\r
610 self.repRapInfoPage = RepRapInfoPage(self)
\r
612 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
\r
613 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage)
\r
614 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
\r
615 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage)
\r
616 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
\r
618 self.FitToPage(self.firstInfoPage)
\r
619 self.GetPageAreaSizer().Add(self.firstInfoPage)
\r
621 self.RunWizard(self.firstInfoPage)
\r
624 def OnPageChanging(self, e):
\r
625 e.GetPage().StoreData()
\r
627 def OnPageChanged(self, e):
\r
628 if e.GetPage().AllowNext():
\r
629 self.FindWindowById(wx.ID_FORWARD).Enable()
\r
631 self.FindWindowById(wx.ID_FORWARD).Disable()
\r
632 self.FindWindowById(wx.ID_BACKWARD).Disable()
\r