Kaynağa Gözat

Merged in joernsn/flatcam/spindlespeed (pull request #13)

Added parameter "Spindle speed" to cnc jobs
jpcgt 10 yıl önce
ebeveyn
işleme
6cf552021a
5 değiştirilmiş dosya ile 88 ekleme ve 17 silme
  1. 15 6
      FlatCAMApp.py
  2. 18 0
      FlatCAMGUI.py
  3. 16 6
      FlatCAMObj.py
  4. 20 0
      ObjectUI.py
  5. 19 5
      camlib.py

+ 15 - 6
FlatCAMApp.py

@@ -266,7 +266,8 @@ class App(QtCore.QObject):
             "zdownrate": None,
             "zdownrate": None,
             "excellon_zeros": "L",
             "excellon_zeros": "L",
             "gerber_use_buffer_for_union": True,
             "gerber_use_buffer_for_union": True,
-            "cncjob_coordinate_format": "X%.4fY%.4f"
+            "cncjob_coordinate_format": "X%.4fY%.4f",
+            "spindlespeed": None
         })
         })
 
 
         ###############################
         ###############################
@@ -1809,7 +1810,8 @@ class App(QtCore.QObject):
             "zdownrate": CNCjob,
             "zdownrate": CNCjob,
             "excellon_zeros": Excellon,
             "excellon_zeros": Excellon,
             "gerber_use_buffer_for_union": Gerber,
             "gerber_use_buffer_for_union": Gerber,
-            "cncjob_coordinate_format": CNCjob
+            "cncjob_coordinate_format": CNCjob,
+            "spindlespeed": CNCjob
         }
         }
 
 
         for param in routes:
         for param in routes:
@@ -2056,7 +2058,9 @@ class App(QtCore.QObject):
                      'drillz': float,
                      'drillz': float,
                      'travelz': float,
                      'travelz': float,
                      'feedrate': float,
                      'feedrate': float,
-                     'toolchange': int}
+                     'spindlespeed': int,
+                     'toolchange': int
+                     }
 
 
             for key in kwa:
             for key in kwa:
                 if key not in types:
                 if key not in types:
@@ -2086,6 +2090,7 @@ class App(QtCore.QObject):
                     job_obj.z_cut = kwa["drillz"]
                     job_obj.z_cut = kwa["drillz"]
                     job_obj.z_move = kwa["travelz"]
                     job_obj.z_move = kwa["travelz"]
                     job_obj.feedrate = kwa["feedrate"]
                     job_obj.feedrate = kwa["feedrate"]
+                    job_obj.spindlespeed = kwa["spindlespeed"] if "spindlespeed" in kwa else None
                     toolchange = True if "toolchange" in kwa and kwa["toolchange"] == 1 else False
                     toolchange = True if "toolchange" in kwa and kwa["toolchange"] == 1 else False
                     job_obj.generate_from_excellon_by_tool(obj, kwa["tools"], toolchange)
                     job_obj.generate_from_excellon_by_tool(obj, kwa["tools"], toolchange)
                     
                     
@@ -2135,7 +2140,9 @@ class App(QtCore.QObject):
                      'z_move': float,
                      'z_move': float,
                      'feedrate': float,
                      'feedrate': float,
                      'tooldia': float,
                      'tooldia': float,
-                     'outname': str}
+                     'outname': str,
+                     'spindlespeed': int
+                     }
 
 
             for key in kwa:
             for key in kwa:
                 if key not in types:
                 if key not in types:
@@ -2429,13 +2436,14 @@ class App(QtCore.QObject):
             'drillcncjob': {
             'drillcncjob': {
                 'fcn': drillcncjob,
                 'fcn': drillcncjob,
                 'help': "Drill CNC job.\n" +
                 'help': "Drill CNC job.\n" +
-                        "> drillcncjob <name> -tools <str> -drillz <float> -travelz <float> -feedrate <float> -outname <str> [-toolchange (int)] \n" +
+                        "> drillcncjob <name> -tools <str> -drillz <float> -travelz <float> -feedrate <float> -outname <str> [-spindlespeed (int)] [-toolchange (int)] \n" +
                         "   name: Name of the object\n" +
                         "   name: Name of the object\n" +
                         "   tools: Comma separated indexes of tools (example: 1,3 or 2)\n" +
                         "   tools: Comma separated indexes of tools (example: 1,3 or 2)\n" +
                         "   drillz: Drill depth into material (example: -2.0)\n" +
                         "   drillz: Drill depth into material (example: -2.0)\n" +
                         "   travelz: Travel distance above material (example: 2.0)\n" +
                         "   travelz: Travel distance above material (example: 2.0)\n" +
                         "   feedrate: Drilling feed rate\n" +
                         "   feedrate: Drilling feed rate\n" +
                         "   outname: Name of object to create\n" +
                         "   outname: Name of object to create\n" +
+                        "   spindlespeed: Speed of the spindle in rpm (example: 4000)\n" +
                         "   toolchange: Enable tool changes (example: 1)\n"
                         "   toolchange: Enable tool changes (example: 1)\n"
             },
             },
             'scale': {
             'scale': {
@@ -2459,12 +2467,13 @@ class App(QtCore.QObject):
             'cncjob': {
             'cncjob': {
                 'fcn': cncjob,
                 'fcn': cncjob,
                 'help': 'Generates a CNC Job from a Geometry Object.\n' +
                 'help': 'Generates a CNC Job from a Geometry Object.\n' +
-                        '> cncjob <name> [-z_cut <c>] [-z_move <m>] [-feedrate <f>] [-tooldia <t>] [-outname <n>]\n' +
+                        '> cncjob <name> [-z_cut <c>] [-z_move <m>] [-feedrate <f>] [-tooldia <t>] [-spindlespeed (int)] [-outname <n>]\n' +
                         '   name: Name of the source object\n' +
                         '   name: Name of the source object\n' +
                         '   z_cut: Z-axis cutting position\n' +
                         '   z_cut: Z-axis cutting position\n' +
                         '   z_move: Z-axis moving position\n' +
                         '   z_move: Z-axis moving position\n' +
                         '   feedrate: Moving speed when cutting\n' +
                         '   feedrate: Moving speed when cutting\n' +
                         '   tooldia: Tool diameter to show on screen\n' +
                         '   tooldia: Tool diameter to show on screen\n' +
+                        '   spindlespeed: Speed of the spindle in rpm (example: 4000)\n' +
                         '   outname: Name of the output object'
                         '   outname: Name of the output object'
             },
             },
             'write_gcode': {
             'write_gcode': {

+ 18 - 0
FlatCAMGUI.py

@@ -580,6 +580,15 @@ class ExcellonOptionsGroupUI(OptionsGroupUI):
         self.feedrate_entry = LengthEntry()
         self.feedrate_entry = LengthEntry()
         grid1.addWidget(self.feedrate_entry, 2, 1)
         grid1.addWidget(self.feedrate_entry, 2, 1)
 
 
+        spdlabel = QtGui.QLabel('Spindle speed:')
+        spdlabel.setToolTip(
+            "Speed of the spindle\n"
+            "in RPM (optional)"
+        )
+        grid1.addWidget(spdlabel, 3, 0)
+        self.spindlespeed_entry = LengthEntry()
+        grid1.addWidget(self.spindlespeed_entry, 3, 1)
+
 
 
 class GeometryOptionsGroupUI(OptionsGroupUI):
 class GeometryOptionsGroupUI(OptionsGroupUI):
     def __init__(self, parent=None):
     def __init__(self, parent=None):
@@ -647,6 +656,15 @@ class GeometryOptionsGroupUI(OptionsGroupUI):
         self.cnctooldia_entry = LengthEntry()
         self.cnctooldia_entry = LengthEntry()
         grid1.addWidget(self.cnctooldia_entry, 3, 1)
         grid1.addWidget(self.cnctooldia_entry, 3, 1)
 
 
+        spdlabel = QtGui.QLabel('Spindle speed:')
+        spdlabel.setToolTip(
+            "Speed of the spindle\n"
+            "in RPM (optional)"
+        )
+        grid1.addWidget(spdlabel, 4, 0)
+        self.cncspindlespeed_entry = LengthEntry()
+        grid1.addWidget(self.cncspindlespeed_entry, 4, 1)
+
         ## Paint area
         ## Paint area
         self.paint_label = QtGui.QLabel('<b>Paint Area:</b>')
         self.paint_label = QtGui.QLabel('<b>Paint Area:</b>')
         self.paint_label.setToolTip(
         self.paint_label.setToolTip(

+ 16 - 6
FlatCAMObj.py

@@ -608,7 +608,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             # "toolselection": ""
             # "toolselection": ""
             "tooldia": 0.1,
             "tooldia": 0.1,
             "toolchange": False,
             "toolchange": False,
-            "toolchangez": 1.0
+            "toolchangez": 1.0,
+            "spindlespeed": ""
         })
         })
 
 
         # TODO: Document this.
         # TODO: Document this.
@@ -664,7 +665,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             "feedrate": self.ui.feedrate_entry,
             "feedrate": self.ui.feedrate_entry,
             "tooldia": self.ui.tooldia_entry,
             "tooldia": self.ui.tooldia_entry,
             "toolchange": self.ui.toolchange_cb,
             "toolchange": self.ui.toolchange_cb,
-            "toolchangez": self.ui.toolchangez_entry
+            "toolchangez": self.ui.toolchangez_entry,
+            "spindlespeed":  self.ui.spindlespeed_entry
         })
         })
 
 
         assert isinstance(self.ui, ExcellonObjectUI)
         assert isinstance(self.ui, ExcellonObjectUI)
@@ -740,6 +742,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             job_obj.z_cut = self.options["drillz"]
             job_obj.z_cut = self.options["drillz"]
             job_obj.z_move = self.options["travelz"]
             job_obj.z_move = self.options["travelz"]
             job_obj.feedrate = self.options["feedrate"]
             job_obj.feedrate = self.options["feedrate"]
+            job_obj.spindlespeed = self.options["spindlespeed"]
             # There could be more than one drill size...
             # There could be more than one drill size...
             # job_obj.tooldia =   # TODO: duplicate variable!
             # job_obj.tooldia =   # TODO: duplicate variable!
             # job_obj.options["tooldia"] =
             # job_obj.options["tooldia"] =
@@ -825,12 +828,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
     ui_type = CNCObjectUI
     ui_type = CNCObjectUI
 
 
     def __init__(self, name, units="in", kind="generic", z_move=0.1,
     def __init__(self, name, units="in", kind="generic", z_move=0.1,
-                 feedrate=3.0, z_cut=-0.002, tooldia=0.0):
+                 feedrate=3.0, z_cut=-0.002, tooldia=0.0,spindlespeed=None):
 
 
         FlatCAMApp.App.log.debug("Creating CNCJob object...")
         FlatCAMApp.App.log.debug("Creating CNCJob object...")
 
 
         CNCjob.__init__(self, units=units, kind=kind, z_move=z_move,
         CNCjob.__init__(self, units=units, kind=kind, z_move=z_move,
-                        feedrate=feedrate, z_cut=z_cut, tooldia=tooldia)
+                        feedrate=feedrate, z_cut=z_cut, tooldia=tooldia, spindlespeed=spindlespeed)
 
 
         FlatCAMObj.__init__(self, name)
         FlatCAMObj.__init__(self, name)
 
 
@@ -971,6 +974,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             "cutz": -0.002,
             "cutz": -0.002,
             "travelz": 0.1,
             "travelz": 0.1,
             "feedrate": 5.0,
             "feedrate": 5.0,
+            "spindlespeed": "",
             "cnctooldia": 0.4 / 25.4,
             "cnctooldia": 0.4 / 25.4,
             "painttooldia": 0.0625,
             "painttooldia": 0.0625,
             "paintoverlap": 0.15,
             "paintoverlap": 0.15,
@@ -998,6 +1002,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             "cutz": self.ui.cutz_entry,
             "cutz": self.ui.cutz_entry,
             "travelz": self.ui.travelz_entry,
             "travelz": self.ui.travelz_entry,
             "feedrate": self.ui.cncfeedrate_entry,
             "feedrate": self.ui.cncfeedrate_entry,
+            "spindlespeed": self.ui.cncspindlespeed_entry,
             "cnctooldia": self.ui.cnctooldia_entry,
             "cnctooldia": self.ui.cnctooldia_entry,
             "painttooldia": self.ui.painttooldia_entry,
             "painttooldia": self.ui.painttooldia_entry,
             "paintoverlap": self.ui.paintoverlap_entry,
             "paintoverlap": self.ui.paintoverlap_entry,
@@ -1076,13 +1081,18 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         self.generatecncjob()
         self.generatecncjob()
 
 
     def generatecncjob(self, z_cut=None, z_move=None,
     def generatecncjob(self, z_cut=None, z_move=None,
-                       feedrate=None, tooldia=None, outname=None):
+                       feedrate=None, tooldia=None, outname=None, spindlespeed=None):
 
 
         outname = outname if outname is not None else self.options["name"] + "_cnc"
         outname = outname if outname is not None else self.options["name"] + "_cnc"
         z_cut = z_cut if z_cut is not None else self.options["cutz"]
         z_cut = z_cut if z_cut is not None else self.options["cutz"]
         z_move = z_move if z_move is not None else self.options["travelz"]
         z_move = z_move if z_move is not None else self.options["travelz"]
         feedrate = feedrate if feedrate is not None else self.options["feedrate"]
         feedrate = feedrate if feedrate is not None else self.options["feedrate"]
         tooldia = tooldia if tooldia is not None else self.options["cnctooldia"]
         tooldia = tooldia if tooldia is not None else self.options["cnctooldia"]
+
+        # To allow default value to be "" (optional in gui) and translate to None
+        if(not isinstance(spindlespeed, int)):
+            spindlespeed = self.options["spindlespeed"] if isinstance(self.options["spindlespeed"], int) else None
+
         
         
         # Object initialization function for app.new_object()
         # Object initialization function for app.new_object()
         # RUNNING ON SEPARATE THREAD!
         # RUNNING ON SEPARATE THREAD!
@@ -1095,7 +1105,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             job_obj.z_cut = z_cut
             job_obj.z_cut = z_cut
             job_obj.z_move = z_move
             job_obj.z_move = z_move
             job_obj.feedrate = feedrate
             job_obj.feedrate = feedrate
-
+            job_obj.spindlespeed = spindlespeed
             app_obj.progress.emit(40)
             app_obj.progress.emit(40)
             # TODO: The tolerance should not be hard coded. Just for testing.
             # TODO: The tolerance should not be hard coded. Just for testing.
             job_obj.generate_from_geometry_2(self, tolerance=0.0005)
             job_obj.generate_from_geometry_2(self, tolerance=0.0005)

+ 20 - 0
ObjectUI.py

@@ -271,6 +271,16 @@ class GeometryObjectUI(ObjectUI):
         self.cnctooldia_entry = LengthEntry()
         self.cnctooldia_entry = LengthEntry()
         grid1.addWidget(self.cnctooldia_entry, 3, 1)
         grid1.addWidget(self.cnctooldia_entry, 3, 1)
 
 
+        # Spindlespeed
+        spdlabel = QtGui.QLabel('Spindle speed:')
+        spdlabel.setToolTip(
+            "Speed of the spindle\n"
+            "in RPM (optional)"
+        )
+        grid1.addWidget(spdlabel, 4, 0)
+        self.cncspindlespeed_entry = LengthEntry()
+        grid1.addWidget(self.cncspindlespeed_entry, 4, 1)
+
         self.generate_cnc_button = QtGui.QPushButton('Generate')
         self.generate_cnc_button = QtGui.QPushButton('Generate')
         self.generate_cnc_button.setToolTip(
         self.generate_cnc_button.setToolTip(
             "Generate the CNC Job object."
             "Generate the CNC Job object."
@@ -446,6 +456,16 @@ class ExcellonObjectUI(ObjectUI):
         grid1.addWidget(self.toolchangez_entry, 4, 1)
         grid1.addWidget(self.toolchangez_entry, 4, 1)
         self.ois_tcz = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry])
         self.ois_tcz = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry])
 
 
+        # Spindlespeed
+        spdlabel = QtGui.QLabel('Spindle speed:')
+        spdlabel.setToolTip(
+            "Speed of the spindle\n"
+            "in RPM (optional)"
+        )
+        grid1.addWidget(spdlabel, 5, 0)
+        self.spindlespeed_entry = LengthEntry()
+        grid1.addWidget(self.spindlespeed_entry, 5, 1)
+
         choose_tools_label = QtGui.QLabel(
         choose_tools_label = QtGui.QLabel(
             "Select from the tools section above\n"
             "Select from the tools section above\n"
             "the tools you want to include."
             "the tools you want to include."

+ 19 - 5
camlib.py

@@ -2506,7 +2506,8 @@ class CNCjob(Geometry):
 
 
     defaults = {
     defaults = {
         "zdownrate": None,
         "zdownrate": None,
-        "coordinate_format": "X%.4fY%.4f"
+        "coordinate_format": "X%.4fY%.4f",
+        "spindlespeed": None
     }
     }
 
 
     def __init__(self,
     def __init__(self,
@@ -2516,7 +2517,8 @@ class CNCjob(Geometry):
                  feedrate=3.0,
                  feedrate=3.0,
                  z_cut=-0.002,
                  z_cut=-0.002,
                  tooldia=0.0,
                  tooldia=0.0,
-                 zdownrate=None):
+                 zdownrate=None,
+                 spindlespeed=None):
 
 
         Geometry.__init__(self)
         Geometry.__init__(self)
         self.kind = kind
         self.kind = kind
@@ -2540,6 +2542,9 @@ class CNCjob(Geometry):
         else:
         else:
             self.zdownrate = None
             self.zdownrate = None
 
 
+        self.spindlespeed = spindlespeed
+
+
         # Attributes to be included in serialization
         # Attributes to be included in serialization
         # Always append to it because it carries contents
         # Always append to it because it carries contents
         # from Geometry.
         # from Geometry.
@@ -2605,7 +2610,10 @@ class CNCjob(Geometry):
         gcode += self.feedminutecode + "\n"
         gcode += self.feedminutecode + "\n"
         gcode += "F%.2f\n" % self.feedrate
         gcode += "F%.2f\n" % self.feedrate
         gcode += "G00 Z%.4f\n" % self.z_move  # Move to travel height
         gcode += "G00 Z%.4f\n" % self.z_move  # Move to travel height
-        gcode += "M03\n"  # Spindle start
+        if(self.spindlespeed != None):
+            gcode += "M03 S%d\n" % int(self.spindlespeed)  # Spindle start with configured speed
+        else:
+            gcode += "M03\n"  # Spindle start
         gcode += self.pausecode + "\n"
         gcode += self.pausecode + "\n"
 
 
         for tool in points:
         for tool in points:
@@ -2618,7 +2626,10 @@ class CNCjob(Geometry):
                 gcode += "M6\n"  # Tool change
                 gcode += "M6\n"  # Tool change
                 gcode += "(MSG, Change to tool dia=%.4f)\n" % exobj.tools[tool]["C"]
                 gcode += "(MSG, Change to tool dia=%.4f)\n" % exobj.tools[tool]["C"]
                 gcode += "M0\n"  # Temporary machine stop
                 gcode += "M0\n"  # Temporary machine stop
-                gcode += "M3\n"  # Spindle on clockwise
+                if(self.spindlespeed != None):
+                    gcode += "M03 S%d\n" % int(self.spindlespeed)  # Spindle start with configured speed
+                else:
+                    gcode += "M03\n"  # Spindle start
 
 
             # Drillling!
             # Drillling!
             for point in points[tool]:
             for point in points[tool]:
@@ -2682,7 +2693,10 @@ class CNCjob(Geometry):
         self.gcode += self.feedminutecode + "\n"
         self.gcode += self.feedminutecode + "\n"
         self.gcode += "F%.2f\n" % self.feedrate
         self.gcode += "F%.2f\n" % self.feedrate
         self.gcode += "G00 Z%.4f\n" % self.z_move  # Move (up) to travel height
         self.gcode += "G00 Z%.4f\n" % self.z_move  # Move (up) to travel height
-        self.gcode += "M03\n"  # Spindle start
+        if(self.spindlespeed != None):
+            self.gcode += "M03 S%d\n" % int(self.spindlespeed)  # Spindle start with configured speed
+        else:
+            self.gcode += "M03\n"  # Spindle start
         self.gcode += self.pausecode + "\n"
         self.gcode += self.pausecode + "\n"
 
 
         ## Iterate over geometry paths getting the nearest each time.
         ## Iterate over geometry paths getting the nearest each time.