Problem Details
A rotary axis (typical 4th/5th axis, A/B/C) was commanded to index between angular positions and took the long way around instead of the shortest angular route. The operator attempted to force shortest-path behaviour by inserting M126 into the program. The M-code had no useful effect on the observed motion. The behaviour was ultimately corrected with M94, which was the M-code that actually addressed the underlying condition on that control.
This is a classic symptom pattern on rotary axes:
- Axis position display accumulates past 360 degrees (e.g. 720.000, 1080.000) after repeated indexing in one direction.
- A subsequent absolute command such as
G90 C90.produces a very long move (several full revolutions) instead of a short index. - Cable-carrier, rotary union or coolant line wrap-up warnings appear after a production run.
- Cycle time grows over the run as accumulated angle increases.
Root Cause
The failure was a mis-selected M-code, not a servo, backlash or parameter fault. The engineering root cause has two layers:
- Accumulated absolute rotary coordinate. The rotary axis was configured (or left in a state) where the absolute coordinate keeps counting past one revolution. In that condition an absolute positioning command is interpreted as a linear-style move in degrees, so the control legitimately drives through every intermediate degree between the current large value and the target. That is not an error — the control is executing exactly what was asked.
-
Wrong M-code family applied.
M126was assumed to be the shortest-path enable. On the control in question it did not produce the expected behaviour.M94did. M-code numbering above the mandatory range is not standardised across controls or across OEM machine builders; the same number can be an unassigned code, an OEM auxiliary function, or a completely unrelated macro call.
Why M-code assumptions fail
| Assumption | Reality on a real machine |
|---|---|
| M-codes above M30 are standard across brands | Only a small core set (M00, M01, M02, M03, M04, M05, M06, M08, M09, M30) is broadly consistent. Higher numbers are control- and builder-specific. |
| A code found in a forum post or another machine's program applies here | The same number may be unassigned, remapped by the machine builder, or routed to a custom macro (M-code to macro call parameters). |
| An unassigned M-code will alarm out | It may be passed to the PMC/PLC and silently ignored if no ladder logic decodes it — giving the appearance that "the code did nothing". |
| Shortest path is purely an M-code function | It usually depends on rollover being enabled by machine parameter first; the M-code only selects behaviour within that mode. |
Solution
Step 1 — Identify the correct code from the machine's own documentation
- Open the machine builder's programming manual, not a generic control manual. The builder's M-code list overrides the control vendor's default list where they conflict.
- Locate the rotary/index axis section and note the exact codes for: rollover / coordinate reduction, shortest-path selection, direction-forced positioning (CW only / CCW only), and their cancel codes.
- Cross-check against the actual machine: on the control, review the assigned M-codes screen or the PMC ladder M-code decode block if the manual is unavailable or outdated.
Step 2 — Verify the rotary axis parameter configuration
Before blaming the program, confirm the axis is set up as a rotary axis with rollover, not as a linear axis with degrees as the unit. Check with the machine builder or control documentation:
| Item to verify | Expected condition for shortest-path indexing |
|---|---|
| Axis type | Set as rotary axis, not linear |
| Rollover / cyclic function | Enabled |
| Movement per revolution | 360.000 degrees (or the correct value for a geared index table) |
| Absolute command rounding | Configured so absolute commands are reduced within one revolution |
| Rotary axis soft limits | Released or set beyond one revolution if the axis must turn continuously |
Step 3 — Apply the correct M-code in the program
In the case documented here, M94 produced the required behaviour and M126 did not. Structure the program so the mode is set explicitly and cancelled explicitly rather than relying on a modal state left over from a previous job:
O1000 (ROTARY INDEX EXAMPLE)
G90 G17 G21 G40 G80 (safe modal reset)
M94 (rotary handling code verified on THIS machine)
G00 C0. (reference the table at a known angle)
...
G00 C90. (index - short move expected)
...
G00 C270. (index - direction chosen by active mode)
...
M30
If the builder's manual defines a separate cancel code for the mode, place it in the program tail together with the other modal resets so the next operator does not inherit an unexpected state.
Step 4 — Alternatives if no shortest-path M-code exists
Not every machine offers the function. Workarounds that require no parameter changes:
-
Incremental commands. Command the index with
G91and a signed increment, e.g.G91 C-90., so the direction and travel are fully explicit. Return toG90immediately after. - Programmed unwind. After a group of indexes, command a return to the base angle explicitly in the direction that unwinds the utilities, or reset the coordinate with a work-offset/preset command permitted by the control.
-
Macro-computed shortest move. Compute the delta in a macro variable, normalise it to the range −180 to +180, and output an incremental move. Example logic pattern:
Confirm the available macro variables for current axis position on your control before using this pattern.#101 = [ #TARGET - #CURRENT ] WHILE [ #101 GT 180. ] DO1 #101 = #101 - 360. END1 WHILE [ #101 LE -180. ] DO2 #101 = #101 + 360. END2 G91 C#101 G90
Verification
- Dry run with the axis clear. With the tool retracted and no workpiece contact possible, single-block through the index sequence at reduced rapid override.
- Watch the distance-to-go display. On the block that indexes to the new angle, the remaining distance should be less than or equal to 180.000 degrees if shortest path is active. A value above 180 or a multi-revolution value means the mode is not active or the coordinate is still accumulating.
- Check absolute position after a full cycle. Run the program ten times without homing. If rollover is working, the displayed C position stays within one revolution instead of climbing by 360 per cycle.
- Confirm direction on the 180-degree case. A move of exactly 180 degrees is ambiguous. Note which direction the control chooses and, if the choice matters for cable wrap or a probe cable, replace that move with an explicit incremental command.
- Cycle-time check. Compare the measured cycle time of a full part before and after the change. Elimination of multi-revolution moves should show up as a repeatable reduction, and cycle time should no longer drift upward across consecutive parts.
- Utility wrap check. Inspect the rotary union, air/coolant lines and any encoder cable after a production run to confirm no net accumulated wind-up.
Preventive Practice
- Keep a machine-specific M-code sheet at the control. Do not copy auxiliary M-codes between machines, even from the same builder, without checking the list.
- Treat any M-code that "does nothing" as unassigned until proven otherwise — a silently ignored code is the normal outcome for a number with no PMC decode.
- Start every rotary program with an explicit safe-modal block and, where supported, an explicit rotary-mode selection so behaviour does not depend on the previous job.
- Where absolute rotary positioning is not strictly needed, prefer incremental indexing. It is unambiguous, portable between machines, and immune to accumulated-coordinate problems.
- Document the verified code in the program header as a comment so the next programmer does not repeat the M126 substitution.
FAQ
Why does my rotary axis take the long way around on an absolute command?
Because the axis coordinate has accumulated past 360 degrees, or rollover is disabled, so the control treats the command as a linear move in degrees and travels the full numeric difference. Verify the rotary axis type, rollover setting and degrees-per-revolution before changing the program.
Is M126 the standard shortest-path M-code?
No. Auxiliary M-code numbering above the small mandatory core set is control- and machine-builder specific. In the case documented here M126 had no effect and M94 delivered the required rotary behaviour, so always confirm the number against your own machine's M-code list.
Why did the wrong M-code not raise an alarm?
An M-code with no decode logic in the PMC/PLC can simply be passed through and ignored, so the program runs normally while the intended function never activates. Treat "no visible effect" as evidence the code is unassigned, not as evidence the function failed.
How do I get shortest-path indexing if my control has no such M-code?
Use incremental commands with G91 and a signed angle, or compute the delta in a macro and normalise it to the range −180 to +180 before issuing an incremental move. Both approaches make direction explicit and avoid multi-revolution travel.
How do I confirm shortest path is actually active?
Single-block the index block and read the distance-to-go display: with shortest path active it should never exceed 180.000 degrees. Also run the program repeatedly without homing and confirm the absolute position stays within one revolution instead of increasing by 360 each cycle.