Overview: Why Use Dual Work Offsets?
When machining a part that must be finished on more than one face (a block that needs both ends faced, a bracket that must be milled on opposite sides, or a turned/flip-finished blank), the operator can choose one of three strategies: run the program twice with manual repositioning, write a subprogram with multiple coordinate references, or call a second work coordinate system inside the same program. The third strategy is the cleanest because it preserves continuous program flow, requires no operator intervention between cuts beyond a part flip, and leaves an auditable single program file on the controller.
On Siemens SINUMERIK 840D sl / 828D / 802D controllers this is implemented through settable work offsets (German: einstellbare Nullpunktverschiebungen) accessed by the standard G-codes G54 through G599, or, on FANUC-compatible post processors, by G54 through G59 plus the extended G54.1 P1..P48 range. The original example posted by the operator shows a clean two-pass block-facing job on a 3 inch raw blank that needs to be reduced to 2.75 inch finished thickness, with an optional stop between operations and a tool change at the top of the program.
Work Coordinate System Architecture
Every CNC controller maintains at least one programmable origin (machine zero, set by the manufacturer at a known reference point on each axis) plus an active work offset that the programmer references with G54..G59 (and the extended G54.1 range on FANUC-style controls). The active offset is added to all subsequent absolute coordinate moves until another G5x code, a G92 shift, or a controller reset changes it.
| G-code | FANUC Name | Siemens SINUMERIK Frame | Typical Use |
|---|---|---|---|
| G54 | Work Offset 1 | $P_UIFR[1] / Frame 1 | Primary workpiece origin |
| G55 | Work Offset 2 | $P_UIFR[2] / Frame 2 | Second setup, flipped part, opposite face |
| G56 | Work Offset 3 | $P_UIFR[3] / Frame 3 | Multi-fixture cells, pallet changer |
| G57 | Work Offset 4 | $P_UIFR[4] / Frame 4 | Multi-fixture cells |
| G58 | Work Offset 5 | $P_UIFR[5] / Frame 5 | Multi-fixture cells |
| G59 | Work Offset 6 | $P_UIFR[6] / Frame 6 | Multi-fixture cells |
| G54.1 P1..P48 | Extended Offsets (FANUC) | n/a by default | Fixtures beyond 6 |
| G54..G599 (programmable) | n/a | $P_UIFR[1..100] | Siemens settable ZO up to 100 frames |
The active offset is modal: it stays in effect until another G5x code, a G92 (or G52 on FANUC) single-axis shift, a reset, or a M30 program end. On Siemens controllers the modal group for work offsets is NCM grp 6 according to the SINUMERIK Operate programming manual; selecting G55 while G54 is active causes the controller to recompute the absolute position from the new frame before the next linear or rapid move.
Siemens SINUMERIK-Specific Frame Behaviour
Siemens controllers separate the workpiece-related frames ($P_UIFR / settable frames) from the system frame ($P_SYSTEMFRAME) and from the basic frame ($P_BFRAME). This matters when chaining offsets: a G55 command on a SINUMERIK 840D sl adds the second settable frame on top of any active basic frame and any active rotation. The programmer does not need to zero out G54 before calling G55; the controller switches the active frame at the modal boundary.
Two practical differences vs. a FANUC-style control:
- Siemens stores the offset values in NC variables (e.g. $P_UIFR[1, X, TR] = 0.0) editable from the HMI under Work offsets > Settable frames. A persistence reset on the controller clears these unless they have been written to a part program with
ROT / TRANS / SCALEorATRANS. - Siemens permits up to 100 settable frames by default (G54..G153 in the 840D sl sl-list). The G5x names map to the first six for compatibility; the remainder are addressed by G54 + n in operator-parameter form or via the equivalent frame index.
For documentation, see the SINUMERIK 840D sl Programming Manual and the SINUMERIK 828D Programming Manual. The frame architecture is identical between 840D sl and 828D; only the HMI labelling differs.
Prerequisites
- Siemens SINUMERIK 802D, 828D, or 840D sl controller (or a FANUC-compatible controller if running the unmodified example).
- Soft-key access to the Settable Zero Offset (ZO) table under Work offsets on the HMI.
- Edge finder or 3D probe with calibrated probe tip in the spindle for establishing the two part origins.
- Tool length offset number 1 already calibrated (H01 / $TC_DP3[1,1] on Siemens, H01 on FANUC).
- Coolant nozzle, vise or fixture, and a reference surface (a 1-2-3 block or precision parallels) to set the Z reference for each face.
- Optional stop enabled on the controller if the operator wants M1 (rather than M0) to pause between faces.
Establishing the Two Work Origins
Set G54 first. With the raw blank clamped in the vise and the first face (the side to be cut first) up:
- Edge-find X0 on the part edge (or probe the part edge) and store the X reading into Work Offset G54.
- Edge-find Y0 on the part edge and store the Y reading into Work Offset G54.
- Touch off Z on the unmachined top face (the 3.000 inch face in the example). Enter the value into the G54 Z slot. Because the part is 3.000 thick and the finished face 1 is at 2.875 (0.125 inch face cut), the controller interprets any subsequent G54 Z move as measured from the top of the raw blank.
Do not yet touch off G55. The second origin is established after the part has been flipped. After the first cut, lay the freshly machined face down on the parallels, re-clamp, edge-find X and Y again, and now enter the X / Y / Z values into the G55 work offset slot. Z on G55 must be set on the surface that will become the bottom of the part after flipping (the freshly machined face from step one).
Programming the First Facing Pass (G54)
The first half of the program is identical to a standard single-offset facing routine. Safety line, tool change, optional stop, then the active G54 frame:
% ; Program start (FANUC) / MPF identifier on Siemens
G90 G00 G80 G49 G40 ; Absolute, rapids, cancel canned cycle, cancel tool length comp, cancel cutter comp
T1 M6 ; Tool 1, tool change
M1 ; Optional stop: lets the operator re-check spindle/tool before cut
G54 G90 G00 X-2.0 Y-2.0 S3000 M3 ; Activate G54 frame, rapid above start point, spindle CW
G43 H1 Z2.875 M8 ; Apply tool length offset H1, rapid to Z cut level (2.875 in above G54 Z=0), coolant on
G01 X5.0 F50. ; Linear feed to clear part at 50 ipm
G91 G28 G00 Z0. ; Return to Z reference
G91 G28 G00 Y0. ; Return to Y reference
M0 ; Program stop - operator flips the part
On Siemens 840D sl this maps to:
; SPF101 - Face Block Op1
N10 G90 G0 G60
N20 T1 D1
N30 M6
N40 M1
N50 G54 G90 X-2.0 Y-2.0
N60 S3000 M3
N70 Z2.875
N80 G1 X5.0 F50
N90 G0 Z100
N100 M0 ; Stop for part flip
The modal G54 stays active until the next G5x call. The M0 halts block reading and waits for Cycle Start from the operator.
Programming the Second Facing Pass (G55)
After the M0, the operator flips the part, re-clamps, and presses Cycle Start. The next block reactivates G55 (or stays in G54 if the operator prefers to re-write the Z-only value of G54 instead of using G55). Using G55 keeps the audit trail of two separate setups clear:
G55 G90 G00 X-2.0 Y-2.0 S3000 M3 ; Switch active frame to G55 (fresh origin)
G43 H1 Z2.750 M8 ; Approach new Z target (2.750 in for second 0.125 in face cut)
G01 X5.0 F50.
G91 G28 G00 Z0.
G91 G28 G00 Y0.
M30
%
Note that the tool, spindle speed, and feedrate are re-issued on the second block because modals are unaffected by the M0, but it is good practice to state them explicitly after any M0 / M1. A G49 cancel in the safety line at the top means H1 must be re-applied with G43 after the M0; the G43 line above does exactly that.
Complete G-code Program Example
%
O0201 (FACE BLOCK BOTH SIDES - DUAL OFFSET)
G90 G00 G80 G49 G40 G17 G21 G54
T01 M06
M01 (CHECK TOOL & BLANK)
G54 G90 G00 X-2.0 Y-2.0 S3000 M03
G43 H01 Z2.875 M08
G01 X5.000 F50.
G91 G28 G00 Z0.
G91 G28 G00 Y0.
M00 (FLIP BLOCK & REZERO G55)
G55 G90 G00 X-2.0 Y-2.0 S3000 M03
G43 H01 Z2.750 M08
G01 X5.000 F50.
G91 G28 G00 Z0.
G91 G28 G00 Y0.
G91 G28 G00 X0.
M30
%
This is the source operator's example with an X-axis home added before M30 to ensure the table returns to a known parking position. On a Siemens 840D sl the equivalent is:
; MPF201 / _N_MPF201
N10 G90 G0 G60
N20 T1 D1 M6
N30 M1
N40 G54 X-2.0 Y-2.0
N50 S3000 M3
N60 Z2.875
N70 G1 X5.0 F50
N80 Z100
N90 M0
N100 G55 X-2.0 Y-2.0
N110 S3000 M3
N120 Z2.750
N130 G1 X5.0 F50
N140 Z100
N150 M30
Alternative Programming Methods
If the controller does not expose a second settable frame, or if the operator wants to keep the program short, two alternatives are commonly used:
| Method | Code | Pros | Cons |
|---|---|---|---|
| Dual G5x frame | G54 / G55 | Clear audit trail; each setup is its own offset | Operator must touch off G55 after the flip |
| G92 / G52 single-axis shift | G92 Z[shift] | Re-uses G54; no second offset table | Modifies absolute Z; easy to forget G92 reset |
| Subprogram with macro variable | #100 = 2.875 / 2.750 | Single point of edit for Z heights | Requires FANUC custom macro B or Siemens @ variables |
| Subprogram with #1 / @P_SET | CALL / RET on Siemens | Modular, reusable across parts | Adds two extra files to manage |
For FANUC custom macro B, the operator can drive the two Z heights from a common variable so the program does not have to be edited twice:
#100 = 2.875 ; Op1 finish Z (above G54 origin)
#101 = 2.750 ; Op2 finish Z (above G55 origin)
G54 G00 X-2.0 Y-2.0 S3000 M3
G43 H1 Z#100 M8
G01 X5.0 F50.
G91 G28 Z0.
M0
G55 G00 X-2.0 Y-2.0 S3000 M3
G43 H1 Z#101 M8
G01 X5.0 F50.
G91 G28 Z0.
M30
Siemens equivalent: declare in the GUD block (Global User Data):
DEF NCK INT _OP_Z1 = 2.875
DEF NCK INT _OP_Z2 = 2.750
then reference G1 X5.0 F50 Z=_OP_Z1 and G1 X5.0 F50 Z=_OP_Z2 in the two passes. Siemens user-defined variables are explained in the SINUMERIK 828D Programming Manual.
Verification and Dry Run Procedure
- Dry-run the program with the M0 / M1 stop disabled (parameter setting on Siemens: SETUP > Program control > Dry run feedrate; on FANUC: DRY RUN switch on) and the spindle override to 0% to confirm motion paths.
- Single-block through the program. Confirm at the G43 H1 Z2.875 line that the controller reads the actual Z position as expected above the raw blank (use the Actual Position display on the HMI).
- After M0, do not move any axis by hand. Re-touch off G55 using the freshly cut face as Z=0 and the new X / Y edges as X=0 / Y=0.
- Press Cycle Start. Confirm the controller moves to the new Z2.750 absolute position by reading the displayed MCS (machine coordinate system) value vs. WCS (work coordinate system) value; they must differ by exactly the G55 frame contents.
- Measure the finished block with micrometers or calipers. The finished thickness must be 2.750 +/- 0.001 inch (or whatever the drawing call-out dictates) and both faces must be parallel within 0.001 inch.
Troubleshooting Matrix
| Symptom | Likely Root Cause | Fix |
|---|---|---|
| Second cut crashes into the part at the wrong Z | G55 Z not reset after the flip; controller still uses raw G54 Z value | Re-touch G55 Z on the freshly machined face; verify in Work Offset table |
| Operator forgets to flip and the cut duplicates the first pass | Used M1 (optional stop) instead of M0 (program stop), optional stop disabled on HMI | Switch to M0, or enable the optional stop switch (FANUC: OSP ON; Siemens: Program control > OPI) |
| Spindle does not restart after M0 | S3000 M3 not re-issued in the G55 block | Re-issue S3000 M3 after the M0 (modal but explicit is safer) |
| Tool length comp is missing on second cut (crash) | G49 in safety line canceled H1; G43 H1 not re-issued after M0 | Always re-issue G43 H01 on the line following G55 |
| Y position is offset by vise jaw shift after flip | G55 Y not re-touched | Re-edge-find Y after the part flip |
| Siemens alarm 16931 "Frame not allowed" | Attempting to call a non-configured frame on a Siemens 802D base configuration | Enable additional frames in machine data: MD20150 $MC_GCODE_DEFAULT_SETTINGS or use $P_UIFR[ ] index 1..6 only |
| Siemens alarm 14011 "Channel not ready" | M0 executed while spindle still ramping | Insert dwell (G4 F2) or wait for spindle-at-speed before M0 |
| FANUC alarm 5060 "G5x offset value out of range" | G55 Z written in metric while program is set G20 (inch) or vice versa | Match G20/G21 mode to offset value units; toggle with G10 L2 P2 to rewrite G55 |
What is the difference between G54 and G55 on a Siemens SINUMERIK CNC?
G54 and G55 are the first two settable work offsets (German: einstellbare Nullpunktverschiebungen) stored as $P_UIFR[1] and $P_UIFR[2]. Switching between them simply changes the active frame; X, Y, and Z coordinates written after a G55 line are interpreted relative to the G55 origin instead of the G54 origin. See the SINUMERIK 840D sl Programming Manual for the full frame table.
Can I use the same G54 offset twice instead of G55 for a flipped part?
Yes. Touch off G54 X, Y, and Z after the flip, and the program stays in G54 for both passes. Using G55 is preferred for an audit trail because the first-cut and second-cut origins are stored in separate rows of the work-offset table.
Why does my tool length offset disappear after M0 on a FANUC controller?
The safety line at the top of the program contains G49, which cancels tool length compensation. Because M0 does not reset modal states, H1 must be re-applied with a G43 H1 line after the M0. Always re-issue G43 H01 on the first move of the second operation.
How many settable work offsets are available on a Siemens 840D sl?
Up to 100 settable frames (G54..G153 in the 840D sl sl-list, though only six are pre-named G54..G59 for compatibility). The actual number available on a specific machine depends on the MD20150 $MC_GCODE_DEFAULT_SETTINGS machine data setting; on default configurations G54..G599 are accessible.
Is M0 or M1 better for a part flip in the middle of a program?
M0 (program stop) is unconditional and always halts the program. M1 (optional stop) only halts if the optional-stop switch is enabled on the HMI. For a flip operation where you definitely want to pause, use M0. Use M1 only when the pause is situational (for example, the first article of a run).