diff --git a/Cura/alterations/start.gcode b/Cura/alterations/start.gcode index 4f1222a5..7db5699c 100644 --- a/Cura/alterations/start.gcode +++ b/Cura/alterations/start.gcode @@ -4,8 +4,6 @@ G90 ;absolute positioning G28 X0 Y0 ;move X/Y to min endstops G28 Z0 ;move Z to min endstops -M106 ;turn on fan - ; if your prints start too high, try changing the Z0.0 below ; to Z1.0 - the number after the Z is the actual, physical ; height of the nozzle in mm. This can take some messing around diff --git a/Cura/cura_sf/fabmetheus_utilities/settings.py b/Cura/cura_sf/fabmetheus_utilities/settings.py index f89fa870..aeb64c15 100644 --- a/Cura/cura_sf/fabmetheus_utilities/settings.py +++ b/Cura/cura_sf/fabmetheus_utilities/settings.py @@ -265,9 +265,11 @@ def getProfileInformation(): 'Name_of_Cool_End_File': DEFSET, 'Name_of_Cool_Start_File': DEFSET, 'Orbital_Outset_millimeters': DEFSET, - 'Turn_Fan_On_at_Beginning': "False", + 'Turn_Fan_On_at_Beginning': storedSetting("fan_enabled"), 'Turn_Fan_Off_at_Ending': "False", 'Minimum_feed_rate_mm/s': storedSetting("cool_min_feedrate"), + 'Fan_on_at_layer': storedSetting('fan_layer'), + 'Fan_speed_%': storedSetting('fan_speed'), },'hop': { 'Activate_Hop': "False", 'Hop_Over_Layer_Thickness_ratio': DEFSET, diff --git a/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py b/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py index d78f194c..5a4f5491 100644 --- a/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py +++ b/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py @@ -163,6 +163,8 @@ class CoolRepository: self.executeTitle = 'Cool' self.minimumFeedRate = settings.FloatSpin().getFromValue(0.0, 'Minimum feed rate (mm/s):', self, 10.0, 5.0) + self.fanTurnOnLayerNr = settings.IntSpin().getFromValue(0, 'Fan on at layer:', self, 100, 0) + self.fanSpeed = settings.IntSpin().getFromValue(0, 'Fan speed (%):', self, 100, 100) def execute(self): 'Cool button has been clicked.' @@ -333,8 +335,6 @@ class CoolSkein: self.oldFlowRate = float(splitLine[1][1 :]) elif firstWord == '(': self.edgeWidth = float(splitLine[1]) - if self.repository.turnFanOnAtBeginning.value: - self.distanceFeedRate.addLine('M106') elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('cool') return @@ -371,6 +371,8 @@ class CoolSkein: elif firstWord == '(': self.layerCount.printProgressIncrement('cool') self.distanceFeedRate.addLine(line) + if self.repository.turnFanOnAtBeginning.value and self.repository.fanTurnOnLayerNr.value == self.layerCount.layerIndex: + self.distanceFeedRate.addLine('M106 S%d' % (self.repository.fanSpeed.value * 255 / 100)) self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.coolStartLines) layerTime = self.getLayerTime() remainingOrbitTime = max(self.repository.minimumLayerTime.value - layerTime, 0.0) diff --git a/Cura/gui/advancedConfig.py b/Cura/gui/advancedConfig.py index 4f9a0c9b..99c841f8 100644 --- a/Cura/gui/advancedConfig.py +++ b/Cura/gui/advancedConfig.py @@ -23,16 +23,13 @@ class advancedConfigWindow(configBase.configWindowBase): c = configBase.SettingRow(left, "Extra Wall thickness for bottom/top (mm)", 'extra_base_wall_thickness', '0.0', 'Additional wall thickness of the bottom and top layers.') validators.validFloat(c, 0.0) - configBase.TitleRow(left, "Sequence") - c = configBase.SettingRow(left, "Print order sequence", 'sequence', ['Loops > Perimeter > Infill', 'Loops > Infill > Perimeter', 'Infill > Loops > Perimeter', 'Infill > Perimeter > Loops', 'Perimeter > Infill > Loops', 'Perimeter > Loops > Infill'], 'Sequence of printing. The perimeter is the outer print edge, the loops are the insides of the walls, and the infill is the insides.'); - c = configBase.SettingRow(left, "Force first layer sequence", 'force_first_layer_sequence', True, 'This setting forces the order of the first layer to be \'Perimeter > Loops > Infill\'') - configBase.TitleRow(left, "Cool") c = configBase.SettingRow(left, "Minimum feedrate (mm/s)", 'cool_min_feedrate', '5', 'The minimal layer time can cause the print to slow down so much it starts to ooze. The minimal feedrate protects against this. Even if a print gets slown down it will never be slower then this minimal feedrate.') validators.validFloat(c, 0.0) - - configBase.TitleRow(left, "Joris") - c = configBase.SettingRow(left, "Joris the outer edge", 'joris', False, '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.') + c = configBase.SettingRow(left, "Fan on layer number", 'fan_layer', '0', 'The layer at which the fan is turned on. The first layer is layer 0.') + validators.validInt(c, 0) + c = configBase.SettingRow(left, "Fan speed (%)", 'fan_speed', '100', 'When the fan is turned on, it is enabled at this speed setting.') + validators.validInt(c, 0, 100) configBase.TitleRow(left, "Raft (if enabled)") c = configBase.SettingRow(left, "Raft extra margin (mm)", 'raft_margin', '3.0', 'If the raft is enabled, this is the extra raft area around the object which is also rafted. Increasing this margin will create a stronger raft.') @@ -42,24 +39,31 @@ class advancedConfigWindow(configBase.configWindowBase): c = configBase.SettingRow(left, "Raft interface material amount (%)", 'raft_interface_material_amount', '100', 'The interface layer is a weak thin layer between the base layer and the printed object. It is designed to has little material to make it easy to break the base off the printed object. This setting adjusts the amount of material used for the interface layer.') validators.validFloat(c, 0.0) + configBase.TitleRow(left, "Support") + c = configBase.SettingRow(left, "Support material amount (%)", 'support_rate', '100', 'Amount of material used for support, less material gives a weaker support structure which is easier to remove.') + validators.validFloat(c, 0.0) + c = configBase.SettingRow(left, "Support distance from object (mm)", 'support_distance', '0.5', 'Distance between the support structure and the object.') + validators.validFloat(c, 0.0) + configBase.TitleRow(right, "Infill") c = configBase.SettingRow(right, "Infill pattern", 'infill_type', ['Line', 'Grid Circular', 'Grid Hexagonal', 'Grid Rectangular'], 'Pattern of the none-solid infill. Line is default, but grids can provide a strong print.') c = configBase.SettingRow(right, "Solid infill top", 'solid_top', True, 'Create a solid top surface, if set to false the top is filled with the fill percentage. Useful for cups/vases.') c = configBase.SettingRow(right, "Infill overlap (%)", 'fill_overlap', '15', 'Amount of overlap between the infill and the walls. There is a slight overlap with the walls and the infill so the walls connect firmly to the infill.') validators.validFloat(c, 0.0) - configBase.TitleRow(right, "Support") - c = configBase.SettingRow(right, "Support material amount (%)", 'support_rate', '100', 'Amount of material used for support, less material gives a weaker support structure which is easier to remove.') - validators.validFloat(c, 0.0) - c = configBase.SettingRow(right, "Support distance from object (mm)", 'support_distance', '0.5', 'Distance between the support structure and the object.') - validators.validFloat(c, 0.0) - configBase.TitleRow(right, "Bridge") c = configBase.SettingRow(right, "Bridge speed (%)", 'bridge_speed', '100', 'Speed at which bridges are printed, compared to normal printing speed.') validators.validFloat(c, 0.0) c = configBase.SettingRow(right, "Bridge material (%)", 'bridge_material_amount', '100', 'Amount of material used for bridges, increase go extrude more material when printing a bridge.') validators.validFloat(c, 0.0) + configBase.TitleRow(right, "Sequence") + c = configBase.SettingRow(right, "Print order sequence", 'sequence', ['Loops > Perimeter > Infill', 'Loops > Infill > Perimeter', 'Infill > Loops > Perimeter', 'Infill > Perimeter > Loops', 'Perimeter > Infill > Loops', 'Perimeter > Loops > Infill'], 'Sequence of printing. The perimeter is the outer print edge, the loops are the insides of the walls, and the infill is the insides.'); + c = configBase.SettingRow(right, "Force first layer sequence", 'force_first_layer_sequence', True, 'This setting forces the order of the first layer to be \'Perimeter > Loops > Infill\'') + + configBase.TitleRow(right, "Joris") + c = configBase.SettingRow(right, "Joris the outer edge", 'joris', False, '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.') + main.Fit() self.Fit() diff --git a/Cura/gui/alterationPanel.py b/Cura/gui/alterationPanel.py index c47b7c8a..2692b7fa 100644 --- a/Cura/gui/alterationPanel.py +++ b/Cura/gui/alterationPanel.py @@ -7,7 +7,7 @@ class alterationPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent,-1) - self.alterationFileList = ['start.gcode', 'end.gcode', 'cool_start.gcode', 'cool_end.gcode', 'replace.csv'] + self.alterationFileList = ['start.gcode', 'end.gcode', 'support_start.gcode', 'support_end.gcode', 'replace.csv'] self.currentFile = None self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB) diff --git a/Cura/gui/icon.py b/Cura/gui/icon.py new file mode 100644 index 00000000..8b53bbf7 --- /dev/null +++ b/Cura/gui/icon.py @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------- +# This file was generated by /usr/bin/img2py +# +from wx.lib.embeddedimage import PyEmbeddedImage + +Main = PyEmbeddedImage( + "iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAIAAAD9MqGbAAAAA3NCSVQICAjb4U/gAAAC/klE" + "QVQ4jYWUe0hTYRTAz+5rd5uPys2Z89mtLLecPRQpZw+ishf0gB5EQRZFWY20h/6jGQWSlJRR" + "RFGRFJXRHw3ECpRWbqRZq1WabErqqjWd7XF3d7e72x8rfKX9/jsf349zzncOn6DyPRuPBeAv" + "IY5DUBT+hy2IY/FYII1g2s2mi5Vl7WZTMBhQZS5Qqefbf3w7UlIxeYp0PBkDgMYGXenhAo4L" + "yqcqUqiZpjfGVoMeAFat35yjWTau6f3lrCwrxgn8bNWNxcvzERRl/f4TB3e9ano2ccHYuxcN" + "A46fqzdsWbpybfiIEAr3aUsYH52mzJjAROVJVOdbo7bkdMiod+gbvZYv0Sq1NDZuLoK4Xzc7" + "W43ipBRMEjFK6+cwjKHdABDNsh9KtQAgmTY9cctO1vHTdOxA+FJMTi4ZGzc2JyJTpACAE8fy" + "6l8RUtmfgqWyvAajYuPWcEgHPf8wZ2drAODW1WoylUKFJAA0ftWteaTMb15SPutpbwIUWg4t" + "u5eyXadptj0f0WdBxWWht/+Z7vH929cyvF6cDzVh/k6nmZUwHpR5O0/gDnnykvKtvzp6XJa1" + "1LahPgHg8MlTU6SxN2rO9TNMyEc3XKojRaLIokludFD+nT+jqVZQqS55LhE1ffiGCe588qYR" + "DAAEPe6Wmirn9RoifY4sc0GpvNaHBo62ALIUEFQIJgGdHSNiB9Lnlien7elgSWRoshGRWYXF" + "8es2cV2Wzrs3AUDE4QCAmElKqc08cCUr4ziOitvbynieg/D2DZczL1xzuey2XjPeUeTjaNV5" + "HdgNLk833VuP4ZFCkdw9+ImhbYDPGGGG2f9ik9X5GUeJAMfWPslJFyvEfgcvQAR8aESaURrP" + "c3szTnzsbwMAkrbFdz1kAOwzd29WnxShoveGwj7rg9EvNBZbd52xrYKKW5RI7XA6Wn701A86" + "WhFUSCm1ePKGiUwA0Os03pdWUPMAEOL8jFgBACTdJ5tXLRj1J4yFcRh89qao6ASIWcH5He5A" + "lwRiBqIX/gbbS0S3wHAu3wAAAABJRU5ErkJggg==") +getMainData = Main.GetData +getMainImage = Main.GetImage +getMainBitmap = Main.GetBitmap +getMainIcon = Main.GetIcon + diff --git a/Cura/gui/mainWindow.py b/Cura/gui/mainWindow.py index 67377eac..20a00324 100644 --- a/Cura/gui/mainWindow.py +++ b/Cura/gui/mainWindow.py @@ -14,6 +14,7 @@ from gui import configWizard from gui import machineCom from gui import printWindow from gui import simpleMode +from gui import icon from util import profile def main(): @@ -35,6 +36,7 @@ class mainWindow(configBase.configWindowBase): super(mainWindow, self).__init__(title='Cura') wx.EVT_CLOSE(self, self.OnClose) + self.SetIcon(icon.getMainIcon()) menubar = wx.MenuBar() fileMenu = wx.Menu() @@ -167,6 +169,7 @@ class mainWindow(configBase.configWindowBase): configBase.TitleRow(right, "Cool") c = configBase.SettingRow(right, "Minimal layer time (sec)", 'cool_min_layer_time', '10', 'Minimum time spend in a layer, gives the layer time to cool down before the next layer is put on top. If the layer will be placed down too fast the printer will slow down to make sure it has spend atleast this amount of seconds printing this layer.') validators.validFloat(c, 0.0) + c = configBase.SettingRow(right, "Enable cooling fan", 'fan_enabled', True, 'Enable the cooling fan during the print. The extra cooling from the cooling fan is essensial during faster prints.') nb.AddPage(alterationPanel.alterationPanel(nb), "Start/End-GCode") @@ -309,3 +312,4 @@ class mainWindow(configBase.configWindowBase): def OnClose(self, e): profile.saveGlobalProfile(profile.getDefaultProfilePath()) self.Destroy() + diff --git a/Cura/gui/printWindow.py b/Cura/gui/printWindow.py index c84d8424..7eae41fd 100644 --- a/Cura/gui/printWindow.py +++ b/Cura/gui/printWindow.py @@ -4,6 +4,8 @@ import __init__ import wx, threading from gui import machineCom +from gui import icon +from util import gcodeInterpreter printWindowHandle = None @@ -20,11 +22,14 @@ class printWindow(wx.Frame): def __init__(self): super(printWindow, self).__init__(None, -1, title='Printing') self.machineCom = None + self.machineConnected = False self.thread = None self.gcodeList = None self.printIdx = None self.bufferLineCount = 4 self.sendCnt = 0 + + self.SetIcon(icon.getMainIcon()) self.SetSizer(wx.BoxSizer()) self.panel = wx.Panel(self) @@ -34,8 +39,8 @@ class printWindow(wx.Frame): sb = wx.StaticBox(self.panel, label="Statistics") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) - boxsizer.Add(wx.StaticText(self.panel, -1, "Filament: #.##m #.##g"), flag=wx.LEFT, border=5) - boxsizer.Add(wx.StaticText(self.panel, -1, "Print time: ##:##"), flag=wx.LEFT, border=5) + self.statsText = wx.StaticText(self.panel, -1, "Filament: #.##m #.##g\nPrint time: ##:##") + boxsizer.Add(self.statsText, flag=wx.LEFT, border=5) self.sizer.Add(boxsizer, pos=(0,0), span=(4,1), flag=wx.EXPAND) @@ -43,11 +48,12 @@ class printWindow(wx.Frame): self.loadButton = wx.Button(self.panel, -1, 'Load GCode') self.printButton = wx.Button(self.panel, -1, 'Print GCode') self.cancelButton = wx.Button(self.panel, -1, 'Cancel print') + self.progress = wx.Gauge(self.panel, -1) self.sizer.Add(self.connectButton, pos=(0,1)) self.sizer.Add(self.loadButton, pos=(1,1)) self.sizer.Add(self.printButton, pos=(2,1)) self.sizer.Add(self.cancelButton, pos=(3,1)) - self.sizer.Add(wx.Gauge(self.panel, -1), pos=(4,0), span=(1,2), flag=wx.EXPAND) + self.sizer.Add(self.progress, pos=(4,0), span=(1,2), flag=wx.EXPAND) self.sizer.AddGrowableRow(3) self.sizer.AddGrowableCol(0) @@ -60,6 +66,24 @@ class printWindow(wx.Frame): self.Layout() self.Fit() self.Centre() + + self.UpdateButtonStates() + self.UpdateProgress() + + def UpdateButtonStates(self): + self.connectButton.Enable(not self.machineConnected) + self.loadButton.Enable(self.printIdx == None) + self.printButton.Enable(self.machineConnected and self.gcodeList != None and self.printIdx == None) + self.cancelButton.Enable(self.printIdx != None) + + def UpdateProgress(self): + status = "" + if self.printIdx == None: + self.progress.SetValue(0) + else: + self.progress.SetValue(self.printIdx) + status += 'Line: %d/%d\n' % (self.printIdx, len(self.gcodeList)) + self.statsText.SetLabel(status) def OnConnect(self, e): if self.machineCom != None: @@ -68,12 +92,13 @@ class printWindow(wx.Frame): self.machineCom = machineCom.MachineCom() self.thread = threading.Thread(target=self.PrinterMonitor) self.thread.start() + self.UpdateButtonStates() def OnLoad(self, e): pass def OnPrint(self, e): - if self.machineCom == None: + if not self.machineConnected: return if self.gcodeList == None: return @@ -82,9 +107,11 @@ class printWindow(wx.Frame): self.printIdx = 1 self.sendLine(0) self.sendCnt = self.bufferLineCount + self.UpdateButtonStates() def OnCancel(self, e): - pass + self.printIdx = None + self.UpdateButtonStates() def OnClose(self, e): global printWindowHandle @@ -102,8 +129,15 @@ class printWindow(wx.Frame): line = line.strip() if len(line) > 0: gcodeList.append(line) + gcode = gcodeInterpreter.gcode() + gcode.loadList(gcodeList) + print gcode.extrusionAmount + print gcode.totalMoveTimeMinute print "Loaded: %s (%d)" % (filename, len(gcodeList)) + self.progress.SetRange(len(gcodeList)) self.gcodeList = gcodeList + self.UpdateButtonStates() + self.UpdateProgress() def sendLine(self, lineNr): if lineNr >= len(self.gcodeList): @@ -116,11 +150,17 @@ class printWindow(wx.Frame): while True: line = self.machineCom.readline() if line == None: + self.machineConnected = False + wx.CallAfter(self.UpdateButtonState) return - while self.sendCnt > 0: - self.sendLine(self.printIdx) - self.printIdx += 1 - self.sendCnt -= 1 + if self.machineConnected: + while self.sendCnt > 0: + self.sendLine(self.printIdx) + self.printIdx += 1 + self.sendCnt -= 1 + elif line.startswith("start"): + self.machineConnected = True + wx.CallAfter(self.UpdateButtonState) if self.printIdx != None: if line.startswith("ok"): if skipCount > 0: @@ -128,6 +168,7 @@ class printWindow(wx.Frame): else: self.sendLine(self.printIdx) self.printIdx += 1 + wx.CallAfter(self.UpdateProgress) elif "resend" in line.lower() or "rs" in line: try: lineNr=int(line.replace("N:"," ").replace("N"," ").replace(":"," ").split()[-1]) diff --git a/Cura/gui/simpleMode.py b/Cura/gui/simpleMode.py index e2a6d91e..13954fd1 100644 --- a/Cura/gui/simpleMode.py +++ b/Cura/gui/simpleMode.py @@ -11,6 +11,7 @@ from gui import preferencesDialog from gui import configWizard from gui import machineCom from gui import printWindow +from gui import icon from util import profile class simpleModeWindow(configBase.configWindowBase): @@ -19,6 +20,7 @@ class simpleModeWindow(configBase.configWindowBase): super(simpleModeWindow, self).__init__(title='Cura - Simple mode') wx.EVT_CLOSE(self, self.OnClose) + self.SetIcon(icon.getMainIcon()) menubar = wx.MenuBar() fileMenu = wx.Menu() @@ -187,6 +189,9 @@ class simpleModeWindow(configBase.configWindowBase): put('max_z_speed', '1.0') put('bottom_layer_speed', '25') put('cool_min_layer_time', '10') + put('fan_enabled', 'True') + put('fan_layer', '0') + put('fan_speed', '100') #put('model_scale', '1.0') #put('flip_x', 'False') #put('flip_y', 'False') @@ -249,6 +254,7 @@ class simpleModeWindow(configBase.configWindowBase): put('filament_density', '0.85') put('enable_raft', 'True') put('skirt_line_count', '0') + put('fan_layer', '1') #Create a progress panel and add it to the window. The progress panel will start the Skein operation. spp = sliceProgessPanel.sliceProgessPanel(self, self, self.filename) diff --git a/Cura/util/gcodeInterpreter.py b/Cura/util/gcodeInterpreter.py index 347eabed..06ebd5ac 100644 --- a/Cura/util/gcodeInterpreter.py +++ b/Cura/util/gcodeInterpreter.py @@ -23,9 +23,16 @@ class gcode(): self.progressCallback = None def load(self, filename): - fileSize = os.stat(filename).st_size - filePos = 0 + self._fileSize = os.stat(filename).st_size gcodeFile = open(filename, 'r') + self._load(gcodeFile) + gcodeFile.close() + + def loadList(self, l): + self._load(l) + + def _load(self, gcodeFile): + filePos = 0 pos = util3d.Vector3() posOffset = util3d.Vector3() currentE = 0.0 @@ -42,10 +49,10 @@ class gcode(): currentPath.list[0].e = totalExtrusion currentLayer.append(currentPath) for line in gcodeFile: - if filePos != gcodeFile.tell(): - filePos = gcodeFile.tell() - if self.progressCallback != None: - self.progressCallback(float(filePos) / float(fileSize)) + if self.progressCallback != None: + if filePos != gcodeFile.tell(): + filePos = gcodeFile.tell() + self.progressCallback(float(filePos) / float(self._fileSize)) #Parse Cura_SF comments if line.startswith(';TYPE:'): @@ -183,7 +190,6 @@ class gcode(): pass else: print "Unknown M code:" + str(M) - gcodeFile.close() self.layerList.append(currentLayer) self.extrusionAmount = maxExtrusion self.totalMoveTimeMinute = totalMoveTimeMinute diff --git a/Cura/util/profile.py b/Cura/util/profile.py index 8ab00bd3..2548ec81 100644 --- a/Cura/util/profile.py +++ b/Cura/util/profile.py @@ -35,6 +35,9 @@ profileDefaultSettings = { 'max_z_speed': '1.0', 'bottom_layer_speed': '25', 'cool_min_layer_time': '10', + 'fan_enabled': 'True', + 'fan_layer': '0', + 'fan_speed': '100', 'model_scale': '1.0', 'flip_x': 'False', 'flip_y': 'False', diff --git a/scripts/win32/cura.ico b/scripts/win32/cura.ico new file mode 100644 index 00000000..1919bfe1 Binary files /dev/null and b/scripts/win32/cura.ico differ diff --git a/scripts/win32/drivers/Arduino_MEGA_2560.inf b/scripts/win32/drivers/Arduino_MEGA_2560.inf new file mode 100644 index 00000000..2f519730 --- /dev/null +++ b/scripts/win32/drivers/Arduino_MEGA_2560.inf @@ -0,0 +1,106 @@ +;************************************************************ +; Windows USB CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation + + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +LayoutFile=layout.inf +CatalogFile=%MFGFILENAME%.cat +DriverVer=11/15/2007,5.1.2600.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTamd64 + +[DestinationDirs] +DefaultDestDir=12 + + +;------------------------------------------------------------------------------ +; Windows 2000/XP/Vista-32bit Sections +;------------------------------------------------------------------------------ + +[DriverInstall.nt] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles.nt +AddReg=DriverInstall.nt.AddReg + +[DriverCopyFiles.nt] +usbser.sys,,,0x20 + +[DriverInstall.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,%DRIVERFILENAME%.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.nt.Services] +AddService=usbser, 0x00000002, DriverService.nt + +[DriverService.nt] +DisplayName=%SERVICE% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\%DRIVERFILENAME%.sys + +;------------------------------------------------------------------------------ +; Vista-64bit Sections +;------------------------------------------------------------------------------ + +[DriverInstall.NTamd64] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles.NTamd64 +AddReg=DriverInstall.NTamd64.AddReg + +[DriverCopyFiles.NTamd64] +%DRIVERFILENAME%.sys,,,0x20 + +[DriverInstall.NTamd64.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,%DRIVERFILENAME%.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.NTamd64.Services] +AddService=usbser, 0x00000002, DriverService.NTamd64 + +[DriverService.NTamd64] +DisplayName=%SERVICE% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\%DRIVERFILENAME%.sys + + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[SourceDisksFiles] +[SourceDisksNames] +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_2341&PID_0010 + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_2341&PID_0010 + + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGFILENAME="CDC_vista" +DRIVERFILENAME ="usbser" +MFGNAME="Arduino LLC (www.arduino.cc)" +INSTDISK="Arduino Mega 2560 Driver Installer" +DESCRIPTION="Arduino Mega 2560" +SERVICE="USB RS-232 Emulation Driver" diff --git a/scripts/win32/drivers/dpinst32.exe b/scripts/win32/drivers/dpinst32.exe new file mode 100644 index 00000000..f4d9174e Binary files /dev/null and b/scripts/win32/drivers/dpinst32.exe differ diff --git a/scripts/win32/drivers/dpinst64.exe b/scripts/win32/drivers/dpinst64.exe new file mode 100644 index 00000000..22279722 Binary files /dev/null and b/scripts/win32/drivers/dpinst64.exe differ diff --git a/scripts/win32/header.bmp b/scripts/win32/header.bmp new file mode 100644 index 00000000..379081de Binary files /dev/null and b/scripts/win32/header.bmp differ diff --git a/scripts/win32/installer.nsi b/scripts/win32/installer.nsi new file mode 100644 index 00000000..590deabb --- /dev/null +++ b/scripts/win32/installer.nsi @@ -0,0 +1,117 @@ +!define VERSION 'RC1' + +; The name of the installer +Name "Cura ${VERSION}" + +; The file to write +OutFile "Cura_${VERSION}.exe" + +; The default installation directory +InstallDir $PROGRAMFILES\Cura_${VERSION} + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\Cura_${VERSION}" "Install_Dir" + +; Request application privileges for Windows Vista +RequestExecutionLevel admin + +; Set the LZMA compressor to reduce size. +SetCompressor /SOLID lzma +;-------------------------------- + +!include "MUI2.nsh" +!include Library.nsh + +!define MUI_ICON "cura.ico" +!define MUI_BGCOLOR FFFFFF + +; Directory page defines +!define MUI_DIRECTORYPAGE_VERIFYONLEAVE + +; Header +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_HEADERIMAGE_BITMAP "header.bmp" +!define MUI_HEADERIMAGE_BITMAP_NOSTRETCH + +;Do not leave (Un)Installer page automaticly +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +; Pages +;!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + +; Languages +!insertmacro MUI_LANGUAGE "English" + +; Reserve Files +!insertmacro MUI_RESERVEFILE_LANGDLL +ReserveFile '${NSISDIR}\Plugins\InstallOptions.dll' +ReserveFile "cura.ico" +ReserveFile "header.bmp" + +;-------------------------------- + +; The stuff to install +Section "Cura Installer" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there + File /r "dist\" + + ; Write the installation path into the registry + WriteRegStr HKLM "SOFTWARE\Cura_${VERSION}" "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "DisplayName" "Cura ${VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + + CreateDirectory "$SMPROGRAMS\Cura ${VERSION}" + CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\Cura.lnk" "$INSTDIR\cura.bat" "" "$INSTDIR\cura.icon" 0 + + ; Set output path to the driver directory. + SetOutPath "$INSTDIR\drivers\" + File /r "drivers\" + + ${If} ${RunningX64} + ExecWait '"$INSTDIR\drivers\dpinst64.exe" /lm' + ${Else} + ExecWait '"$INSTDIR\drivers\dpinst32.exe" /lm' + ${EndIf} + +SectionEnd + +;-------------------------------- + +; Uninstaller + +Section "Uninstall" + + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" + DeleteRegKey HKLM "SOFTWARE\Cura_${VERSION}" + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\Cura ${VERSION}\*.*" + + ; Remove directories used + RMDir /r "$SMPROGRAMS\Cura ${VERSION}" + RMDir /r "$INSTDIR" + +SectionEnd +