# HG changeset patch # User mdd # Date 1611084347 -3600 # Node ID f7e9bd735ce121c9d82675af184f0cc37ab45ed6 # Parent ea4c43494a19070aedb32cddd2bad7b124e844d5 NeoCube laser cutting improvements diff -r ea4c43494a19 -r f7e9bd735ce1 printrun-src/printrun/laser.py --- a/printrun-src/printrun/laser.py Thu May 30 19:02:52 2019 +0200 +++ b/printrun-src/printrun/laser.py Tue Jan 19 20:25:47 2021 +0100 @@ -1,6 +1,6 @@ """ Lasercutter library -2015-2017 by NeoSoft, Malte Di Donato +2015-2019 by NeoSoft, Malte Di Donato Intended to use standalone or implemented in Pronterface/Printrun """ @@ -18,7 +18,31 @@ # GENERAL HEADER AND FOOTER GCODE GCODE_HEAD = """ ; GCode generated by laser.py pronterface library (marlin code flavour) -; 2015-2017 by NeoSoft - Malte Di Donato +; 2015-2019 by NeoSoft - Malte Di Donato + +G21 ; Metric +; We assume Z is in focus height and laser head is focus at bottom left of image! +G92 X0 Y0 E0; set zero position - new origin +G90 ; absolute positioning +M201 X1000 Y1000 ; Set acceleration +M203 X1000 Y1000 ; Set max feedrate +M209 S0 ; disable firmware retraction, we dont want to burn holes... +;M85 S0 ; Disable idle hold timeout (BUG!) +M84 ; enable motors + +""" + +GCODE_FOOT = """ +M400 ; Wait for all moves to finish +M5 ; Force laser off! +G0 X0 Y0 F%.4f ; Move back to origin +; M501 ; undo all settings made +""" % (100*60) + + +GCODE_HEAD_MELZI = """ +; GCode generated by laser.py pronterface library (marlin code flavour) +; 2015-2019 by NeoSoft - Malte Di Donato G21 ; Metric ; We assume Z is in focus height and laser head is focus at bottom left of image! @@ -35,7 +59,7 @@ """ -GCODE_FOOT = """ +GCODE_FOOT_MELZI = """ M400 ; Wait for all moves to finish M42 P28 S0 ; Force laser off! ;M85 S30 ; re-enable idle hold timeout (BUG!) @@ -56,6 +80,9 @@ # 10mm/sec for black anodized aluminum to get maximum possible engraving! @ 100% power self.lc_travel_speed = 120 + # insert config option to enable the Melzi Marlin FW Hack (M571) + self.lc_melzi_hack = False + # BITMAP: self.lc_bitmap_speed_factor = 1.0 self.lc_dpi = 300 @@ -151,7 +178,10 @@ pix = im.load() fo = open(filename + ".g", "w") - fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) + if self.settings.lc_melzi_hack: + fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD_MELZI)) + else: + fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) fo.write(";Start engraving the raster image: %dx%d points @ %d DPI = %.0fx%.0f mm\n\n" % ( im.size[0], im.size[1], self.settings.lc_dpi, @@ -237,7 +267,10 @@ if self.settings.lc_change_dir: DIR = DIR * (-1) # change y direction on every X - fo.write(GCODE_FOOT) + if self.settings.lc_melzi_hack: + fo.write(GCODE_FOOT_MELZI) + else: + fo.write(GCODE_FOOT) fo.close() if self.pronterwindow: @@ -255,7 +288,10 @@ fi = open(filename, "r") fo = open(filename + ".g", "w") - fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) + if self.settings.lc_melzi_hack: + fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD_MELZI)) + else: + fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) G = "0" LASER_STATE = 0 @@ -303,7 +339,10 @@ print "UNKNOWN: %s" % action last_cmd = cmd - fo.write(GCODE_FOOT) + if self.settings.lc_melzi_hack: + fo.write(GCODE_FOOT_MELZI) + else: + fo.write(GCODE_FOOT) fi.close() fo.close() @@ -423,8 +462,11 @@ self.log("Scaling factor: %.2f, %.2f" % (scale_x,scale_y)) fo = open(filename + ".g", "w") - fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) - fo.write("M571 S0 E1 ; On SVG we control the laser by ourself\n") + if self.settings.lc_melzi_hack: + fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD_MELZI)) + fo.write("M571 S0 E1 ; On SVG we control the laser by ourself\n") + else: + fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) travel_speed = self.settings.lc_travel_speed * 60 engrave_speed = self.settings.lc_engrave_speed * 60 * self.settings.lc_svg_speed_factor @@ -453,6 +495,7 @@ self.log("Ignoring shape %s (%i) by stroke color" % (tag_suffix, elemidx)) skip = True break + # TODO: do a config option to enter the CUT color or something if skip: continue @@ -463,8 +506,9 @@ mat = shape_obj.transformation_matrix() if d: - fo.write("M400 ; start %s\n" % (tag_suffix)) - fo.write("G92 E0\n") + if self.settings.lc_melzi_hack: + fo.write("M400 ; start %s\n" % (tag_suffix)) + fo.write("G92 E0\n") E = 0 xo = 0 yo = 0 @@ -489,12 +533,19 @@ y = height - y # invert the bed xs = scale_x * x ys = scale_y * y - fo.write("M400 ; Wait for all moves to finish\n") - fo.write("M42 P28 S0 ; Turn off laser\n") - fo.write("G0 X%0.4f Y%0.4f F%.4f ; Move to start of shape\n" % ( - xs, ys, travel_speed)) - fo.write("M400 ; Wait for all moves to finish\n") - fo.write("M42 P28 S255 ; Turn on laser\n") + if self.settings.lc_melzi_hack: + fo.write("M400 ; Wait for all moves to finish\n") + fo.write("M42 P28 S0 ; Turn off laser\n") + fo.write("G0 X%0.4f Y%0.4f F%.4f ; Move to start of shape\n" % ( + xs, ys, travel_speed)) + fo.write("M400 ; Wait for all moves to finish\n") + fo.write("M42 P28 S255 ; Turn on laser\n") + else: + fo.write("M5 ; Turn off laser\n") + fo.write("G0 X%0.4f Y%0.4f F%.4f ; Move to start of shape\n" % ( + xs, ys, travel_speed)) + # todo: laser power as parameter? + fo.write("M3 S100 ; Turn on laser\n") xo = xs yo = ys @@ -521,11 +572,22 @@ E = E + (e_distance) if xs >= 0 and xs <= bed_max_x+0.1 and ys >= 0 and ys <= bed_max_y+0.1: - fo.write("G1 X%0.4f Y%0.4f E%.4f F%.4f\n" % ( - xs, ys, E * E_FACTOR, engrave_speed)) + if self.settings.lc_melzi_hack: + fo.write("G1 X%0.4f Y%0.4f E%.4f F%.4f\n" % ( + xs, ys, E * E_FACTOR, engrave_speed)) + else: + fo.write("G1 X%0.4f Y%0.4f F%.4f\n" % ( + xs, ys, engrave_speed)) else: - fo.write("G0 X%0.4f Y%0.4f F%.4f\n" % ( - xs, ys, travel_speed)) + if self.settings.lc_melzi_hack: + fo.write("G0 X%0.4f Y%0.4f F%.4f\n" % ( + xs, ys, travel_speed)) + else: + fo.write("M5 ; Turn off laser\n") + fo.write("G0 X%0.4f Y%0.4f F%.4f\n" % ( + xs, ys, travel_speed)) + # todo: laser power as parameter? + fo.write("M3 S100 ; Turn on laser\n") errors += 1 if errors < 10: self.log("Position outside print dimension: %d, %d" % (xs, ys)) @@ -533,15 +595,23 @@ #print " Point: ", end_pt[0], end_pt[1], pen #self.log("Laser OFF at: " + repr(sp[-1][-1])) - if shape_obj.xml_node.get('fill'): + #if shape_obj.xml_node.get('fill'): + if tag_suffix == "polygon": # Close the polygon - e_distance = math.hypot(object_xs - xo, object_ys - yo) - E = E + (e_distance) - fo.write("G1 X%0.4f Y%0.4f E%.4f F%.4f ; Close the object polygon\n" % ( - object_xs, object_ys, E * E_FACTOR, engrave_speed)) - print "connecting filled path end to start" + if self.settings.lc_melzi_hack: + e_distance = math.hypot(object_xs - xo, object_ys - yo) + E = E + (e_distance) + fo.write("G1 X%0.4f Y%0.4f E%.4f F%.4f ; Close the object polygon\n" % ( + object_xs, object_ys, E * E_FACTOR, engrave_speed)) + else: + fo.write("G1 X%0.4f Y%0.4f F%.4f ; Close the object polygon\n" % ( + object_xs, object_ys, engrave_speed)) + print "connecting filled polygon path end to start" - fo.write(GCODE_FOOT) + if self.settings.lc_melzi_hack: + fo.write(GCODE_FOOT_MELZI) + else: + fo.write(GCODE_FOOT) fo.close() if errors > 0: diff -r ea4c43494a19 -r f7e9bd735ce1 printrun-src/printrun/pronterface.py --- a/printrun-src/printrun/pronterface.py Thu May 30 19:02:52 2019 +0200 +++ b/printrun-src/printrun/pronterface.py Tue Jan 19 20:25:47 2021 +0100 @@ -316,6 +316,7 @@ def _lc_add_settings(self, size): # first add the lasercutter options self.settings._add(StaticTextSetting("separator_lc_general", "General laser settings", "", group = "Laser")) + self.settings._add(BooleanSetting("lc_melzi_hack", False, "Use Melzi M571 Hack instead M3/M5", "no description :)", "Laser"), self.update_lc_settings) self.settings._add(SpinSetting("lc_travel_speed", 120, 1, 300, "Travel speed in mm/s", "", "Laser"), self.update_lc_settings) self.settings._add(SpinSetting("lc_engrave_speed", 10, 1, 300, "Engrave speed in mm/s", "", "Laser"), self.update_lc_settings) self.settings._add(SpinSetting("lc_z_focus", 16, -80, 80, "Laser Z focus position", "", "Laser"), self.update_lc_settings) @@ -325,7 +326,7 @@ self.settings._add(StaticTextSetting("separator_lc_bitmap", "PNG Bitmap processing", "", group = "Laser")) self.settings._add(FloatSpinSetting("lc_bitmap_speed_factor", 1.0, 0.1, 2.0, "Engrave speed factor", "", "Laser"), self.update_lc_settings) - self.settings._add(SpinSetting("lc_dpi", 300, 25, 300, "Image DPI", "Image resolution for scaling", "Laser"), self.update_lc_settings) + self.settings._add(SpinSetting("lc_dpi", 300, 25, 600, "Image DPI", "Image resolution for scaling", "Laser"), self.update_lc_settings) self.settings._add(SpinSetting("lc_grey_threshold", 0, 0, 255, "Grey threshold value for RGB", "", "Laser"), self.update_lc_settings) self.settings._add(BooleanSetting("lc_invert_cut", True, "PNG: Invert grey threshold", "Invert laser on/off logic", "Laser"), self.update_lc_settings) self.settings._add(BooleanSetting("lc_change_dir", True, "PNG: Change direction", "Engrave in both directions on Y Axis", "Laser"), self.update_lc_settings) @@ -336,8 +337,8 @@ self.settings._add(StaticTextSetting("separator_lc_svg", "SVG processing", "", group = "Laser")) self.settings._add(FloatSpinSetting("lc_svg_speed_factor", 1.0, 0.1, 2.0, "Engrave speed factor", "", "Laser"), self.update_lc_settings) self.settings._add(FloatSpinSetting("lc_svg_smoothness", 0.2, 0.1, 10.0, "Smoothness", "Smoothness of curves (smaller value = smoother curve)", "Laser"), self.update_lc_settings) - self.settings._add(SpinSetting("lc_svg_width", 50, 1, 250, "Width (mm)", "Image width", "Laser"), self.update_lc_settings) - self.settings._add(SpinSetting("lc_svg_height", 50, 1, 250, "Height (mm)", "Image height", "Laser"), self.update_lc_settings) + self.settings._add(SpinSetting("lc_svg_width", 50, 1, 9999, "Width (mm)", "Image width", "Laser"), self.update_lc_settings) + self.settings._add(SpinSetting("lc_svg_height", 50, 1, 9999, "Height (mm)", "Image height", "Laser"), self.update_lc_settings) self.settings._add(ComboSetting("lc_svg_scalemode", "original", ["original", "scale", "stretch"], "Scaling mode", "scale/stretch to above dimensions", "Laser"), self.update_lc_settings) self.settings._add(BooleanSetting("lc_svg_offset", True, "Calculate offset to X=0, Y=0", "If enabled, move image to origin position", "Laser"), self.update_lc_settings)