Probing in Mach4


What is probing?

When you want to detect the surface of your workpiece or another object, you will advance a dedicated probe, or your bit or torch head with a wire attached to it towards the material so that it activate a circuit which will activate an input pin. Basically when the probe touches something, it will activate an input pin, which will stop motion and the current position will be reported back to Mach4.

Probing can be done with an expensive and very precise probe with its own electronics that will output a voltage when it makes contact.  

Probing can also be done with something a resistor and a wire making an ohmic probe for your tool to sense contact with a probing plate.


Basic Probing Command

G31 Z 1.0 F10 is a simple probing command.

  • The G31 (which is the same as G31.0) will tell Mach4 to tell the SmoothStepper to probe with input Probe #0.

  • The Z 1.0 tells the Z axis to move towards 1.0 units from the current position.

  • The F10 tells the Z axis to move at a speed of 10 units per minute.


Advanced Probing Commands

The ESS supports up to 4 probes, so you can use the following commands to specify which probe you want to use.  Please remember that each probe needs to be assigned to an input pin and enabled in the ESS's Config -> Input Signals tab.

  • Probe 0:  G31.0 or G31

  • Probe 1:  G31.1

  • Probe 2:  G31.2

  • Probe 3:  G31.3

You may also specify more that one axis to move during a probing command:  G31.0 X3 Y4 Z6 F10

With that command all three axes will move simultaneously with coordinated motion.


How can I test probing repeatedly?

This code will repeatedly test probing on your system.   If you log it while you are doing this, you can see everything that the ESS is doing .

If you only want to run this once per cycle start, then replace the M47 with a M30 command. Save these three lines of GCode as a .nc or .tap file and then run them as GCode and not MDI.

G0 Z 1 (Or whatever Z height you want to start at)

G31 F10 Z0 (adjust feed and final position for your system)

M47 (Repeat Program from the first line)


If you can get this to run repeatedly without failing, then the ESS and your hardware are probing correctly!


What will Mach4 do if the Probe signal is already active when a probing routine is commanded?

If the Probe signal is active when a G31 probing routine is commanded, Mach4 will determine that the probe was a success and continue onto the next line of GCode. Mach4 will NOT notify the SmoothStepper whatsoever, and only post this message in the log file.

How Probing Works

When Mach4 sees a probing command, it will make sure that all motion is stopped before executing the new probing command. Mach4 will accelerate the specified axes up to the commanded feed rate *, and produce planned motion that the SmoothStepper will follow.

* In the case of multiple axes, at least one of the axes will accelerate up to the commanded feed rate, but other axes may move much more slowly if they have a shorter distance to traverse.


The SmoothStepper will follow that planned motion until one of three things happens:

  • The user presses stop, at which point motion will stop instantly. This is an aborted probing cycle.

  • The specified probe pin makes contact, and then the SmoothStepper will decelerate to a stop. The SmoothStepper will then report the position of all motors to complete the successful probing cycle. Please not that the reported position is where the axes decelerated to and stopped at, not where the probe first made contact.

  • The commanded position is reached at which point motion will stop, but Mach4 will command a deceleration to a gentle stop at that final position. This is a failed probing cycle, since the probe never made contact with the material.


  • In the case of an aborted probing cycle, the machine is stopped, because the user pressed stop.  

  • In the case of a successful probing cycle, Mach4 will continue running, and executing the subsequent commands.

  • In the case of a failed probing cycle, the SmoothStepper will by default stop Mach4.


Why does the SmoothStepper stop Mach4 when a probing cycle fails? The simplest answer is because we always have, and we are not going to change that now since that is what the current users expect to happen. However, the technical reason for why is because of these possibilities:

  • We never reached the material, so any subsequent operations would occur too far away.

  • The tool that you are using broke, so it is shorted than expected, and you need to replace the tool,

  • Something went wrong with your circuitry, and your probe just plowed down into your material.

The SmoothStepper can't tell why the probing operation failed, only that it did. When running GCode, the only logical conclusion is to stop the GCode from running.


Common Probing Log Files

If there is noise on the probe signal (like a wire is floating electrically) and the signal is bouncing high to low repeatedly, you would expect to see something like this:


Something is Going Wrong With Probing

If something is going wrong with your probing operations, go to the MDI window, and type G31 Z 0 F10 and adjust any of those values to make it work for your setup at your current position.

Go to the Mach4 menu -> Diagnostic -> Logging... Press the play button in the upper left hand corner of the logging window.

Press the Cycle Start button, and then watch to see what happens.

  • Does the SmoothStepper report that the probing operation completed successfully when the probe contacted the material?  If so, then probing is working successfully with your hardware, the SmoothStepper and Mach4 .

  • If the probe never made contact, then you need to modify your probing command and try again.

  • If the probe smashed into your material and didn't stop, you need to see if the commanded probe signal activated in the log file. If the commanded probe signal did not activate:

    • Did you command the correct probe number?

    • Did you enable the probe in the SmoothStepper's Input Signals configuration tab?

    • If the probes active signal is ON when the probe is not touching and OFF when the probe is active, then the Active High / Low setting needs to be changed for the probe's input pin on the SmoothSteppers's Config window -> Pin tab.

    • Will the probe activate manually if you bring the touch plate up to it? If not then there is something wrong with your wiring.


Mach4's built in probing wizard (or utility or button) isn't working right!

Mach4 set up their wizard or probing utility to do large moves with G31 commands, just in case you hit something. However these moves will FAIL if you don't touch something and the ESS will then Stop Mach. Why does the ESS stop Mach if a probing command fails? Because if you are running GCode, you WANT the ESS to stop Mach if a probing command fails.

The following sections will show you how to change the ESS's behavior just before you run the Mach4 probing utility, and then change it back afterwords. This gives you the best of both worlds.

Why don't I modify the Mach4 probing utility?  Because there are multiples of them based off of the screen set you are using, and I don't know what you are trying to do. Besides, it is Mach's code not the SmoothSteppers.

Why don't I change how the ESS operates? If I did, I would be changing the operating behavior for tens of thousands of other customers, and they would be very surprised by this change in probing behavior.  Besides, if probing fails in GCode, Mach4 and the GCode should stop.


I'm Doing Some Advanced Probing Techniques

The Problem

Sometimes people want to move their tool in a fail safe manner so it won't crash and break, by replacing G00 or G01 with a G31 Probing Cycle Command. If the tool, which also needs to be the probe in this case, touches the material, then motion should stop, but if not touch the material then it will reach the commanded end point, and the SmoothStepper will report that the probe did not make contact and disable Mach4.

Let's talk about this scenario for a moment:

  1. The probe never touched, so the SmoothStepper stopped Mach, since that is the safest thing to do when a probing cycle fails.

  2. This would typically not be occurring in GCode, this would be in an advanced probing routine or in a lua script.

If you are using a probing cycle to move to a new position WITHOUT making contact, you are by definition doing the opposite of what a normal probing cycle would do, which is why you are experiencing this problem.


The Probing Config Tab

The SmoothStepper has a feature to allow you work around this when you are doing something that requires it (like surface mapping with a lua routine), by unchecking the box Probe Failure Disables Mach. Please note that YOU SHOULD NOT UNCHECK THIS WHILE RUNNING GCODE! If you do, bad crashes or miscut material may be the result.

If you should not have this unchecked when running GCode, this means that your special probing scripts and routines can call the m2010 (PROBE_FAILURE_DISABLES_MACH=0) to disable that feature while doing your advanced probing, and then before resuming your GCode call m2010 (PROBE_FAILURE_DISABLES_MACH=1) so a probe failure then will disable Mach4.


SmoothStepper Probing Registers

At this point, we are talking about lua scripts, and it sure seems like it would be helpful to know the state of each probing command while it is happening and after it completes. The SmoothStepper registry already provides you with all of that information.


  • ESS/Probing_Failure_Disables_Mach tells you the state of this feature. You may modify it by the m2010 command listed previously, via lua script or by the Probing tab config window.

  • ESS/Probing_State This gives a quick overview of the SmoothStepper's probing state. This register will be dynamically over written, and you should not test against or try to overwrite this value.

    • If the probing completes successfully, then the commanded probe and Probing_State will be set to 3 (PROBE_STATE_FINALIZED)

    • If the commanded probe never completes, then the commanded probe and Probing_State will be set to -1 (PROBE_STATE_FAILED)

    • If probing is aborted, the individual probes will be left as is and Probing_State will be set to -2 (PROBE_STATE_ABORTED)

  • ESS/Probe_Failure_Occurred This register will tell you when a probing error occurred.

    • A 0 means that a probing failure has not occured.

    • A -1 or -2 means that the probing failed. After your lua script has read a -1 (PROBE_STATE_FAILED) or -2 (PROBE_STATE_ABORTED), you need to set this register to 0 so you know that particular error instance has been cleared. You can then continue with your probing script however you want to continue considering that the probing cycle failed.

  • ESS/Probe_0 Tells you what happened to this specific probe. A read only register.

  • ESS/Probe_1 Tells you what happened to this specific probe. A read only register.

  • ESS/Probe_2 Tells you what happened to this specific probe. A read only register.

  • ESS/Probe_3 Tells you what happened to this specific probe. A read only register.


How do I use these registers in lua?

If you want to reenable Mach4 via lua code: 

mc.mcCntlEnable(MINSTANCE mInst, int state) -- to enable set state to 1 or true to disable set state to 0 or false


If you want to read the ESS/Probe_Failure_Occurred register:

hregProbeFailureOccurred = mc.mcRegGetHandle(inst, string.format("ESS/Probe_Failure_Occurred"))

iProbeFailureOccurredStateValue, iReturnCode = mc.mcRegGetValue(hregProbFailureOccurred ) --This will read the value

And to set it back to 0 so your code knows you handled the failure:

mc.mcRegSetValue(hregProbFailureOccurred, 0 ) --This will clear the failure


What COULD a script look like for you?

local inst = mc.mcGetInstance()

local ProbeString = "G91 G31 X3"

local ProbeString2 = "G91 G31 X-3"

local hregProbeFailureOccurred = mc.mcRegGetHandle(inst, string.format("ESS/Probe_Failure_Occurred"))


--Example Probing Command

-- local rcgc = mc.mcCntlGcodeExecuteWait(inst, ProbeString) -- THIS MIGHT RETURN -18 depending on previous actions



-- Given that the ESS Plugin is configured to "Disable Mach On Probe Fail" on the probe Tab,

--A failed Probing Cycle result in a lock which causes subsequent ExecuteWait calls to return -18 MERROR_NOT_NOW

--This can be disabled using the next two lines:


hregProbingFailureDisablesMach = mc.mcRegGetHandle(inst, string.format("ESS/Probing_Failure_Disables_Mach"))

mc.mcRegSetValue(hregProbingFailureDisablesMach , 0 ) -- Setting to 0 means that Mach will NOT be disabled if the probe fails to make contact

--With the feature disabled we should be able to probe multiple times with no locking if probe fails to strike:




rc = mc.mcCntlGcodeExecuteWait(inst, ProbeString)


--To determine if a strike occurred:

local iProbeFailureOccurredStateValue, iReturnCode = mc.mcRegGetValue(hregProbeFailureOccurred )

-- 0 means a strike happened, -1 and -2 mean no strikes occurred

-- Handle your probing failure as appropriate for your situation...



--Now clear out the failure report...

--local iReturnCode = mc.mcRegSetValue(hregProbeFailureOccurred , 0) --We are setting it to 0 to clear it out since we just 'handled' the failure




--Sample code to see if Mach is throwing a MERROR_NOT_NOW because it was stopped or disabled by the SmoothStepper because of a probing failure

rc = mc.mcCntlGcodeExecuteWait(inst, ProbeString2)

if (rc == -18) then

--the error occurred

mc.mcCntlSetLastError(inst, ">>>>> Lua Probing Script: Mach MERROR_NOT_NOW occurred")


--the error did not occur

mc.mcCntlSetLastError(inst, ">>>>> Lua Probing Script: No error occurred")




mc.mcRegSetValue(hregProbingFailureDisablesMach , 1 ) -- Setting to 1 means that Mach WILL be disabled if the probe fails to make contact, which we want for the GCode we are presumably returning to.






Top of Page