New post processor for JD's Garage Plasma Cutter (Gen 2)

I am new to Sheetcam still, but I have created a Post Processor for the JD’s Garage Plasma Cutter Gen 2 and similar machines that use grblHAL on an ESP32, with the Z-probe. I started with JD’s recommended “GRBL THC with scribe” post processor, and then I made several modifications that made the post-processor work a bit better for me and machines like mine. Also, being a very nerdy software engineer, I also made the g-code a little bit easier for me to follow and modify - and especially to create variants when I need to fix just one part of a cut. The comments in the g-code include a Cut # that matches up to Sheetcam’s numbers (S1, S2, etc.). I’m sure this post-processor is not perfect, I already have seen a few things I’d like to fix, but it works exceptionally well for me - better than the Fusion 360 GRBL post processor (though I don’t attribute that so much to my changes but more to the original that I modified.)

To provide a few more details that may be helpful. My machine is based on the JD’s Garage Generation 2 machine (which for anyone who is not aware comes from a set of plans that may be purchased for $25 US and which appears to be a clone of the entry-level Langmuir Systems Crossfire CNC plasma machine - right down to identical looking 3D printed parts.) I originally built the Gen 1 JD’s garage machine but had a ton of problems with it from problems with the 3D printed parts holding threads, to friction on the suspended arm, to the worst problem of all EMI on the Z-probe. I eventually gave up on their GEN 1 and started modifying my machine. I made it much bigger, added linear rails and a second Y rail and motor, and replaced their Z axis with one from Amazon. I threw out ALL of the 3D printed parts and made everything from metal - except that I did 3D print a breakaway magnetic torch holder. I added a DANI THC11DPL Torch Height Controller while I patiently waited for JD’s Garage to release their THC. (I bought theirs but have never hooked it up, the DANI THC works great, and in my experience, he is much easier to work with and get support from than the JD’s garage guys were before they decided I was too much of pain to deal with because I asked questions.) Because I also had problems with the JD’s garage Z-axis binding up and causing the probe switch to sometimes stick and other problems, when I replaced it with an 100mm Linear Stage Actuator for the Z-axis, I needed to make a new probe, so I designed an ohmic sensor that clamps to the torch and feeds a signal into a CNC4PC PTS-1 Plasma Touch Probe.

It was about the time that I decided to tackle the relentless EMI problems with the Z-probe (that still happened with the PTS-1) that JD’s Garage announced their Gen 2 machine. I bought the plans and converted my electronics over to match (mostly), but using the DANI THC and the PTS-1. I also made several other changes to fix issues with JD’s garage Gen 2 electronics, such as burning the e-fuse that lets you get rid of the otherwise completely unnecessary 2nd relay - which is only there because pin 12 on the ESP32 is a “strapping pin” which can’t be directly connected to the X PUL- on the X motor driver during the first 1ms of ESP32 startup without dropping the voltage to the internal SD storage to an unusable level – unless you burn the e-fuse freeing up the pin, and I modified the grblHAL + Blackbox driver code to send an enable signal on PIN 25 of the ESP32 for the PTS-1 during a probe operation). While redoing the electronics, I also put copper tape around EVERY wire, and I added a bypass capacitor to the Z-probe signal and several ferrite cores to the Z-probe signal inside the electronics box and near the torch. This fixed my EMI problems, and after 2 years of struggling with JD’s garage plans I finally have a working CNC Plasma Cutter!

I switched to Sheetcam because I have been considering selling some of my work (DXF files and/or physical pieces), but Fusion 360’s license is too restrictive and too costly for someone just starting up. A one-time fee for Sheetcam gets me in the clear and as I mentioned previously seems to work better anyway. (I have been doing my designs with Bend-Tech Pro’s Sheet Metal designer - also because it was a one-time license fee.)

Anyway - after my long rambling… The post-processor is attached. The only variables you need to worry about are listed and as follows:

  • switchOffset - This defaults to 0.0 because my ohmic sensor doesn’t have an offset, but the stock JD’s Garage z-axis needs an offset to account for the distance you have to lift Z to get the switch to release and have the torch just barely touch the metal. Enter this in mm.
  • firstPierceTime - This is left over from the GRBL THC with scriber post-processor, defaults to 0, but might be useful for some machines
  • maxZProbeDistance - This is the maximum length of the Z-probe. I set it to the full-travel length in mm of my Z axis. You probably don’t need to change it for a stock JD’s Garage machine, but it is there just in case.

One of my modifications was to make sure there is a Z-probe before every cut. I also added a lot of comments to help make sense of what the g-codes do especially around probes and oddities of the grblHAL (such as the error 33 after a probe on Arcs.)

I hope you find this useful, and I want to make sure that everyone knows that I couldn’t have done it without the excellent work of the author of the GRBL THC with scriber.scpost.

Since I am a new user, I’m not allowed to upload the post-processor, so here it is in text:
grblHALPlasmaZProbe.scpost

--************************************************
--*** Set these values up to suit your machine ***
--************************************************

--Put your switch offset value here in MILLIMETRES
--For Switch-based probes:
-- Put a sheet of metal on your machine and place a sheet of paper on top.
-- Slowly jog the torch down onto the paper until the touch-off switch just operates.
-- Zero the Z axis then pull gently on the paper and slowly jog up until the paper slides out.
-- The Z axis position is your switch offset.
--For Ohmic Probes:
-- Set to 0.0.  If you need to back-off from the point of probe contact put the distance in MILLIMETERS here
switchOffset = 0.0

--this is an extra delay added to the first pierce as needed by some machines
firstPierceTime = 0 

--Maximum Z-probe distance in MILLIMETERS
maxZProbeDistance = 100

--************************************************
--***           End of settings                ***
--************************************************

--************************************************
--***          GLOBAL VARIABLES                ***
--************************************************
--Cut Counter, just to keep track
cutCount = 0

--Last cutCount where Cut Height Comment was shown
cutCountHeightComment = 0



function OnAbout(event)
   ctrl = event:GetTextCtrl()
   ctrl:AppendText("grblHAL Plasma Cutter with Z probe\n")
   ctrl:AppendText("Written by Andrew L. Sandoval - based on GRBL THC with scriber.scpost\n")
   ctrl:AppendText("\n")
   ctrl:AppendText("Modal G-codes and coordinates\n")
   ctrl:AppendText("Comments enclosed with ( and )\n")
   ctrl:AppendText("M03/M05 turn the torch on/off\n")
   ctrl:AppendText("The torch is referenced with a Z-probe before each pierce\n")
   ctrl:AppendText("Designed for use with grblHal and a z-probe\n")
   ctrl:AppendText("Post variables:\n")
   ctrl:AppendText("switchOffset - set your net switch offset amount\n")
   ctrl:AppendText("maxZProbeDistance - set the maximum Z-probe distance\n")
end


--   Modified 10/14/24 by Andrew L. Sandoval
--   Based on GRBL THC with scribe

post.DefineVariable("switchOffset",sc.unitLINEAR,-1e17,1e17)
post.DefineVariable("maxZProbeDistance",sc.unitLINEAR,0,1e17)

function OnInit()

   offX = 0
   offY = 0
   offZ = 0

   post.SetCommentChars ("()", "[]")  --make sure ( and ) characters do not appear in system text
   commentText = "Post: " .. postName .. " Andrew L. Sandoval"
   OnComment()

   commentText = fileNameOnly .. " " .. " " .. date .. " " .. time
   OnComment()

   if(scale == metric) then
      commentText = "Metric Mode"
      OnComment()
      post.Text ("G21\n") --metric mode
   else
      commentText = "Inch Mode"
      OnComment()
      post.Text ("G20\n") --inch mode
   end
   post.Text ("G53 G90 G40\n")
   minArcSize = 0.2 --arcs smaller than this are converted to moves
   firstRef = true
   currentZAxis = "Z"

   dist = 9999999
   lastz = 0
   thcstate = 1
   firstPierce = firstPierceTime;

   commentText = "Feedrate: " .. var.JetOperation0_FeedRate .. " mm/min " .. (var.JetOperation0_FeedRate * (1/25.4)) .. " inches/min"
   OnComment()

   commentText = "Plunge rate: " .. var.JetOperation0_PlungeRate .. " mm/min " .. (var.JetOperation0_PlungeRate * (1/25.4)) .. " inches/min"
   OnComment()

   commentText = "Plunge Saftey: " .. plungeSafety .. " mm " .. (plungeSafety * (1/25.4)) .. " inches"
   OnComment()

   commentText = "Safe Z: " .. safeZ .. " mm " .. (safeZ * (1/25.4)) .. " inches"
   OnComment()
end

function OnNewLine()
   post.Text ("N")
   post.Number (lineNumber, "0000")
   post.Text(" ")
   lineNumber = lineNumber + 10
end


function OnFinish()
   endZ = safeZ
   OnRapid()
   endX = 0
   endY = 0
   offX = 0
   offY = 0
   offZ = 0
   OnRapid()
   post.Text ("M05\n")  -- Torch Off
   post.ModalText ("G00 X0 Y0")  -- Go Home, with Z at safe height
   if(currentZ ~= safeZ) then
      post.ModalNumber (" " .. currentZAxis, safeZ * scale, "0.0000")
      post.Eol()
   end
   post.Text("M30\n")  -- Reset
   cutCount = 0
end

function OnRapid()
   if(endX > 1e17 and endY > 1e17) then return end
   local len = math.hypot((endX + offX)-currentX , (endY + offY)-currentY)
   dist = dist + len
   post.ModalText ("G00 ")
   post.ModalNumber ("X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ and firstRef == false and currentZ ~= safeZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.Eol()
end

function OnMove()
   post.CancelModaltext()
   post.CancelModalNumbers()
   local len = math.hypot(endX - currentX , endY - currentY)
   dist = dist + len
   post.ModalText ("G01")
   post.ModalNumber (" X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.ModalNumber (" F", feedRate * scale, "0.0###")
   if(cutCountHeightComment < cutCount) then
      commentText = "Cut Height: " .. cutHeight .. " mm " .. (cutHeight * (1/25.4)) .. " inches"
      OnCommentSpace()
      cutCountHeightComment = cutCount
   end
   post.Eol()
end

function OnArc()
   post.CancelModaltext()
   post.CancelModalNumbers()
   local radius = math.hypot(currentX - arcCentreX, currentY - arcCentreY)
   dist = dist + radius * math.abs(arcAngle)

   if(arcAngle <0) then
      post.ModalText ("G03")
   else
      post.ModalText ("G02")
   end
   post.ModalNumber (" X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.Text (" I")
   post.Number ((arcCentreX - currentX) * scale, "0.0000")
   post.Text (" J")
   post.Number ((arcCentreY - currentY) * scale, "0.0000")
   post.ModalNumber (" F", feedRate * scale, "0.0###")
   post.Eol()
end

function OnPenDown()
   cutCount = cutCount + 1
   -- Always Reference() before starting a cut, regardless of dist
   -- this matches how the Fusion 360 GRBL post processor works and ensure each new
   -- cut starts at the proper height
   commentText = "Cut " .. cutCount .. " X=" .. (scale*currentX) .. " Y=" .. (scale*currentY)
   OnComment()

   Reference();  -- Z-probe
   post.ModalText ("G00")
   post.Text(" Z")
   post.Number (pierceHeight * scale, "0.0000")
   commentText = "Z @ pierce height: " .. pierceHeight .. " mm " .. (pierceHeight * (1/25.4)) .. " inches"
   OnCommentSpace()
   post.Eol()
   post.Text ("M03\n")
   if (pierceDelay + firstPierce > 0.001) then
      post.Text ("G04 P")
      post.Number (pierceDelay + firstPierce,"0.0##")
      firstPierce = 0
      commentText = "Pierce Delay: " .. pierceDelay .. " seconds"
      OnCommentSpace()
      post.Eol()
   end
   -- Reset G0 after G38.2 to avoid Error 33 from GRBL
   post.Text("G00 X")
   post.Number(currentX * scale, "0.0000")
   post.Text(" Y")
   post.Number(currentY * scale, "0.0000")
   post.Text(" Z")
   post.Number(pierceHeight * scale, "0.0000")
   post.Text(" F")
   post.Number (plungeRate * scale, "0.0###")
   commentText = "Reset position after probe to prevent GRBL error 33"
   OnCommentSpace()
   post.Eol()
   -- ^^^
end

function OnNewOperation()
   commentText = "Operation: " .. operationName .. " OpIndex: " .. operationIndex
   OnComment()
end

function OnNewPart()
   commentText = "Part: " .. partName .. " partIndex: " .. partIndex
   OnComment()
end

function OnSetFeed()
   post.ModalNumber ("F", feedRate * scale, "0.0###")
   commentText = "Feedrate: " .. feedRate .. " mm/min " .. (feedRate * (1/25.4)) .. " inches/min"
   OnCommentSpace()
   post.Eol()
end

function Reference()
   firstRef = false

   post.ModalText("G38.2 Z")
   post.Number((-1 * maxZProbeDistance) * scale, "0.0##")
   post.ModalNumber (" F", plungeRate * scale, "0.0###")
   commentText = "Z-probe with Feedrate: " .. plungeRate .. " mm/min " .. (plungeRate * (1/25.4)) .. " inches/min"
   OnCommentSpace()   
   post.Eol()

   post.ModalText("G92 Z0.0")  -- Z0 is now where the Z-probe triggers (touches)
   commentText = "Z = Probe Touch/Trigger"
   OnCommentSpace()
   post.ModalText ("G00")
   post.Text(" Z")
   post.Number (switchOffset * scale, "0.0000")
   commentText = "switchOffset " .. switchOffset .. " mm " .. (switchOffset * scale) .. " inches"
   OnCommentSpace()
   post.Eol()
   post.ModalText("G92 Z0.0")  -- Z0 is now where the Z-probe has backed off to the point where the nozzle just touches
   commentText = "Z = nozzle touching metal (e.g. adjusted by switch Offset)"
   OnCommentSpace()
end

function OnPenUp()
   post.Text ("M05\n")
   if (endDelay > 0) then
      post.Text ("G04 P")
      post.Number (endDelay,"0.###")
      post.Eol()
   end
end

function OnToolChange()
    offX = 0
    offY = 0
    offZ = 0
end

function OnDrill()
   OnRapid()
   currentX = endX
   currentY = endY
   OnPenDown()
   endZ = drillZ
   OnMove()
   OnPenUp()
   endZ = safeZ
   OnRapid()
end


function OnComment()
  post.Text("(",commentText,")\n")
end

function OnCommentSpace()
  post.Text(" (",commentText,")\n")
end

Well done! Thanks for contributing your post processor. I believe we have many sheetcam users running grbl.
Welcome to the sheetcam community forum.

1 Like

@alsandoval i’m having the error 33 on the first arc and everything aborts.
I also have the JDG 2.0 with Z no THC
I will try your post to see if it solves my problems
I tried the one GRBL plasma LDC v24-12-8 from @bLouChip, it doesn’t error out however the torch run too far off the material.
In both your scpost I’m trying to read the comments to understand and I’m quickly over my head.
I need to figure out how to setup the height correctly.

Try the latest version in this forum post-

I added some simplified usage instructions.

In the output from my post-processor, you will see comments like the one on this line:

N0230 G00 X2.4253 Y0.0950 Z0.1181 F8.0 (Reset position after probe to prevent GRBL error 33)

This error 33 is due to a bug in the grblHal code/firmware, but resetting the position seems to fix it for me - which is why I include that comment every time I repeat/reset the position prior to an arc.

Also, FWIW, I found a small bug in my post-processor when I was using drilling operations (which I used to mark a spot with the plasma cutter for drilling, since the plasma cutter doesn’t do a great job with round holes in thick material - like the 1/2" steel I was cutting). The bug is in the OnInit() function. The fixed grblHALPlasmaZProbe.scpost is in the text below:

--************************************************
--*** Set these values up to suit your machine ***
--************************************************

--Put your switch offset value here in MILLIMETRES
--For Switch-based probes:
-- Put a sheet of metal on your machine and place a sheet of paper on top.
-- Slowly jog the torch down onto the paper until the touch-off switch just operates.
-- Zero the Z axis then pull gently on the paper and slowly jog up until the paper slides out.
-- The Z axis position is your switch offset.
--For Ohmic Probes:
-- Set to 0.0.  If you need to back-off from the point of probe contact put the distance in MILLIMETERS here
switchOffset = 0.0

--this is an extra delay added to the first pierce as needed by some machines
firstPierceTime = 0 

--Maximum Z-probe distance in MILLIMETERS
maxZProbeDistance = 100

--************************************************
--***           End of settings                ***
--************************************************

--************************************************
--***          GLOBAL VARIABLES                ***
--************************************************
--Cut Counter, just to keep track
cutCount = 0

--Last cutCount where Cut Height Comment was shown
cutCountHeightComment = 0



function OnAbout(event)
   ctrl = event:GetTextCtrl()
   ctrl:AppendText("grblHAL Plasma Cutter with Z probe\n")
   ctrl:AppendText("Written by Andrew L. Sandoval - based on GRBL THC with scriber.scpost\n")
   ctrl:AppendText("\n")
   ctrl:AppendText("Modal G-codes and coordinates\n")
   ctrl:AppendText("Comments enclosed with ( and )\n")
   ctrl:AppendText("M03/M05 turn the torch on/off\n")
   ctrl:AppendText("The torch is referenced with a Z-probe before each pierce\n")
   ctrl:AppendText("Designed for use with grblHal and a z-probe\n")
   ctrl:AppendText("Post variables:\n")
   ctrl:AppendText("switchOffset - set your net switch offset amount\n")
   ctrl:AppendText("maxZProbeDistance - set the maximum Z-probe distance\n")
end


--   Modified 10/14/24 by Andrew L. Sandoval
--   Based on TRBL THC with scribe

post.DefineVariable("switchOffset",sc.unitLINEAR,-1e17,1e17)
post.DefineVariable("maxZProbeDistance",sc.unitLINEAR,0,1e17)

function OnInit()

   offX = 0
   offY = 0
   offZ = 0

   post.SetCommentChars ("()", "[]")  --make sure ( and ) characters do not appear in system text
   commentText = "Post: " .. postName .. " Andrew L. Sandoval"
   OnComment()

   commentText = fileNameOnly .. " " .. " " .. date .. " " .. time
   OnComment()

   if(scale == metric) then
      commentText = "Metric Mode"
      OnComment()
      post.Text ("G21\n") --metric mode
   else
      commentText = "Inch Mode"
      OnComment()
      post.Text ("G20\n") --inch mode
   end
   post.Text ("G53 G90 G40\n")
   minArcSize = 0.2 --arcs smaller than this are converted to moves
   firstRef = true
   currentZAxis = "Z"

   dist = 9999999
   lastz = 0
   thcstate = 1
   firstPierce = firstPierceTime;

   if(var.JetOperation0_FeedRate) then
   commentText = "Feedrate: " .. var.JetOperation0_FeedRate .. " mm/min " .. (var.JetOperation0_FeedRate * (1/25.4)) .. " inches/min"
   OnComment()
   end

   if(var.JetOperation0_PlungeRate) then
   commentText = "Plunge rate: " .. var.JetOperation0_PlungeRate .. " mm/min " .. (var.JetOperation0_PlungeRate * (1/25.4)) .. " inches/min"
   OnComment()
   end

   commentText = "Plunge Saftey: " .. plungeSafety .. " mm " .. (plungeSafety * (1/25.4)) .. " inches"
   OnComment()

   commentText = "Safe Z: " .. safeZ .. " mm " .. (safeZ * (1/25.4)) .. " inches"
   OnComment()
end

function OnNewLine()
   post.Text ("N")
   post.Number (lineNumber, "0000")
   post.Text(" ")
   lineNumber = lineNumber + 10
end


function OnFinish()
   endZ = safeZ
   OnRapid()
   endX = 0
   endY = 0
   offX = 0
   offY = 0
   offZ = 0
   OnRapid()
   post.Text ("M05\n")  -- Torch Off
   post.ModalText ("G00 X0 Y0")  -- Go Home, with Z at safe height
   if(currentZ ~= safeZ) then
      post.ModalNumber (" " .. currentZAxis, safeZ * scale, "0.0000")
      post.Eol()
   end
   post.Text("M30\n")  -- Reset
   cutCount = 0
end

function OnRapid()
   if(endX > 1e17 and endY > 1e17) then return end
   local len = math.hypot((endX + offX)-currentX , (endY + offY)-currentY)
   dist = dist + len
   post.ModalText ("G00 ")
   post.ModalNumber ("X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ and firstRef == false and currentZ ~= safeZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.Eol()
end

function OnMove()
   post.CancelModaltext()
   post.CancelModalNumbers()
   local len = math.hypot(endX - currentX , endY - currentY)
   dist = dist + len
   post.ModalText ("G01")
   post.ModalNumber (" X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.ModalNumber (" F", feedRate * scale, "0.0###")
   if(cutCountHeightComment < cutCount) then
      commentText = "Cut Height: " .. cutHeight .. " mm " .. (cutHeight * (1/25.4)) .. " inches"
      OnCommentSpace()
      cutCountHeightComment = cutCount
   end
   post.Eol()
end

function OnArc()
   post.CancelModaltext()
   post.CancelModalNumbers()
   local radius = math.hypot(currentX - arcCentreX, currentY - arcCentreY)
   dist = dist + radius * math.abs(arcAngle)

   if(arcAngle <0) then
      post.ModalText ("G03")
   else
      post.ModalText ("G02")
   end
   post.ModalNumber (" X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.Text (" I")
   post.Number ((arcCentreX - currentX) * scale, "0.0000")
   post.Text (" J")
   post.Number ((arcCentreY - currentY) * scale, "0.0000")
   post.ModalNumber (" F", feedRate * scale, "0.0###")
   post.Eol()
end

function OnPenDown()
   cutCount = cutCount + 1
   -- Always Reference() before starting a cut, regardless of dist
   -- this matches how the Fusion 360 GRBL post processor works and ensure each new
   -- cut starts at the proper height
   commentText = "Cut " .. cutCount .. " X=" .. (scale*currentX) .. " Y=" .. (scale*currentY)
   OnComment()

   Reference();  -- Z-probe
   post.ModalText ("G00")
   post.Text(" Z")
   post.Number (pierceHeight * scale, "0.0000")
   commentText = "Z @ pierce height: " .. pierceHeight .. " mm " .. (pierceHeight * (1/25.4)) .. " inches"
   OnCommentSpace()
   post.Eol()
   post.Text ("M03\n")
   if (pierceDelay + firstPierce > 0.001) then
      post.Text ("G04 P")
      post.Number (pierceDelay + firstPierce,"0.0##")
      firstPierce = 0
      commentText = "Pierce Delay: " .. pierceDelay .. " seconds"
      OnCommentSpace()
      post.Eol()
   end
   -- Reset G0 after G38.2 to avoid Error 33 from GRBL
   post.Text("G00 X")
   post.Number(currentX * scale, "0.0000")
   post.Text(" Y")
   post.Number(currentY * scale, "0.0000")
   post.Text(" Z")
   post.Number(pierceHeight * scale, "0.0000")
   post.Text(" F")
   post.Number (plungeRate * scale, "0.0###")
   commentText = "Reset position after probe to prevent GRBL error 33"
   OnCommentSpace()
   post.Eol()
   --- ^^^
end

function OnNewOperation()
   commentText = "Operation: " .. operationName .. " OpIndex: " .. operationIndex
   OnComment()
end

function OnNewPart()
   commentText = "Part: " .. partName .. " partIndex: " .. partIndex
   OnComment()
end

function OnSetFeed()
   post.ModalNumber ("F", feedRate * scale, "0.0###")
   commentText = "Feedrate: " .. feedRate .. " mm/min " .. (feedRate * (1/25.4)) .. " inches/min"
   OnCommentSpace()
   post.Eol()
end

function Reference()
   firstRef = false

   post.ModalText("G38.2 Z")
   post.Number((-1 * maxZProbeDistance) * scale, "0.0##")
   post.ModalNumber (" F", plungeRate * scale, "0.0###")
   commentText = "Z-probe with Feedrate: " .. plungeRate .. " mm/min " .. (plungeRate * (1/25.4)) .. " inches/min"
   OnCommentSpace()   
   post.Eol()

   post.ModalText("G92 Z0.0")  -- Z0 is now where the Z-probe triggers (touches)
   commentText = "Z = Probe Touch/Trigger"
   OnCommentSpace()
   post.ModalText ("G00")
   post.Text(" Z")
   post.Number (switchOffset * scale, "0.0000")
   commentText = "switchOffset " .. switchOffset .. " mm " .. (switchOffset * scale) .. " inches"
   OnCommentSpace()
   post.Eol()
   post.ModalText("G92 Z0.0")  -- Z0 is now where the Z-probe has backed off to the point where the nozzle just touches
   commentText = "Z = nozzle touching metal (e.g. adjusted by switch Offset)"
   OnCommentSpace()
end

function OnPenUp()
   post.Text ("M05\n")
   if (endDelay > 0) then
      post.Text ("G04 P")
      post.Number (endDelay,"0.###")
      post.Eol()
   end
end

function OnToolChange()
    offX = 0
    offY = 0
    offZ = 0
end

function OnDrill()
   OnRapid()
   currentX = endX
   currentY = endY
   OnPenDown()
   endZ = drillZ
   OnMove()
   OnPenUp()
   endZ = safeZ
   OnRapid()
end


function OnComment()
  post.Text("(",commentText,")\n")
end

function OnCommentSpace()
  post.Text(" (",commentText,")\n")
end

If you are using a JD’s Garage machine that has their Z-axis with the microware-door switch for a z-probe, just change the switchOffset = 0.0 line in the above text (and import it as your post-processor). switchOffset will be the same measurement you would have used in Fusion 360 in the “PLASMA: Plasma touch probe offset” field of the post-processor.

@alsandoval your latest scpost above worked during a full simulation with the torch off, I set the (switch offset to 1.5mm) which keeps the plasma torch approx. 2mm from top of metal sheet, that seems to be the ideal height for my setup. I will experiment more with height.
Thank you very much for creating this scpost it is awesome to have people like you and @bLouChip that want to help with sheetcam.
I will also update my FB post in the JDs garage to show credit for creating this scpost.

1 Like

I feel relieved to read you as a a witness of JD’s garage ’ s design. and see I was not just the clumsy or impotent customer of their design. A lot of issues could indeeb be discussed with their design and components’ choices. Having the X axis tube made out of steel instead of aluminium, in spite of having support from only one end, it is just a joke. And as you mention they barely addresse EMI risks, and recommend a very basic arduino board, how do you shield against EMI with a simple USB wire ? (I spent much time as well with bluetooth, but never succeed, communication may vary from one seller to another, that is far from simple); As well, now I am very surprised and struck to see they have designed nothing on their Y bearings blocks, to enable a fine tune of XY perpandicularity ! No need to extend the complains-list, it would be possible though. I can ironically say thanks to them since I had to learn a lot on my way, but that was not the goal actually. 25$ is cheap, and should have first guessed the risks, but the aim is to have time saved, no start again from scratch so many parts of the design !

I am happy to see you as a new member and contributer of the forum, and will be curious to test your postprocessor if it fits my need, but I need 4 axis/tube cutting gcodes.

Thanks! I hope this is helpful. I also understand your frustration with JD’s Garage. I don’t want to be critical of them - they already really don’t like me (they will not let me purchase any of their other plans - because I made the mistake of trying to be helpful). Despite my negative experience with their personalities, In the long run they are doing the world a service, helping more people to take those initial steps in building something cool. There will always be people like you and me who can help those who struggle take next steps to success. :slight_smile:

Yes I also got banned from the FB group for having a custom table, it’s unfortunate they don’t take constructive criticism really well
Collectively we can make things better, especially because their JDG post processor never actually worked with sheetcam, error 33 bug as you detailed abovve. Fusion 360 is a steep learning curve and actually a lot more expensive it you respect the license agreement, free for personal use.
I do agree their plans at the price point is an excellent value for money, without them I wouldn’t have any CNC plasma cutter.

2 Likes

Here is my first project thanks to your post processor, its approx. 28in wide, I still need to play around with the torch height and air psi, and speed of the cut, in the area where there are many changes of directions more dross collected.

That looks great! I’m very happy this worked for you!

FWIW I am still working through issues with torch height, etc. too. (My ohmic sensor approach works, but I still have occasional issues with the offset and the speed of response from the THC.) I just wired-up the anti-dive for the DANI THC and tried that out. That feature only works with something like Sheetcam where you can put in rules related to travel distance, etc.

I also learned the hard way…from the JD’s Garage recommended Fusion post-processor how much acceleration can impact probing. At some point I may re-work the grblHAL/Blackbox firmware so that a Z-probe value isn’t measured from “touch-off” but from the last point where contact was present (e.g. where the switch or ohmic sensor still closed the circuit.) This is because there is always acceleration and residual momentum from the motor. If you set the probe speed too high, you will see that even after the switch closes or the ohmic sensor triggers, the nozzle still keeps moving down.

There was a bug in the Fusion post-processor where if you switched Fusion from millimeters to inches, it would spit-out a probe feedrate in millimeters/second while the machine was set to inches/second - causing the probe to trigger but then crash violently. (I submitted a fix for the post-processor but they original author told me he was working through other changes and had found and fixed that bug already.) In Sheetcam I set my probe feedrate to 8 inches/second and it mostly does okay, but I still have times when starting a cut the nozzle hits the metal and drags or pulls the torch off of the magnetic base.

ditto, I learned this the hard way too, broke a probe limit switch. You are on the right track understanding why, but its not momentum, its purely a function of deceleration config and probe speed. Change either and the grbl measured switch offset distance will change, strictly due to switch closure overrun distance. I have found that the overrun is quite predictable provided its measured at the same probe speed and axis deceleration ($122 for Z). The speed directly affects the distance traveled due to MCU latency when reacting to limit switch state change. The deceleration config directly affects the distance traveled due to time necessary to decelerate the motion as configured, so as not to lose STEPs. Than add that the probe command has a max distance of travel, if that programmed max distance is too short, grbl can already be in deceleration mode when the limit switch changes state, making the measured distance less reliable. The fix to that variable is to use a max probe distance much greater than what is necessary to change the limit switch state.

Thanks @bLouChip! I’ve thought about using the post-processor to add a 2nd a probe - the first one at one feedrate (e.g. my current 8 ipm), and then move up to the pierce height (2x cutting height) and do a second probe at something like 1/10 of the previous feedrate. IMO it is worth it to pay the price in terms of time taken on the probes rather than to have the torch head crash into the work piece – especially when cutting expensive 1/2" pieces of metal. :slight_smile:

In my case, I don’t have a real switch offset because I’m using an ohmic sensor - this FWIW is really easy with an inexpensive torch that has a CNC option because (so far as I’ve seen) the negative on the CNC voltage is connected to the nozzle, and the CNC4PC PTS-1 sensor is meant to measure (only during probing) between the nozzle and the cutting surface. Still though, I think everything you said still applies because if you probe too quickly, especially on thin metal, you just push that surface downward with the nozzle and it acts about the same as it would if you are too fast with a switch with an offset.

My $122 is set the same for all of my axis - I just don’t know enough to know where it actually should be…

[11:36:47] [ $$ ] $100=40.00000 ;X-axis steps per millimeter
[11:36:47] [ $$ ] $101=40.00000 ;Y-axis steps per millimeter
[11:36:47] [ $$ ] $102=320.00000 ;Z-axis steps per millimeter
[11:36:47] [ $$ ] $110=12500.000 ;X-axis maximum rate, mm/min
[11:36:47] [ $$ ] $111=12500.000 ;Y-axis maximum rate, mm/min
[11:36:47] [ $$ ] $112=2000.000 ;Z-axis maximum rate, mm/min
[11:36:47] [ $$ ] $120=700.000 ;X-axis acceleration, mm/sec^2
[11:36:47] [ $$ ] $121=700.000 ;Y-axis acceleration, mm/sec^2
[11:36:47] [ $$ ] $122=700.000 ;Z-axis acceleration, mm/sec^2
[11:36:47] [ $$ ] $130=1000.000 ;X-axis maximum travel, millimeters
[11:36:47] [ $$ ] $131=1000.000 ;Y-axis maximum travel, millimeters
[11:36:47] [ $$ ] $132=100.000 ;Z-axis maximum travel, millimeters

I am also not quite sure if the $102 is the best option for use with my THC, but it has the value that I calculated to be right based on the motor and leadscrew, etc. If I change it, I’ll have to try to figure out the math with a different setting on the driver – but it would probably get me better height responses from the THC which sometimes bounces up and down a bit.

Thanks for your feedback.

-Andrew

A couple thoughts-

  • just to clarify, $122 and most $nnn config settings are not intended to be changed often, certainly not during the operation of a cutting job. I run 400mm/sec^2, necessary to dampen the effects of mechanical resonance (shaking while stopping and changing direction of XYmotion, Y mainly) since my CNC has high center of gravity and heavy gantry. I just run Z at the same value.
  • re. double probe for accuracy- I use to do that, 1000mm/m to find switch, retract 5, second probe at 50mm/m. But this was before I discovered the consistency of the probe overrun after contact. Now I just have 1 probe at 1000mm/m, but I do a reverse probe immediately after. Reverse probe is motion opposite direction until the switch opens. In your case, done. I’m my case, I still adjust Z0 by the new switch offset value. See the links I referenced earlier, there is a short thread on this ‘reverse probe’ concenpt. This makes for a significantly more accurate probe to find surface since it factors out about 95% of sheet metal flex. And its faster than the afore mentioned two probe technique.
1 Like

Thanks! I slowed down the speed on my THC and I get much better cuts now, but I may still have some issues like the one you mentioned. I notice for example that bend relief lines always have a few mm of…ugliness, and circles, even larger circles have one sort of jagged spot.

Right now though I’m seeing issues where every now and then my Z motor hums but doesn’t move UP when retracting to the safety height. It works fine 95% of the time, but until I figure that out, I don’t want to run any big jobs for fear of a ruined piece of metal (which has gotten to be too expensive lately.)

Thank you for posting this. I just built their Plasma table and while there is lots to work on, i am using Freecad. and Sheetcam I now have me Sheetcam license and this post processor works well for most items so far except a Shapestring layer but im sure ill sort it out. Thanks again.

@alsandoval can you please help me understand the Z-probe gremlins you were describing related to EMI? I am using your .scpost and it generally works well but I have experienced 2 issues. Periodic miss of the Z-axis to drop and probe and the torch fires about 1” off the material and the second is a periodic “stall “ of a job.

Again. Thanks for supporting folks here. Your experience is very much appreciated.

M

Yes, I am also still fighting EMI issues. I had it working well when I use my homemade ohmic sensor (instead of the JD’s garage switch) on an IPT60 torch. Mine looks like this:

But I just upgraded to an X45 torch from PlasmaDyn, that “uses” Hypertherm consumables. (In reality it looks like it uses…some Hypertherm consumables, and the rest are close knock-offs but not quite the same.) I wanted this for the Ohmic cap that they provide, and for my first cut it worked just fine. For my second cut you can see that the cut came out fine, but there were a couple of times that the probe didn’t work quite right and the torch started too high. Either the THC adjusted for it and fixed it, or the new torch is that much better, because the cut worked fine… Even though I complained about it running jagged, once I took the slag off it looked smooth. Here is the video - it long (probably very boring, and I am slow of speech as I think through what I’m seeing.)
(As I new user I can’t put a link to the video… So try putting a slash where the space is on this: youtu.be osma7rrIm9s)

So I ran a dry run with, and this time you can hear the probe getting an early signal and then an error because things aren’t where they were expected to be. Here is a shorter video of the dry run:
youtu.be TBIfohpCa4s

Both videos are with the same file I generated from Sheetcam, both using my latest version of the post processor that probes twice, the 2nd time at half speed. I’ll share it below even though it may not be right yet, or necessary. But the g-code looks fine to me, and when I run it with my IPT60 torch with the homemade ohmic sensor it works just fine, whether a dry run or actually cutting.

I can’t rule out the possibility that this CNC4PC PTS-1 touch sensor just doesn’t work right, but because it works almost always with the home-made ohmic sensor I don’t think it is the problem. I had the same problem with the JD’s Garage standard z-axis with the microwave door switch. And I had the same problem with the home-made ohmic sensor until I wrapped every single wire with copper tape, added a mylar capacitor between ground and the Z-probe pin on the ESP32, and added ferrite cores to many of the lines.

Another problem I’ve had with this machine is that every now and then the Z-axis motor will hum but not move up or down. I put a ferrite core (I have a package of them from Amazon) around the Z-motor wires leaving the Z driver, and that seems to have solved that problem, but may have made the Z-probe triggering worse.

The truth is…I’ve sunk so much time and money into this machine that I almost regret every building it. I could have purchased a Crossfire from Langmuir for what I’ve sunk into this, and the JD’s Garage guys have made it clear that they hate me (they’ve blocked me from making purchases and from their FB group) because I asked too many questions, and made suggestions and changes to my machine that “they could not support”, all in an effort to get this thing working. When I found something that worked I told them, but they were not happy about it, and their answers were always so terse and unhelpful that I gave up on them.

So, I’m not throwing in the towel yet - I can’t afford to after all of this, but if I don’t find a good solution to the EMI problems soon, I’ll be replacing ALL of the electronics except maybe the motors. Maybe I’ll try the Proma electronics when I can afford it.

I will say that the X45 torch seems to do a much better job than the IPT60 torches do, but I’ve tried exactly 2 cuts so far.

Here is the Post that has some fixes and does the 2-probes. You can disable the 2nd probe by setting the secondProbeMultiplier variable to 0.
grblHALPlasmaZProbe2.scpost

--************************************************
--*** Set these values up to suit your machine ***
--************************************************

--Put your switch offset value here in MILLIMETRES
--For Switch-based probes:
-- Put a sheet of metal on your machine and place a sheet of paper on top.
-- Slowly jog the torch down onto the paper until the touch-off switch just operates.
-- Zero the Z axis then pull gently on the paper and slowly jog up until the paper slides out.
-- The Z axis position is your switch offset.
--For Ohmic Probes:
-- Set to 0.0.  If you need to back-off from the point of probe contact put the distance in MILLIMETERS here
switchOffset = 0.0

--this is an extra delay added to the first pierce as needed by some machines
firstPierceTime = 0 

--Maximum Z-probe distance in MILLIMETERS
maxZProbeDistance = 100

-- Second Probe Multiplier, set to zero to NOT double-probe after each rapid movement
-- otherwise perform the first probe at the specified plungeRate, and
-- then raize Z back to the pierceHeight x2 and probe again at the plungeRate * secondProbeMultiplier
-- so that you can get a more accurate reading (if moving slower) on the 2nd probe before adjusting
-- the Z reference value (G92 Z0).  In my case I'm using 8 inches per minute as my plungeRate
-- so using 0.50 as my secondProbeMultiplier means that the 2nd G38.2 probe will run at 4 ipm
-- This is utilized in the Reference function.
secondProbeMultiplier = 0.50

-- If set to true, probing is disabled
doNotProbe = false

--************************************************
--***           End of settings                ***
--************************************************

--************************************************
--***          GLOBAL VARIABLES                ***
--************************************************
--Cut Counter, just to keep track
cutCount = 0

--Last cutCount where Cut Height Comment was shown
cutCountHeightComment = 0

--Is this the first time we've referenced Z (via probe)?
firstRef = true


function OnAbout(event)
   ctrl = event:GetTextCtrl()
   ctrl:AppendText("grblHAL Plasma Cutter with Z probe\n")
   ctrl:AppendText("Written by Andrew L. Sandoval - based on GRBL THC with scriber.scpost\n")
   ctrl:AppendText("\n")
   ctrl:AppendText("Modal G-codes and coordinates\n")
   ctrl:AppendText("Comments enclosed with ( and )\n")
   ctrl:AppendText("M03/M05 turn the torch on/off\n")
   ctrl:AppendText("The torch is referenced with a Z-probe before each pierce\n")
   ctrl:AppendText("Designed for use with grblHal and a z-probe\n")
   ctrl:AppendText("Post variables:\n")
   ctrl:AppendText("switchOffset - set your net switch offset amount\n")
   ctrl:AppendText("maxZProbeDistance - set the maximum Z-probe distance\n")
   ctrl:AppendText("secondProbeMultiplier - set a multiplier to other than 0 to perform a 2nd probe at the specified multipier of the plungeRate, e.g. 0.10 would be 1/10th plungeRate\n")
end


--   Modified 10/14/24 by Andrew L. Sandoval
--   Based on TRBL THC with scribe

post.DefineVariable("switchOffset",sc.unitLINEAR,-1e17,1e17)
post.DefineVariable("maxZProbeDistance",sc.unitLINEAR,0,1e17)

function OnInit()

   offX = 0
   offY = 0
   offZ = 0

   post.SetCommentChars ("()", "[]")  --make sure ( and ) characters do not appear in system text
   commentText = "Post: " .. postName .. " Andrew L. Sandoval"
   OnComment()

   commentText = fileNameOnly .. " " .. " " .. date .. " " .. time
   OnComment()

   if(scale == metric) then
      commentText = "Metric Mode"
      OnComment()
      post.Text ("G21\n") --metric mode
   else
      commentText = "Inch Mode"
      OnComment()
      post.Text ("G20\n") --inch mode
   end
   post.Text ("G53 G90 G40\n")
   minArcSize = 0.2 --arcs smaller than this are converted to moves
   currentZAxis = "Z"

   dist = 9999999
   lastz = 0
   thcstate = 1
   firstPierce = firstPierceTime;

   if(var.JetOperation0_FeedRate) then
   commentText = "Feedrate: " .. var.JetOperation0_FeedRate .. " mm/min " .. (var.JetOperation0_FeedRate * (1/25.4)) .. " inches/min"
   OnComment()
   end

   if(var.JetOperation0_PlungeRate) then
   commentText = "Plunge rate: " .. var.JetOperation0_PlungeRate .. " mm/min " .. (var.JetOperation0_PlungeRate * (1/25.4)) .. " inches/min"
   OnComment()
   end

   commentText = "Plunge Saftey: " .. plungeSafety .. " mm " .. (plungeSafety * (1/25.4)) .. " inches"
   OnComment()

   commentText = "Safe Z: " .. safeZ .. " mm " .. (safeZ * (1/25.4)) .. " inches"
   OnComment()

   firstRef = false
end

function OnNewLine()
   post.Text ("N")
   post.Number (lineNumber, "0000")
   post.Text(" ")
   lineNumber = lineNumber + 10
end


function OnFinish()
   endZ = safeZ
   OnRapid()
   endX = 0
   endY = 0
   offX = 0
   offY = 0
   offZ = 0
   OnRapid()
   post.Text ("M05\n")  -- Torch Off
   post.ModalText ("G00 X0 Y0")  -- Go Home, with Z at safe height
   if(currentZ ~= safeZ) then
      post.ModalNumber (" " .. currentZAxis, safeZ * scale, "0.0000")
      post.Eol()
   end
   post.Text("M30\n")  -- Reset
   cutCount = 0
end

function OnRapid()
   -- Always make sure Z is safe before any rapid movement, except for the initial one
   -- where it is assumed the machine was set at a safe Z height to begin with
   if(firstRef == false and currentZ ~= safeZ) then
       post.Text("G00 Z")
       post.Number(safeZ * scale, "0.000")
       post.Eol()
   end
   if(endX > 1e17 and endY > 1e17) then return end
   local len = math.hypot((endX + offX)-currentX , (endY + offY)-currentY)
   dist = dist + len
   post.ModalText ("G00 ")
   post.ModalNumber ("X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ and firstRef == false and currentZ ~= safeZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.Eol()
end

function OnMove()
   post.CancelModaltext()
   post.CancelModalNumbers()
   local len = math.hypot(endX - currentX , endY - currentY)
   dist = dist + len
   post.ModalText ("G01")
   post.ModalNumber (" X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.ModalNumber (" F", feedRate * scale, "0.0###")
   if(cutCountHeightComment < cutCount) then
      commentText = "Cut Height: " .. cutHeight .. " mm " .. (cutHeight * (1/25.4)) .. " inches"
      OnCommentSpace()
      cutCountHeightComment = cutCount
   end
   post.Eol()
end

function OnArc()
   post.CancelModaltext()
   post.CancelModalNumbers()
   local radius = math.hypot(currentX - arcCentreX, currentY - arcCentreY)
   dist = dist + radius * math.abs(arcAngle)

   if(arcAngle <0) then
      post.ModalText ("G03")
   else
      post.ModalText ("G02")
   end
   post.ModalNumber (" X", (endX + offX) * scale, "0.0000")
   post.ModalNumber (" Y", (endY + offY) * scale, "0.0000")
   if(offZ) then
      post.ModalNumber (" " .. currentZAxis, (endZ + offZ) * scale, "0.0000")
   end
   post.Text (" I")
   post.Number ((arcCentreX - currentX) * scale, "0.0000")
   post.Text (" J")
   post.Number ((arcCentreY - currentY) * scale, "0.0000")
   post.ModalNumber (" F", feedRate * scale, "0.0###")
   post.Eol()
end

function OnPenDown()
   cutCount = cutCount + 1
   -- Always Reference() before starting a cut, regardless of dist
   -- this matches how the Fusion 360 GRBL post processor works and ensure each new
   -- cut starts at the proper height
   commentText = "Cut " .. cutCount .. " X=" .. (scale*currentX) .. " Y=" .. (scale*currentY)
   OnComment()

   Reference();  -- Z-probe
   post.Text("G00 Z")
   post.Number (pierceHeight * scale, "0.0000")
   post.Text(" F")
   post.Number(plungeRate * scale, "0.0###")
   commentText = "Z @ pierce height: " .. pierceHeight .. " mm " .. (pierceHeight * (1/25.4)) .. " inches"
   OnCommentSpace()
   post.Eol()
   post.Text ("M03\n")
   if (pierceDelay + firstPierce > 0.001) then
      post.Text ("G04 P")
      post.Number (pierceDelay + firstPierce,"0.0##")
      firstPierce = 0
      commentText = "Pierce Delay: " .. pierceDelay .. " seconds"
      OnCommentSpace()
      post.Eol()
   end
   -- Reset G0 after G38.2 to avoid Error 33 from GRBL
   post.Text("G00 X")
   post.Number(currentX * scale, "0.0000")
   post.Text(" Y")
   post.Number(currentY * scale, "0.0000")
   post.Text(" Z")
   post.Number(pierceHeight * scale, "0.0000")
   post.Text(" F")
   post.Number (plungeRate * scale, "0.0###")
   commentText = "Reset position after probe to prevent GRBL error 33"
   OnCommentSpace()
   post.Eol()
   --- ^^^
end

function OnNewOperation()
   commentText = "Operation: " .. operationName .. " OpIndex: " .. operationIndex
   OnComment()
end

function OnNewPart()
   commentText = "Part: " .. partName .. " partIndex: " .. partIndex
   OnComment()
end

function OnSetFeed()
   post.ModalNumber ("F", feedRate * scale, "0.0###")
   commentText = "Feedrate: " .. feedRate .. " mm/min " .. (feedRate * (1/25.4)) .. " inches/min"
   OnCommentSpace()
   post.Eol()
end

function SwitchOffsetAdjust()
   if(switchOffset ~= 0) then
      post.Text("G00 Z")
      post.Number (switchOffset * scale, "0.0000")
      commentText = "switchOffset " .. switchOffset .. " mm " .. (switchOffset * scale) .. " inches"
      OnCommentSpace()
      post.Eol()
      commentText = "Appling switchOffset difference to Z"
      OnCommentSpace()
      post.Text("G92 Z0.0")  -- Z0 is now adjusted by switchOffset
   end
end

function Reference()
   firstRef = false
   if(doNotProbe == true) then
      do return end
   end

   post.Text("G38.2 Z")
   post.Number((-1 * maxZProbeDistance) * scale, "0.0##")
   post.Text(" F")
   post.Number(plungeRate * scale, "0.0###")
   commentText = "Z-probe with Feedrate: " .. plungeRate .. " mm/min " .. (plungeRate * (1/25.4)) .. " inches/min"
   OnCommentSpace()   
   post.Eol()

   post.Text("G92 Z0.0")  -- Z0 is now where the Z-probe triggers (touches)
   commentText = "Z = Probe Touch/Trigger"
   OnCommentSpace()

   if(secondProbeMultiplier > 0.0) then
       -- Run a second probe at the (plungeRate * secondProbeMultiplier) to get a more accurate reference
       -- Starting a the 2x pierceHeight, which will also be a slow asent to ensure the feedrate is reduced
       post.Text("G00 Z")
       post.Number((pierceHeight * 2) * scale, "0.0000")
       post.Text(" F")
       post.Number((plungeRate * secondProbeMultiplier) * scale, "0.0000")

       commentText = "Running 2nd Probe from 2x pierceHeight at " .. (plungeRate * secondProbeMultiplier) .. " mm/s " .. ((plungeRate * secondProbeMultiplier) * 1/25.4) .. " inches/s"
       OnCommentSpace()
       -- Second probe
       post.Text("G38.2 Z")
       post.Number((-1 * maxZProbeDistance) * scale, "0.0##")
       post.Text(" F");
       post.Number((plungeRate * secondProbeMultiplier) * scale, "0.0000")
       post.Eol()

       post.Text("G92 Z0.0")  -- Z0 is now where the Z-probe has backed off to the point where the nozzle just touches
       commentText = "Z = nozzle touching metal (e.g. adjusted by switch Offset)"
       OnCommentSpace()
    end
    SwitchOffsetAdjust()
end

function OnPenUp()
   post.Text ("M05\n")
   if (endDelay > 0) then
      post.Text ("G04 P")
      post.Number (endDelay,"0.###")
      post.Eol()
   end
end

function OnToolChange()
    offX = 0
    offY = 0
    offZ = 0
end

function OnDrill()
   OnRapid()
   currentX = endX
   currentY = endY
   OnPenDown()
   endZ = drillZ
   OnMove()
   OnPenUp()
   endZ = safeZ
   OnRapid()
end


function OnComment()
  post.Text("(",commentText,")\n")
end

function OnCommentSpace()
  post.Text(" (",commentText,")\n")
end

Your trust level has been boosted to allow posting files and links.

1 Like

@alsandoval sorry to hear about your EMI issues. As a DIY’r myself, I understand the frustrations, I think we all go through that as some point to some degree. You may be just a few dollars away from solution though. I recommend taking a step back for a few days, reading some EMI mitigation material (links in the reference below), and assessing the corrections necessary.

Here are my recommendations from a few years ago while building my plasma table.

There may also be controller board issues as it concerns signal processing and controller box shielding. Since writing those recommendations, I discovered an excellent design and construction of a BOB/controller for grblHAL, it is designed to help mitigate EMI if implemented correctly.

I recall it being $45 and perhaps another $45 for the Teensy4.1 MPU. If you are using the DANI THC 9SUD then it works directly with this BOB and grblHAL where grbl manages the Z motion UP/DN during THC operation, which is better than the alternative DANI THC 7DP which operates Z autonomous to the controller (not an EMI issue per se, its a quality of operation issue).

I hope this helps.

1 Like