" VIM script to post process LightBurn CNC laser GRBL gcode converting it to " plasma process gcode. " " Pre-requisite: In LB, select device type GRBL-M3 for code generation. " author: Lou Cipriano 1/18/22 " " Net actions: replace M3 and M5 gcode commands with plasma torch touchoff probes " and retracts respectively. " " Specifically, post process gcode file to change or add these functions: " 1. replace M3 with a block of gcode to begin a plasma cut. " 2. replace M5 with a block of gcode to end a plasma cut. " 3. optionally, add a timed and lateral move to the Z axis transition from Pierce Height " to Initial Torch Height, the lateral move being the " plasma lead-in cut, and the timed element being a component of the " Pierce Delay. These actions should reduce the risk of torch tip " collision with blowback dross during the pierce. " This effectively 'Z ramp move' is optional since there are some instances where LB " does not use a lead-in, such as during tab/bridge cutting and when not " programmed into the layer. BTW - if using lead-in, use a line lead-in, " not an arc lead-in since arcs are just tiny line segments in LB. " 3.5 Its now OK to process a gcode file twice with this script, once as " Plunge Z.. MyPlasmaPP(0), and once as Ramp Z... MyPlasmaPP(1). " This way you can combine both styles of pierce hole effect into " one job. Use the 'Y'/'N' reply to the replace of M3 and M5 commands " during the first pass selectively only changing the Plunge Z " cuts/instances. On the second pass/invocation, reply 'A'll to the " M3 and M5 replace prompts to change the rest. " " Script Usage- " The code is defined to run as a VIM user defined funtion MyPlasmaPP(). " When editing the LB generated gcode file, simple press to enter command mode, then " type ':Call MyPlasmaPP()' enter " to use default args, appropriate for cutting 18ga. to 10ga. mild steel with " Ramp Z pierce effect. " " Args- " MyPlasmaPP([isRampZ], [ITH], [PD], [PH]) " Default arg values- isRampZ=1, ITH=1.5, PD=1.1, PH=ITH*2.2 " " Override default args as desired. For example - " :Call MyPlasmaPP(1, 2.0) " for the case of gcode generated with a line lead-in to use Z ramp and an ITH of 2.0mm. " ITH and PH are always specified in mm then converted in the script " if necessary to match the units mode that LB had generated into the file. " " Respond 'a' to the 'replace with \=subtext' message to change ALL occurances of M3 commands. " Do the same in the next message, which replaces all occurances of M5 commands. " Define the function to VIM one time by adding stmt " ':source \plasmapp5.vim' " to the VIM Startup Settings file (menu Edit-Startup Settings) _vimrc. " Download VIM editor at vim.org. Use version 8.2 or later. function MyPlasmaPP(isRampZ=1, ITH=1.5, PD=1.1, PH=a:ITH*2.2) :let s:firstPassMark = ";MyPlasmaPP() V5" " set window to scroll from center of screen while script runs, " makes it easy to watch the M3 and M5 replace context when responding Y or N. :setlocal scrolloff=999 " Initial Torch Height or cutting height (ITH) in mm :let s:ITH = a:ITH " Pierce Height (PH) in mm :let s:PH = a:PH " Pierce Delay (PD) in seconds " This pierce method has Z is moving during pierce either in a ramp (w XY on line lead=in) " or in a plunge when no lead-in. The dwell time while Z is static at beginning of pierce " is intended to account for most of the mechanical relay and pneumatic soleniod reaction " delays in the torch trigger circuit. After that dwell, beginning moving Z as the plasma " jet begins to pierce the metal. Movement of the torch at this time " provides for some control of the blowback pierce dross. For instance, a gouge effect can " be made if Z moves either ramp or plunge, but the timing varies for each, thus this " code not only splits the overall Pierce Delay value, but also makes the static dwell " dependent on the Z move type. :let s:PD = a:PD :let s:dwellPD = s:PD * (a:isRampZ ? 0.6 : 0.4) :let s:zG93Feed = 60.0 / (s:PD - s:dwellPD) "inverse time feed rate for G93 mode during Z ramp or plunge " Torch Probe Travel (TPT) in mm " This is the travel of the torch on the gravity fed Z carriage once the torch " tip contacts the top of material and until the probe switch is closed. :let s:TPT = 8.6 " Safe Retract (SR) in mm :let s:SR = 20 " M5 Safe Retract Delay (M5RD) in seconds :let s:M5RD = 1.0 :let s:PH2ITH = s:ITH - s:PH "calc distance and direction for transition from PH to ITH :let s:restoreMoveModes = "" " determine the move units and move type of XYZ axis movement commands. " LB puts G20 or G21 values on command line begining with 'G00' " and the next command line is the G90 or G91 type " So, search from top of file (gg) for 'G00' in col 1... :exe "normal gg/^G00\r" :let s:isG20mode = search('G20', "", line(".")) "G20 imperial, else must be G21 metric :let s:isG90mode = search('G90', "", line(".")+1) "G90 absolute, else must be G91 relative " allow for 2 pass use of MyPlasmaPP(). " this is desireable if you'd like to have rampZ and plunge pierce moves " in one job file, rather than separating into 2 files at LB gen time. :exe "normal gg" :let s:isSecondPass = search(s:firstPassMark, "cn", line(".")) :if !s:isSecondPass " find the first feedrate and save it " feedrate must be last value in the line, it usually is :) " Normal command is defined as follows: " gg (goto top of file), /^M3\r (find first M3 in col 1), jfF (down one line, " find F), d$ (delete to end of line and save Fnnn value to @- reg) :exe "normal gg/^M3\rjfFd$" :let s:TrestoreFeedrate = @- "deleted chars are Feedrate as text data type, such as Fnnnn " store the firstpass mark and orginal feedrate in the first line of the file :exe "normal ggi" .. s:firstPassMark s:TrestoreFeedrate .. "\r" :else " find the feedrate in the first line appended to the MyPlasmaPP() marker... :exe "normal ggfFy$" :let s:TrestoreFeedrate = @0 "yanked chars are Feedrate as text data type, such as Fnnnn :endif " handle absolute (G90) vs relative (G91) gcode move modes :if s:isG90mode :let s:PH2ITH = s:ITH "PH to ITH is now relative to Z0 :let s:restoreMoveModes .= "G90 " :endif " handle imperial (G20) vs metric (G21) gcode unit modes :if s:isG20mode :let s:PH2ITH /= 25.4 " PH2ITH was set in mm units, convert to imperial :let s:restoreMoveModes .= "G20 " :endif " Build the Torch Probe Touchoff gcode block that will replace the LB planted M3 commands. " :let s:subtext = "\r;begin torch touchoff probe: " :let s:subtext .= printf("isRampZ=%d, ITH=%.1fmm, PD=%.1fs, PH=%.1fmm\r",a:isRampZ,s:ITH,s:PD,s:PH) :let s:subtext .= "G21 G91 (metric and relative)\r" :let s:subtext .= "G38.2 " .. printf("Z-%.3f",(s:SR+s:TPT+s:ITH+2.0)) .. " F1000 (probe fast to find limit switch)\r" :let s:subtext .= "G0 Z5 (pull off limit switch, ready for slow probe)\r" :let s:subtext .= "G4 P0.400 (delay for probe switch debounce)\r" :let s:subtext .= "G38.2 Z-5 F50 (probe slow for accurate make on switch)\r" :let s:subtext .= "G0 " .. printf("Z%.3f",s:TPT) .. " (retract TPT, to top of material)\r" :let s:subtext .= "G92 Z0 (reset temp Z0 in case of absolute mode gcode file gen)\r" :let s:subtext .= "G0 " .. printf("Z%.3f",s:PH) .. " (retract to PH)\r" :let s:subtext .= "M3 (light it up)\r" :let s:subtext .= "G4 " .. printf("P%.3f (partial pierce delay- set THC DLY=>%.1f)\r",s:dwellPD,s:PD+0.7) :let s:subtext .= s:restoreMoveModes != "" ? s:restoreMoveModes .. " (restore changed modes)\r" : "" :if !a:isRampZ :let s:subtext .= "G1 G93 " .. printf("F%.3f Z%.3f",s:zG93Feed,s:PH2ITH) .. " (plunge Z, remainder of PD)\r" :let s:subtext .= "G94 (restore distance units move mode)\r" :let s:subtext .= s:TrestoreFeedrate .. " (restore feedrate)\r" :let s:subtext .= ";end probe Plunge ITH\r" :else :let s:rampZmark = ";end probe RampZ ITH" :let s:subtext .= s:rampZmark .. "\r" :endif " Replace all instances of LB planted M3 commands, beginning in col 1 and " where M3 is the only word on the line, replace with " Torch Probe Touchoff gcode block created above. :%s/^M3$/\=s:subtext/c " Build the Torch Retract gcode block that will replace the LB planted M5 commands " :let s:subtext = "\r;begin safe retract and ready for probing next cut ITH\r" :let s:subtext .= "G21 G91 (metric and relative)\r" :let s:subtext .= "M5 (put it out)\r" :let s:subtext .= "G4 " .. printf("P%.3f",s:M5RD) .. " (wait for THC to give Z control back to GRBL)\r" :let s:subtext .= "G0 " .. printf("Z%.3f",s:SR) .. " (fast retract to safe height)\r" :let s:subtext .= s:restoreMoveModes != "" ? s:restoreMoveModes .. " (restore changed modes)\r" : "" :let s:subtext .= ";end safe retract and ready ITH\r" " Replace 2nd and all subsequent instances of LB planted M5 commands, " beginning in col 1 and where M5 is the only word on the line, replace with " the retract code block created above. " goto top of file, find the 2nd M5 in col 1, then replace from here to EOF. :exe "normal gg2/^M5\r" :.,$s/^M5$/\=s:subtext/c " if using lead-ins and desiring to ramp Z down during transition from PH to ITH, " then this code needs to append a few commands to the line lead-in cut " Note that when using LB tabs or bridges, lead-ins are not applied to those " cuts, so consider cutting any Tab Enable layer separately and first, using the " isRampZ=0 arg " " append Z PH-to-ITH transition movement to the pierce XY cut, which should be a line lead=in cut. " this effects a ramp down of Z to the ITH. Also, make this a 'timed' mode " feedrate rather than the usual distance mode feedrate. The time duration " of the cut is a component of the pierce delay, this further mitigates risk " of torch tip collision with pierce dross. " " Build the 'Normal' command sequence which will run after each find hit... :if a:isRampZ :let s:cmd = "jj$a " :let s:cmd .= "G93 " .. printf("F%.3f Z%.3f",s:zG93Feed,s:PH2ITH) .. " (ramp Z, remainder of PD)\r" :let s:cmd .= "G94 (restore distance units move mode)\r" :let s:cmd .= s:TrestoreFeedrate .. " (restore feedrate)\r" " append to line lead-ins throughout the file, which will follow the original M3 commands, " which have become comment ';end probe ITH' beginning in col 1 of lines in " which it appears. :exe ':%g/^' .. s:rampZmark .. '/normal' s:cmd :endif " return window scrolling to VIM default :setlocal scrolloff< :endfunction