printrun-src/printrun/laser.py

changeset 20
03b34402d405
parent 19
234037fbca4b
child 21
8551b89bd05e
equal deleted inserted replaced
19:234037fbca4b 20:03b34402d405
31 STEPS_PIXEL = MM_PIXEL * 80 # mine is 80 steps/mm on XY 31 STEPS_PIXEL = MM_PIXEL * 80 # mine is 80 steps/mm on XY
32 32
33 # FOR HPGL: 33 # FOR HPGL:
34 SCALE_FACTOR = 1.0 / 40.0 # 40 plotter units 34 SCALE_FACTOR = 1.0 / 40.0 # 40 plotter units
35 35
36 # GENERAL HEADER AND FOOTER GCODE
37 GCODE_HEAD = """
38 ; GCode generated by laser.py pronterface library (marlin code flavour)
39 ; 2015/2016 by NeoSoft - Malte Bayer
40
41 G21 ; Metric
42 ; We assume Z is in focus height and laser head is focus at bottom left of image!
43 G92 X0 Y0 E0; set zero position - new origin
44 G90 ; absolute positioning
45 M82 ; Set extruder (laser) to absolute positioning
46 M201 X1000 Y1000 E1000 ; Set acceleration
47 M203 X1000 Y1000 Z4 E1000 ; Set max feedrate
48 M209 S0 ; disable firmware retraction, we dont want to burn holes...
49 M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod
50 M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement!
51 G0 X0 Y0 F%d ; Set moving speed TRAVEL_SPEED
52 G1 X0 Y0 F%d ; Set linear engraving speed ENGRAVE_SPEED
53
54 """ % (TRAVEL_SPEED, ENGRAVE_SPEED)
55
56 GCODE_FOOT = """M400 ; Wait for all moves to finish
57 M571 S0 E0
58 M42 P28 S0 ; Force laser off!
59 M501 ; undo all settings made
60 """
36 61
37 from PIL import Image 62 from PIL import Image
38 import sys 63 import sys
39 64
40 # Imports for SVG 65 # Imports for SVG
45 70
46 71
47 class Lasercutter: 72 class Lasercutter:
48 """ 73 """
49 Lasercutter methods 74 Lasercutter methods
50 parameters: log = logger function (accepts a string) 75 parameters: log = logger function (fuction has to accept a string)
51 """ 76 """
52 def __init__(self, pronterwindow = None): 77 def __init__(self, pronterwindow = None):
53 if pronterwindow: 78 if pronterwindow:
54 self.pronterwindow = pronterwindow 79 self.pronterwindow = pronterwindow
55 self.log = pronterwindow.log 80 self.log = pronterwindow.log
81 self.pronterwindow.clear_log(None)
56 else: 82 else:
57 self.pronterwindow = None 83 self.pronterwindow = None
58 self.log = lambda : None 84 self.log = lambda : None
59 self.log("\nLasercutter library initialized resolution: %f mm per pixel" % MM_PIXEL) 85 self.log("Lasercutter library initialized\n%d DPI (%f mm/pixel)" % (DPI, MM_PIXEL))
60 if STEPS_PIXEL <= 5: 86 if STEPS_PIXEL <= 5:
61 self.log("WARNING: STEPS PER PIXEL NEEDS TO BE > 5 (otherwise marlin joins lines): %f" % STEPS_PIXEL) 87 self.log("WARNING: STEPS PER PIXEL NEEDS TO BE > 5 (otherwise marlin joins lines): %f" % STEPS_PIXEL)
88 self.log("Travel/Engrave speed: %d mm/sec, %d mm/sec" % (
89 TRAVEL_SPEED / 60, ENGRAVE_SPEED / 60) )
90 self.log("")
62 91
63 92
64 def pixel2bit(self, pixel, threshold=128): 93 def pixel2bit(self, pixel, threshold=128):
65 """Convert the pixel value to a bit.""" 94 """Convert the pixel value to a bit."""
66 # some really weird stuff here ;-P 95 # some really weird stuff here ;-P
101 self.log("size: %d x %d pixels" % im.size) 130 self.log("size: %d x %d pixels" % im.size)
102 131
103 pix = im.load() 132 pix = im.load()
104 133
105 fo = open(filename + ".g", "w") 134 fo = open(filename + ".g", "w")
106 fo.write(""" 135 fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD))
107 ; Filename: %s
108 ; GCode generated by bitplotter one-night-quick-hack script (marlin code flavour)
109 ; 2015/2016 by NeoSoft - Malte Bayer
110
111 G21 ; Metric
112 ; We assume Z is in focus height and laser head is focus at bottom left of image!
113 G92 X0 Y0 E0; set zero position - new origin
114 G90 ; absolute positioning
115 M82 ; Set extruder (laser) to absolute positioning
116 M201 X1000 Y1000 E500 ; Set acceleration
117 M203 X1000 Y1000 Z4 E10 ; Set max feedrate
118 M209 S0 ; disable firmware retraction, we dont want to burn holes...
119 M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod
120 M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement!
121 G0 X0 Y0 F%d ; Set moving speed TRAVEL_SPEED
122 G1 X0 Y0 F%d ; Set linear engraving speed ENGRAVE_SPEED
123
124 """ % (filename, TRAVEL_SPEED, ENGRAVE_SPEED) )
125 self.log("Travel/Engrave speed: %d mm/sec, %d mm/sec" % (
126 TRAVEL_SPEED / 60, ENGRAVE_SPEED / 60) )
127 136
128 fo.write(";Start engraving the raster image: %dx%d points @ %d DPI = %.0fx%.0f mm\n\n" % ( 137 fo.write(";Start engraving the raster image: %dx%d points @ %d DPI = %.0fx%.0f mm\n\n" % (
129 im.size[0], im.size[1], DPI, im.size[0]*MM_PIXEL, im.size[1]*MM_PIXEL) ) 138 im.size[0], im.size[1], DPI, im.size[0]*MM_PIXEL, im.size[1]*MM_PIXEL) )
130 139
131 INVERT_Y = MM_PIXEL * (im.size[1] -1) * (-1) 140 INVERT_Y = MM_PIXEL * (im.size[1] -1) * (-1)
182 fo.write("G1 X%.4f Y%.4f E%.4f\n" % (XMM, YMM, E * E_FACTOR)) 191 fo.write("G1 X%.4f Y%.4f E%.4f\n" % (XMM, YMM, E * E_FACTOR))
183 last_bit = bit 192 last_bit = bit
184 if CHANGE_DIRECTION: 193 if CHANGE_DIRECTION:
185 DIR = DIR * (-1) # change y direction on every X 194 DIR = DIR * (-1) # change y direction on every X
186 195
187 fo.write("""M400 ; Wait for all moves to finish 196 fo.write(GCODE_FOOT)
188 M571 S0 E0
189 M42 P28 S0 ; Force laser off!
190 M501 ; undo all settings made
191 """)
192
193 fo.close() 197 fo.close()
194 198
195 if self.pronterwindow: 199 if self.pronterwindow:
196 self.log("") 200 self.log("")
197 self.pronterwindow.load_gcode_async(filename + '.g') 201 self.pronterwindow.load_gcode_async(filename + '.g')
203 self.log("Converting HPGL plot for lasercut:") 207 self.log("Converting HPGL plot for lasercut:")
204 self.log("File: %s" % filename) 208 self.log("File: %s" % filename)
205 209
206 fi = open(filename, "r") 210 fi = open(filename, "r")
207 fo = open(filename + ".g", "w") 211 fo = open(filename + ".g", "w")
208 212 fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD))
209
210 fo.write("""
211 ; Filename: %s
212 ; GCode generated by hpglplotter (marlin code flavour)
213
214 G21 ; Metric
215 ; We assume Z is in focus height and laser head is focus at bottom left of image!
216 G92 X0 Y0 E0; set zero position - new origin
217 G90 ; absolute positioning
218 M82 ; Set extruder (laser) to absolute positioning
219 M201 X1000 Y1000 E500 ; Set acceleration
220 M203 X1000 Y1000 Z4 E10 ; Set max feedrate
221 M209 S0 ; disable firmware retraction, we dont want to burn holes...
222 M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod
223 M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement!
224 G0 X0 Y0 F%d ; Set moving speed TRAVEL_SPEED
225 G1 X0 Y0 F%d ; Set linear engraving speed ENGRAVE_SPEED
226
227 """ % (filename, TRAVEL_SPEED, ENGRAVE_SPEED) )
228 213
229 G = "0" 214 G = "0"
230 LASER_STATE = 0 215 LASER_STATE = 0
231 last_coord = [0.0,0.0] 216 last_coord = [0.0,0.0]
232 last_cmd = "" 217 last_cmd = ""
265 print "Ignoring pen thickness" 250 print "Ignoring pen thickness"
266 else: 251 else:
267 print "UNKNOWN: %s" % action 252 print "UNKNOWN: %s" % action
268 last_cmd = cmd 253 last_cmd = cmd
269 254
270 255 fo.write(GCODE_FOOT)
271 fo.write("""M400 ; Wait for all moves to finish
272 M571 S0 E0
273 M42 P28 S0 ; Force laser off!
274 M501 ; undo all settings made
275 """)
276
277 fi.close() 256 fi.close()
278 fo.close() 257 fo.close()
279 258
280 if self.pronterwindow: 259 if self.pronterwindow:
281 self.log("") 260 self.log("")
283 262
284 263
285 def svg2gcode(self, filename, bed_max_x = 50, bed_max_y = 50, smoothness = 0.2): 264 def svg2gcode(self, filename, bed_max_x = 50, bed_max_y = 50, smoothness = 0.2):
286 self.log("Generating paths from SVG...") 265 self.log("Generating paths from SVG...")
287 266
288 preamble = """
289 ; Filename: %s
290 ; GCode generated by bitplotter one-night-quick-hack script (marlin code flavour)
291 ; 2015/2016 by NeoSoft - Malte Bayer
292
293 G21 ; Metric
294 ; We assume Z is in focus height and laser head is focus at bottom left of image!
295 G92 X0 Y0 E0; set zero position - new origin
296 G90 ; absolute positioning
297 M82 ; Set extruder (laser) to absolute positioning
298 M201 X1000 Y1000 E500 ; Set acceleration
299 M203 X1000 Y1000 Z4 E10 ; Set max feedrate
300 M209 S0 ; disable firmware retraction, we dont want to burn holes...
301 M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod
302 M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement!
303 G0 X0 Y0 F%d ; Set moving speed TRAVEL_SPEED
304 G1 X0 Y0 F%d ; Set linear engraving speed ENGRAVE_SPEED
305
306 """ % (filename, TRAVEL_SPEED, ENGRAVE_SPEED)
307 self.log("Travel/Engrave speed: %d mm/sec, %d mm/sec" % (
308 TRAVEL_SPEED / 60, ENGRAVE_SPEED / 60) )
309
310 postamble = """M400 ; Wait for all moves to finish
311 M571 S0 E0
312 M42 P28 S0 ; Force laser off!
313 M501 ; undo all settings made
314 """
315 shape_preamble = "G92 E0\n" 267 shape_preamble = "G92 E0\n"
316 shape_postamble = "" 268 shape_postamble = ""
317
318 269
319 """ 270 """
320 Used to control the smoothness/sharpness of the curves. 271 Used to control the smoothness/sharpness of the curves.
321 Smaller the value greater the sharpness. Make sure the 272 Smaller the value greater the sharpness. Make sure the
322 value is greater than 0.1 273 value is greater than 0.1
346 scale_y = bed_max_y / max(width, height) 297 scale_y = bed_max_y / max(width, height)
347 298
348 self.log("Scaling factor: %.2f, %.2f" % (scale_x,scale_y)) 299 self.log("Scaling factor: %.2f, %.2f" % (scale_x,scale_y))
349 300
350 fo = open(filename + ".g", "w") 301 fo = open(filename + ".g", "w")
351 fo.write(preamble) 302 fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD))
352 303
353 for elem in root.iter(): 304 for elem in root.iter():
354 try: 305 try:
355 _, tag_suffix = elem.tag.split('}') 306 _, tag_suffix = elem.tag.split('}')
356 except ValueError: 307 except ValueError:
391 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f\n" % (xs, ys, E * E_FACTOR, ENGRAVE_SPEED)) 342 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f\n" % (xs, ys, E * E_FACTOR, ENGRAVE_SPEED))
392 else: 343 else:
393 self.log("Position outside print dimension: %d, %d" % (xs, ys)) 344 self.log("Position outside print dimension: %d, %d" % (xs, ys))
394 fo.write(shape_postamble) 345 fo.write(shape_postamble)
395 346
396 fo.write(postamble) 347 fo.write(GCODE_FOOT)
397 fo.close() 348 fo.close()
398 349
399 if self.pronterwindow: 350 if self.pronterwindow:
400 self.log("") 351 self.log("")
401 self.pronterwindow.load_gcode_async(filename + '.g') 352 self.pronterwindow.load_gcode_async(filename + '.g')
402 353

mercurial