Siemens 828D ShopMill Multi-Part Programming with G54 Work Offsets
The Siemens SINUMERIK 828D with ShopMill conversational programming provides four reusable mechanisms for running multiple identical parts from a single blank: settable work offsets (G54–G599), additive programmable transformations (ATRANS), the ShopMill editor's Mark + Repeat soft keys, and Siemens subroutine files (_SPF) called by label (L<label>) or by file name. This reference shows how to combine them so that a 4-to-10-part batch on a Sharp SVL-2416SE-M (or any 828D-built milling machine) executes with one tool change per tool rather than one tool change per part, while keeping every coordinate traceable and every position verifiable.
Overview: Why Fanuc Habits Fail on the 828D
On Fanuc-derived controls (Haas, Fanuc 0i/M, Fagor, Heidenhain's older TNC) the canonical multi-part pattern is M97 P1000 to call a local numbered sub-block and G54–G59 for fixture offsets. The Siemens 828D accepts G-code settable offsets from G54 through G599, but the subroutine architecture, the meaning of the editor's Mark key, and the behaviour of additive offsets all differ from Fanuc conventions. Operators who carry Fanuc muscle memory onto a 828D often produce code that is syntactically valid and executes correctly, yet generates one tool change per part instead of one tool change per tool across the entire batch — exactly the failure mode encountered when bringing Sharp-built 828D machines into a shop that already runs Haas or DMG-Mori Fanuc controls.
The reference Siemens 828D documentation for the items covered here is published in two manuals: the SINUMERIK 828D Milling — Control System Overview (SF, 0709 release) and the Easy Milling with ShopMill — Programming & Operation Manual (1123 release). Both are the official Siemens support PDFs and form the basis for the work-offset and subroutine descriptions that follow.
Prerequisites
- SINUMERIK 828D with the ShopMill option installed. Versions from 4.4 through 4.7 SP3 all support the features described; behaviour is consistent across the 4.x baseline.
- Axes referenced, machine calibrated, tool lengths measured (using the ShopMill tool list or a 3D probe), and the magazine table populated.
- Work offsets
G54throughG59(or extended settable offsetsG54.1 P1+on the NCU zero-offset table for > 6 parts) defined and verified with an edge finder or probe. - Familiarity with the ShopMill program editor, specifically the Mark start / Mark end / Repeat soft keys on the program header.
- Backup of the part program tree to a USB stick or CF card before any structural edit.
Siemens 828D Work Offset Architecture
The Siemens 828D groups coordinate systems into two categories: machine coordinates (G53, MCS) and settable work offsets (WCS). Settable offsets are modal and persistent until overwritten by another G5x call or by G500 (deactivates all settable offsets and reverts to MCS).
| G-Code | Group | Function | Behaviour |
|---|---|---|---|
| G53 | Modal in EIA, non-modal in DIN | Machine coordinates (MCS) | Deactivates active settable offset for one block |
| G54 | Modal | Settable work offset #1 | Persists until overridden |
| G55 | Modal | Settable work offset #2 | Persists until overridden |
| G56 | Modal | Settable work offset #3 | Persists until overridden |
| G57 | Modal | Settable work offset #4 | Persists until overridden |
| G58 | Modal | Settable work offset #5 | Persists until overridden |
| G59 | Modal | Settable work offset #6 | Persists until overridden |
| G500 | Modal | Deactivates all settable offsets | Returns to MCS |
| G54 … G599 | Modal | Extended settable work offsets | Configured under NCU settable zero offsets table |
Settable zero offsets are edited under Menu Select > Setup > Work Offsets on the operator panel, or programmatically through the system variable $P_UIFR[] and the ROT, SCALE, MIRROR, and TRANS commands. Each WCS entry accepts independent X, Y, Z, A, B, and C components plus optional rotation and scale.
G54–G59 Are Absolute, Not Relative
A common question when migrating from controls where offsets behave as relative deltas is: if I am in G54 and I change the G55 entry in the table, does G55 read as the delta from G54 or as an absolute position from machine zero? On the Siemens 828D every settable offset is an absolute translation from G53 machine zero. Changing G55 in the offset table does not add to G54; it is its own independent reference.
Concretely: if part 1 is fixtured at machine coordinates X-300 Y-150, the G54 entry should read X-300 Y-150 Z0. Part 2 at fixture position X-150 Y-50 should be entered into G55 as X-150 Y-50 Z0 — the actual machine coordinate of part 2's datum, not the difference between part 1 and part 2.
Verify the result by issuing G54 G0 X0 Y0 Z50 and indicating the spindle nose over the part fixture. Repeat for each G5x in the batch. A 0.05 mm error on a work-offset entry propagates to every machining block that uses that offset.
ShopMill Mark and Repeat on the 828D
Older Siemens controls (810D, early 820D) used the Mark key as a clipboard highlight for copy/paste. On the 828D and 840D, Mark is the entry point to a structured repeat block: it brackets a sequence of program lines that the editor will then expand with a configurable offset increment per repetition.
- Position the cursor on the line immediately before the block you want repeated.
- Press the Mark start soft key.
- Move the cursor to the last line of the block.
- Press Mark end.
- Press the Repeat soft key. The editor prompts for the number of additional passes and the offset increment per pass (in X, Y, Z, and optionally rotation around the spindle axis).
- ShopMill inserts the repeat header above the marked block; the original block runs once plus N additional copies with the offset applied per copy.
The repeat block is functionally equivalent to writing the same block N times with progressively incremented ATRANS values, but the editor manages the loop and surfaces it visually so the operator can audit the offsets before running.
Subprogram Architecture on the 828D
Siemens 828D stores subprograms as separate files in the NC memory (or on the CF card / network share for newer 4.7+ builds). Each subprogram uses the extension _SPF (subprogram file), the main program uses _MPF, and initialization files use _INI. Programs are called either by label (numbered or named block) within the same _MPF, or by file reference for a separate _SPF.
| File Type | Extension | Purpose | Call Method |
|---|---|---|---|
| Main program | _MPF | Top-level NC program | Selected from NC Start |
| Subprogram (named file) | _SPF | Reusable sub-block sequence |
L<filename> or CALL "NAME"
|
| Local subprogram (in same file) | _MPF | Inline label sequence | L<label> |
| Initialization file | _INI | Run at NCK reset / boot | Automatic |
The Fanuc convention of placing a numbered subroutine at the bottom of the same O-numbered file and calling it with M97 P1000 does not transfer cleanly. On the 828D, the equivalent of an inline subroutine is a numbered or named label inside the same _MPF, called by its label name. For reusable blocks that are shared across multiple main programs, write a separate _SPF file.
ATRANS, ROT, SCALE, MIRROR, TRANS: Programmable Transformations
The Siemens 828D exposes five programmable transformations layered on top of the active WCS. They apply additively without touching the G54–G599 table, so they are ideal for walking one toolpath across an array of parts.
| Command | Function | Cleared By |
|---|---|---|
ATRANS X… Y… Z… |
Additive translation in the active plane |
TRANS (clears all transformations) or ATRANS with new values |
ROT or AROT
|
Additive rotation about spindle axis |
ROT with zero, or TRANS
|
SCALE or ASCALE
|
Additive scale factor |
SCALE 1, or TRANS
|
MIRROR or AMIRROR
|
Additive mirror across an axis |
MIRROR with no axis, or TRANS
|
TRANS |
Clears all programmable transformations | N/A |
Use ATRANS when the spacing between parts is regular and known in advance. Use ROT when parts are rotated on the table but otherwise identical. Use MIRROR when a mirrored fixture position exists. Always issue TRANS before switching from one G5x to another if any additive transformation was active — residual ATRANS values will silently offset the new WCS.
; --- ATRANS usage, 4 parts on 75 mm pitch ---
N10 G54 G0 X0 Y0 Z50 ; move to G54 origin, safe Z
N20 T1 D1 M6
N30 SETMS(1)
N40 G95 S1200 M3
N50 M8
N60 ATRANS X0 Y0 ; part 1 at G54 origin
N70 L FACE_T1
N80 ATRANS X75.0 Y0 ; part 2
N90 L FACE_T1
N100 ATRANS X150.0 Y0 ; part 3
N110 L FACE_T1
N120 ATRANS X225.0 Y0 ; part 4
N130 L FACE_T1
N140 TRANS ; clear additive offset
N150 G0 Z100 M5 M9
N160 T2 D1 M6
N170 G54 G0 X0 Y0 Z50
N180 ATRANS X0 Y0
N190 L POCKET_T2
... (continue for parts 2–4)
N999 M30
R Variables for Parametric Multi-Part Programs
Siemens 828D global R variables (typically R0–R99 for user-defined values, R100+ reserved) are the right tool to make a multi-part program parametric. Storing the number of parts and the spacing in two R-variables lets the operator change one value at the machine to alter the entire batch — no editor required.
; --- MAIN.MPF (parametric, 5 parts on 80 mm pitch) ---
R1 = 5 ; number of parts
R2 = 80.0 ; X spacing between parts (mm)
R3 = 0 ; running counter
R4 = 0 ; accumulated offset
T1 D1 M6
SETMS(1)
G95 S1200 M3
M8
N100 R4 = R3 * R2 ; R4 = (counter) * spacing
N110 G54 G0 X0 Y0 Z50
N120 ATRANS XR4 Y0 ; apply parametric offset
N130 L FACE_T1 ; run subprogram at this offset
N140 R3 = R3 + 1 ; increment counter
N150 IF R3 < R1 GOTOB N100 ; branch back until R3 == R1
N160 TRANS ; clear additive offset
N170 G0 Z100 M5 M9
T2 D1 M6
G95 S1200 M3
M8
R3 = 0 ; reset counter for tool 2
N200 R4 = R3 * R2
N210 G54 G0 X0 Y0 Z50
N220 ATRANS XR4 Y0
N230 L POCKET_T2
N240 R3 = R3 + 1
N250 IF R3 < R1 GOTOB N200
N260 TRANS
N270 G0 Z100 M5 M9
M30
; --- FACE_T1.SPF ---
G0 X0 Y0 Z5
G1 Z-0.5 F80
G1 X100 F200
G0 Z5
RET
; --- POCKET_T2.SPF ---
G0 X10 Y10 Z5
G1 Z-2.0 F60
... (pocketing moves)
G0 Z5
RET
Subprogram Structure on the 828D
A reusable subroutine file is a _SPF file in the same directory as the calling _MPF. The file must end with RET (not M99) and is called by its name with the L<name> statement or by CALL "NAME". Local subprograms (labels) live inside the same _MPF as the calling code and are called by label.
; --- inline local subprogram within MAIN.MPF ---
N10 G54 G0 X0 Y0 Z50
N20 T1 D1 M6
N30 L FACE_LOOP ; call inline label below
N40 G55 G0 X0 Y0 Z50
N50 L FACE_LOOP
N60 G56 G0 X0 Y0 Z50
N70 L FACE_LOOP
N80 G0 Z100 M5 M9
N90 M30
N100 FACE_LOOP
N110 G0 X0 Y0 Z5
N120 G1 Z-0.5 F80
N130 G1 X100 F200
N140 G0 Z5
N150 RET
Step-by-Step Workflow: 4 Parts, 3 Tools, One Blank
- Measure each part datum. With an edge finder or 3D probe, capture X, Y, Z of every part fixture relative to machine zero. Note each reading with its part number.
-
Populate the work-offset table. Enter each part's machine coordinate into slots G54 through G57 (or higher settable offsets if more than 6 parts). Verify by rapid-jogging to
G5x G0 X0 Y0 Z50over each fixture. -
Write one subroutine per tool. For T1 (facing), write
T1_FACE.SPF; for T2 (pocketing), writeT2_POCKET.SPF; for T3 (drilling), writeT3_DRILL.SPF. Each subroutine ends withRETand assumes it is called under an active WCS with the spindle already at the part datum. - Write the main program in the tool-change order. For each tool, issue the tool change, then for each work offset call the corresponding subroutine. This collapses N×T tool changes down to T.
- Dry-run the entire batch. Toggle DRY RUN on and set rapid override to 25%. Step through every part and every tool to verify toolpath stays inside the workpiece envelope and clamps.
- Single-block the first part. Single-block (SBL) through the first part on every tool to verify spindle RPM, feedrate, coolant, and Z-approach clearance. Then run remaining parts in AUTO.
- Capture proving cuts. Save the first part for inspection. If the WCS table is correct, parts 2–N will be within fixture repeatability and tool wear.
Code Comparison: Fanuc/Haas Pattern vs Siemens 828D Pattern
| Function | Haas / Fanuc | Siemens 828D |
|---|---|---|
| Local subprogram call | M97 P1000 |
L1000 (label) or L<filename>
|
| External subprogram call | M98 P1000 |
CALL "SUB_NAME" |
| Subprogram return | M99 |
RET |
| Set work offset | G54 |
G54 |
| Deactivate all WCS | G53 |
G500 or G53
|
| Inline subprogram location | Bottom of same O-file | Same _MPF, called by label |
| Block repeat | Macro loop / manual paste | ShopMill Mark + Repeat with offset increment |
| Local coordinate offset | G52 |
ATRANS |
| Clear additive offset | G52 X0 Y0 |
TRANS |
| Local mirror | G51.1 |
MIRROR / AMIRROR
|
| Local rotation | G68 |
ROT / AROT
|
| Global numeric variables |
#1–#33 (common) / #100+ (extended) |
R0–R99 (global) / LUD for local |
| Spindle selection | Modal via M-codes | SETMS(n) |
Tool-Change Optimization Across the Batch
The original problem in the source material is that the operator's first attempt at multi-part programming generated 4 parts × 5 tools = 20 tool changes. The fix is structural: write one subroutine per tool, call it under each work offset, then change the tool once. The pattern is:
; --- Optimized 4-part / 5-tool main loop ---
RESET_POS ; clear all transforms and rapid to safe Z
T1 D1 M6
G0 G54 X0 Y0 Z20 ; part 1, G54
L T1_FACE
G0 G55 X0 Y0 ; part 2, G55
L T1_FACE
G0 G56 X0 Y0 ; part 3, G56
L T1_FACE
G0 G57 X0 Y0 ; part 4, G57
L T1_FACE
G0 Z100 M5
T2 D1 M6
G0 G54 X0 Y0 Z20
L T2_POCKET
G0 G55 X0 Y0
L T2_POCKET
G0 G56 X0 Y0
L T2_POCKET
G0 G57 X0 Y0
L T2_POCKET
G0 Z100 M5
...repeat for T3, T4, T5...
M30
This collapses the 20 tool changes to 5 (one per tool). For a 5-tool batch of 10 parts the saving is 90 tool changes per cycle, which on a 828D with magazine swap time of 4–7 seconds per change is roughly 6–10 minutes of pure tool-change time saved per setup.
Edge Case: Irregular Spacings
When parts are not on a regular pitch (e.g., one part at fixture slot 1, one at slot 3, one at slot 7 because of clamp obstructions), drop the ATRANS pattern and use the WCS table directly. Populate G54, G55, G56 with each part's actual machine coordinate and call the tool subroutine under each offset without any ATRANS in between.
T1 D1 M6
G54 G0 X0 Y0 Z20 L T1_FACE
G55 G0 X0 Y0 L T1_FACE
G56 G0 X0 Y0 L T1_FACE
G0 Z100 M5
T2 D1 M6
G54 G0 X0 Y0 Z20 L T2_POCKET
G55 G0 X0 Y0 L T2_POCKET
G56 G0 X0 Y0 L T2_POCKET
G0 Z100 M5
M30
The WCS table approach is also the correct choice for first-article proving, because every offset is independently editable from the operator panel without touching the part program.
Edge Case: Mirrored and Rotated Fixtures
If two fixtures are mirrored across the X-axis (e.g., parts handed in pairs), use AMIRROR X0 between work-offset calls to flip the active WCS. For a part rotated 90° on the table, use AROT Z90. Combine freely — transformations layer on top of one another and are cleared in one shot by TRANS.
G54 G0 X0 Y0 Z20 L T1_FACE ; part 1, normal orientation
TRANS
G55 G0 X0 Y0
AMIRROR X0 ; flip about X-axis
L T1_FACE ; part 2, mirrored
TRANS ; clear mirror
G56 G0 X0 Y0
AROT Z90 ; rotate 90° CW about Z
L T1_FACE ; part 3, rotated
TRANS ; clear rotation
M30
Verification Checklist
- Confirm the active WCS in the displayed actual-value window matches the part under the spindle before pressing Cycle Start.
- Single-block (SBL) the first part on every new tool to verify Z-approach clearance above clamps, fixture, and stock.
- Dry-run at 25% rapid override to confirm toolpath stays inside the stock envelope for every work offset.
- Verify R-variable initial values by issuing them as standalone blocks and reading back in the parameters display.
- Confirm
TRANSis issued before anyG5xswitch ifATRANS,ROT, orMIRRORwas active in the previous block; residual transformation values silently offset the new WCS. - Verify tool-length compensation by issuing
G54 G0 X0 Y0 Z0and indicating the spindle nose over a known Z reference for each offset. - Back up the program tree to USB before any structural edit; 828D NC memory is volatile on power-down for the unsaved portion.
Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
| Tool goes to wrong position on second part | WCS entry relative to G54 instead of absolute from G53 | Re-enter each offset as the actual machine coordinate of that part's datum |
| Tool change after every part instead of every tool | Subroutine nested inside the G5x loop, calling itself per part | Split into one subroutine per tool and call each subroutine under each G5x before tool change |
| Alarm: "Subprogram not found" (Siemens 14011) |
_SPF file missing from NC memory or filename mismatch with L<name> call |
Check Program Manager file list; confirm exact case-sensitive name matches the L<name> statement |
| Tool offset drift across parts |
ATRANS not cleared before WCS switch |
Insert TRANS before the next G5x
|
| Spindle starts even though toolpath is in air | DRY RUN not enabled, or DRY RUN overridden by modal M-code | Enable DRY RUN toggle and verify active modal codes in the actual-value window |
| Cutter-comp direction wrong on mirrored part | G41/G42 sign error after AMIRROR | Verify cutter-comp side after every mirror; re-orient tool if needed |
| First part good, subsequent parts out of position | Tool-length number not active for the new offset; magazine called wrong slot | Verify D-number in the tool table and tool call sequence |
| Subprogram edits not picked up at runtime | Cached _SPF from previous NC start |
Reset NCK, re-select the main program, then Cycle Start |
Tool-Table Interaction with Work Offsets
Tool-length and tool-radius compensation on the 828D is held in the tool table, accessed via the D-number in the tool call. The work offset, the programmable transformation, and the tool compensation are independent layers: tool-length is applied after WCS, so a tool that is 10 mm longer than the probe-master shifts the Z-approach by exactly 10 mm regardless of which G5x is active. Verify this by probing at G54 and G59 with the same tool and confirming the indicated Z-readout shifts by exactly the tool length.
Tool radius compensation (G41/G42) is sensitive to programmable transformations. Always re-issue G40 (cutter-comp cancel) before switching from one offset+transformation combination to another, and re-engage cutter-comp on the first linear move after the switch. Failure to do this can trigger alarm 10751 (cutter-comp direction undefined) on the next approach move.
Work-Offset Probing on the 828D
The ShopMill editor supports probe cycles for setting work offsets. Under Setup > Work Offsets, select the offset to set, choose the probe cycle (corner, edge, slot, boss, 4-point boss, 4-point slot), and the control will calculate the WCS entry from the measured points. This is the fastest path to accurate G54–G59 entries on a multi-part fixture and removes the manual edge-finder error.
For multi-fixture setups, probe each fixture independently and write the result into the corresponding G5x slot. The ShopMill probe editor keeps a separate probing routine per offset, so the operator can re-probe any single fixture without re-probing the entire batch.
Machine-Specific Notes: Sharp SVL-2416SE-M
The Sharp SVL-2416SE-M is a vertical machining centre built around a SINUMERIK 828D controller with the ShopMill option. The 24 × 16 inch (610 × 400 mm) travels are well-suited to 4–10 part batches of small-to-medium prismatic parts. Watch for two platform-specific behaviours: (1) the magazine table on Sharp SVL builds is sometimes indexed to start at tool slot 1 = spindle-loaded, so an empty slot at the start of the program requires a T0 placeholder call; (2) the rapid-traverse rate on early SVL builds is 24 m/min, which can cause over-travel alarms if a parametric ATRANS pushes a toolpath past the soft limit during the first dry run. Always run a dry-run with rapid override set to 25% for the first execution of any new multi-part program.
Are Siemens 828D work offsets G54–G59 absolute or relative?
Each G54 through G599 entry on the Siemens 828D is an absolute translation from the G53 machine coordinate system. They are independent, not relative — entering a different value for G55 does not move the spindle by that delta from G54. Enter the actual machine coordinate of each part datum.
How do I call a local subroutine on the 828D the way M97 works on Haas?
Use a labelled block inside the main program and call it with the same label name, e.g. L FACE_LOOP for a subroutine labelled FACE_LOOP. For reusable blocks shared across multiple main programs, write a separate _SPF file and call it with L<filename> or CALL "NAME". End the subroutine with RET, not M99.
How can I run one tool across all parts without a tool change per part?
Write one subroutine per tool and call it under each work offset. Issue G54, run the T1 sub, issue G55, run the T1 sub again, and so on. Only then change to T2 and repeat the G5x loop. This collapses N×T tool changes down to T — for a 5-tool batch of 10 parts that is 90 tool changes saved per cycle.
What is the difference between ATRANS and changing the G54 table?
ATRANS applies an additive offset on top of the active G5x offset for the remainder of the program or until cleared with TRANS. It does not modify the work-offset table. This is faster than writing through the table, survives NC reset, and can be applied per tool within a single program.
Why does the ShopMill Mark feature not behave like copy-paste on the 828D?
On the 828D and 840D, the Mark soft key brackets a block sequence that the editor then expands via the Repeat function with a user-supplied offset increment per pass. It is not a clipboard highlight — that clipboard behaviour is on the older 810D. On the 828D the sequence is Mark start → Mark end → Repeat to insert the loop with the per-pass offset.
Can I use the same R-variable name in two different subprograms?
R-variables are global on the 828D, not file-local. Sharing the same R-variable across multiple _SPF files is a common bug source. Use local-user-data (LUD) variables, prefixed with LUD_, for values that should be scoped to a single subroutine and not persist after RET.