Issue with Before / After M6 Tool selection

I am running a home-built automatic tool changer (ATC) using the Before M6 and After M6 code shown below. Using a Shapeoko 5

The bug is that the machine sometimes picks up the same tool that it just dropped off instead of picking up the tool requested by the M6 command.

For example, assume the machine currently has T1 loaded and receives:

T2 M6

The expected sequence is:

  1. Drop off T1.

  2. Move to the T2 pocket.

  3. Pick up T2.

  4. Continue machining with T2.

When the bug occurs, the machine instead:

  1. Drops off T1.

  2. Returns to the T1 pocket.

  3. Picks T1 back up.

This appears to be related to larger G-code files and some kind of command buffering or synchronization issue.

The problem does not consistently occur. On smaller or simpler G-code files, the tool change works correctly. It also appears to work correctly if there is a pause or other delay in the G-code before the M6, which gives the controller time to โ€œcatch up.โ€

My suspicion is that the controller is still processing buffered G-code when the M6 sequence begins. The M6 code appears to execute before the tool-selection information has fully caught up with the current G-code position.

For example, the G-code may have reached:

T2 M6

but the tool information being read by the ATC macro is still effectively reporting T1 because the controllerโ€™s G-code buffer or parser is behind.

This results in:

T1 โ†’ T1

instead of:

T1 โ†’ T2

The issue occurs with both forms of the tool-change command:

T1 M6

and

M6 T1

The important observation is that the problem is strongly correlated with G-code file size and execution speed. Adding a pause before the M6 can prevent the problem, suggesting that the issue is related to buffered G-code, command execution order, or when the ATC macro reads the active tool value.

; ATC BEFORE M6

%RACK_X = -1232.29
%RACK_Z = -69.92
%SAFE_Z = -5
%RACK_APPROACH_OFFSET = 30    ; distance to the right of RACK_X to approach from โ€” adjust sign/value for your machine

%T1_Y = -443.05
%T2_Y = -503.31
%T3_Y = -564.42
%T4_Y = -623.80
%T5_Y = -684.99
%T6_Y = -743.84

%currentLoadedTool = Number(global.currentLoadedTool || 0)

(msg, BEFORE TOOL IS [currentLoadedTool])

%rackApproachX = RACK_X + RACK_APPROACH_OFFSET
%rackY = currentLoadedTool == 1 ? T1_Y : (currentLoadedTool == 2 ? T2_Y : (currentLoadedTool == 3 ? T3_Y : (currentLoadedTool == 4 ? T4_Y : (currentLoadedTool == 5 ? T5_Y : T6_Y))))

[currentLoadedTool > 0 ? 'M5' : '']
[currentLoadedTool > 0 ? 'G4 P0.5' : '']
[currentLoadedTool > 0 ? 'G53 G0 Z' + SAFE_Z : '']

[currentLoadedTool > 0 ? 'G53 G0 X' + rackApproachX + ' Y' + rackY : '']
[currentLoadedTool > 0 ? 'G53 G0 X' + RACK_X : '']

[currentLoadedTool > 0 ? 'G53 G0 Z' + RACK_Z : '']
[currentLoadedTool > 0 ? 'G4 P0.5' : '']
[currentLoadedTool > 0 ? 'G53 G0 Z' + SAFE_Z : '']


; ATC AFTER M6

%RACK_X = -1232.29
%RACK_Z = -69.92
%SAFE_Z = -5
%RACK_APPROACH_OFFSET = 30

%PROBE_X = -0.5
%PROBE_Y = -1200
%PROBE_Z = -1.5
%PROBE_DISTANCE = 150
%PROBE_FAST = 500
%PROBE_SLOW = 50

%T1_Y = -443.05
%T2_Y = -503.31
%T3_Y = -564.42
%T4_Y = -623.80
%T5_Y = -684.99
%T6_Y = -743.84

(msg, AFTER TOOL IS [tool])

G21
G90

%global.atc = global.atc || {}

G53 G0 Z[SAFE_Z]

%rackApproachX = RACK_X + RACK_APPROACH_OFFSET
%rackY = tool == 1 ? T1_Y : (tool == 2 ? T2_Y : (tool == 3 ? T3_Y : (tool == 4 ? T4_Y : (tool == 5 ? T5_Y : T6_Y))))

G53 G0 X[rackApproachX] Y[rackY]
G53 G0 X[RACK_X]

G53 G0 Z[RACK_Z]

G4 P3

G53 G0 Z[SAFE_Z]

G53 G0 X[PROBE_X] Y[PROBE_Y]
G53 G0 Z[PROBE_Z]

G4 P0.1

; ---- probe, relative moves throughout: immune to WCS state ----
G91
G38.2 Z-[PROBE_DISTANCE] F[PROBE_FAST]
G0 Z2
G38.2 Z-5 F[PROBE_SLOW]
G4 P0.1
G90

%measuredZ = mposz

; ---- compute delta vs previous tool, apply to G54 directly (survives reset) ----
%hasReference = global.atc.referenceZ != null
%zDelta = hasReference ? (measuredZ - global.atc.referenceZ) : 0

(msg, TOOL Z DELTA [zDelta])

%global.atc.referenceZ = measuredZ

G10 L20 P1 Z[posz - zDelta]

G4 P0.1

%global.currentLoadedTool = Number([tool])

(msg, CURRENT LOADED TOOL IS [global.currentLoadedTool])

G53 G0 Z[SAFE_Z]

G54
G17
G21
G90

This text will be hidd

1 Like