Overview: Indirect Subprogram Invocation on SINUMERIK 840D sl / 828D
On Siemens SINUMERIK 840D sl, 840D, 828D, and One NCU controllers, the CALL instruction in the NC high-level language accepts a program identifier that may itself be a string variable. This enables dynamic subprogram selection at runtime — for example, letting an HMI operator choose a machining sequence from a list, or letting the NC select a tool-specific dressing program from a recipe without editing hard-coded CALL statements.
The pattern requires three building blocks:
- A global user data (GUD) string variable large enough to hold the program name (32 characters is the practical default).
- An ISFILE() existence check against the active subprogram directory (
SPF.DIR) so the controller never attempts toCALLa missing program. - A plain
CALL <string_var>statement — notEXTCALL, which has different semantics for external (CF card / network) storage.
This article documents the full mechanism, including directory semantics, slash handling, error codes, and a reproducible HMI-side commissioning checklist.
Prerequisites
| Item | Specification |
|---|---|
| Controller | SINUMERIK 840D sl, 840D, 828D, One NCU, or SinuTrain (PC simulation) |
| Firmware / NCK software | NCU software 4.5 SP2 or higher recommended (HMI version 4.7+). Earlier versions support the same syntax but lack some edge-case handling. |
| Program directory | Local NC program memory (passive file system) — the file must be present in SPF.DIR of the active channel. External files on CF card, network share, or USB require EXTCALL. |
| GUD scope | The string variable must be visible from MAIN.MPF. Use DEF NCK for cross-channel, or DEF CHAN for channel-specific. |
| File name length | Maximum 32 characters (NCK STRING[32]). Includes the dot and extension. Reserve one extra character for the . separator. |
| Operator access | Program selection should be performed in RESET or a controlled subprogram — never inside an active block look-ahead, or the controller will generate illegal program name errors. |
GUD4.DEF or whichever GUD number you choose) before modifying. A syntax error in any DEF statement blocks NCK startup and leaves the machine in passive mode with alarm 12750 Channel %1 error in GUD file GUD%.2DEF or alarm 7596 Channel %1 GUD file.NC File-System Topology: MPF.DIR vs SPF.DIR
SINUMERIK stores part programs in a passive file system rooted at the NC card. The two directories that matter for this pattern are:
| Directory | Contents | Called by | Typical use |
|---|---|---|---|
MPF.DIR |
Main program files (.MPF) |
Operator selection or NC reset | The entry point, e.g. MAIN.MPF
|
SPF.DIR |
Subprogram files (.SPF) |
CALL from a main or another subprogram |
Reusable cycles, subroutines, recipes |
CMA.DIR |
Compile cycles | — | Manufacturer compile cycles (out of scope here) |
CUS.DIR |
User cycles | — | Manufacturer or end-user cycles |
The path string handed to ISFILE() must begin with a leading slash and end with the program name. For subprograms the correct form is:
/SPF.DIR/MY_SUB.SPF
For main programs use /MPF.DIR/.... The dot character . between name and extension is mandatory; the controller does not append it for you.
GUD Variable Definition
Global user data lives in dedicated definition files in the NC active file system. SINUMERIK provides GUD1..GUD9. Files below the leading underscore (_GUD0) are retain — they survive NCK reset. Numbered GUDs are session-only.
Recommended file: GUD4.DEF (or any free number). Place it under NC active / Definitions / GUD4.DEF via HMI menu Start-up > Define.
; GUD4.DEF — global user data
; Cross-channel scope (DEF NCK)
DEF NCK STRING[32] NAME ; target subprogram name (incl. extension)
DEF NCK BOOL ISNAME ; existence flag, 1 = present
Rules of the DEF statement:
- Position: anywhere in the file, separated by semicolons or whitespace.
- Indentation: ignored by the parser.
-
Scope keywords:
NCK(global),CHAN(per-channel),DOUBLE(per-axis-pair — rarely used for strings). -
Type:
STRING[32]reserves 32 characters.STRING[128]is allowed in newer NCK 4.8+ for long paths; default is 32.
;;) and the line-comment marker (; followed by content to end-of-line) are both legal. The parser terminates an entry on the next unquoted semicolon, NOT on end-of-line.The ISFILE() Existence Check
ISFILE(<path>) returns TRUE when the file exists in the addressed directory, FALSE otherwise. The function operates synchronously on the passive file system and is safe to call from MAIN.MPF before a CALL.
ISNAME = ISFILE("/SPF.DIR/" << NAME)
The operator << is the NC string concatenation operator (two left-angle brackets with no space). It joins the directory prefix and the variable contents at runtime. The compiled result is evaluated as the argument to ISFILE().
Common error patterns to avoid:
| Mistake | Symptom | Fix |
|---|---|---|
Missing leading slash: ISFILE("SPF.DIR/"<<NAME)
|
Always returns FALSE
|
Add / at start of literal |
Missing extension: NAME = "MY_SUB"
|
Returns FALSE even when file exists |
Append .SPF when assigning the variable |
Backslashes from a Windows HMI: NAME = "MY\\SUB.SPF"
|
Returns FALSE
|
Force forward slashes when writing to the GUD from the HMI |
| Trailing whitespace in the GUD | Path mismatch | Trim before writing or use the trimmed-assignment pattern below |
The CALL Instruction: Indirect Program Invocation
CALL in NC syntax expects a program identifier token. Because the NCK parser first performs variable substitution and then looks up the resulting name in the local program memory, you can pass a string variable directly:
CALL NAME ; where NAME is a DEF NCK STRING[32] = "MY_SUB.SPF"
The semantics are exactly those of a static CALL MY_SUB.SPF:
- NCK pushes the current program counter onto the internal subprogram stack.
- Program counter is reloaded to the first line of the named subprogram.
- On reaching
M17orRET, control returns to the saved line of the caller.
Up to 8 nested subprogram calls are supported in standard NCK 4.5; NCK 4.7+ extends this to 12 when using 828D sl in compact mode. The depth is consumed by both static CALL and CALL <var> identically.
CALL vs EXTCALL — Do Not Confuse Them
| Aspect | CALL | EXTCALL |
|---|---|---|
| File location | Local NC program memory (SPF.DIR) |
External medium: CF card, network share, USB, /USER/SINUMERIK/...
|
| Path syntax | Program identifier only (e.g. MY_SUB.SPF) |
Full path string (e.g. "//NC/SPF.DIR/MY_SUB.SPF") |
| Active / passive FS | Active | Passive (file is read on demand) |
| Indirect by variable | Yes — primary use case in this article | Yes, but the path must be a complete STRING literal or variable |
| Typical use | In-house cycles, recipes, gcode fragments | Loading large programs, version-controlled libraries on a server |
| Block search behavior | Standard | Block search may rewind to the EXTCALL line |
If your subprogram lives in the active SPF.DIR of the NC, use CALL. If the file is on the CF card or a network share, use EXTCALL with the full passive-FS path. The original Siemens wording — “EXTCALL is a separate instruction with a different meaning” — is the rule to remember.
Complete Working Example
The following MAIN.MPF shows the full pattern: read a program name from the operator (or set it elsewhere), validate it, dispatch to it, and loop if the file is missing.
; =============================================
; MAIN.MPF — dynamic subprogram dispatcher
; Requires GUD4.DEF with NAME (STRING[32]), ISNAME (BOOL)
; =============================================
; --- Default value (replace from HMI or PLC as needed) ---
NAME = "DRILL_CYCLE_42.SPF"
BACK: ; branch target for re-entry
ISNAME = ISFILE("/SPF.DIR/" << NAME)
IF ISNAME == FALSE
; --- the file is missing ---
; Option A: hard fault (raise alarm)
; SETAL(65000, "Subprogram not found")
; Option B: re-prompt (in production, drive NAME from HMI/PLC)
GOTO BACK
ENDIF
; --- the file exists, dispatch ---
CALL NAME
; --- back here after M17 / RET ---
G0 X0 Y0 Z100 ; safe position
M30 ; program end / rewind
Notes on the snippet:
-
SETAL(65000, ...)is an OEM alarm; you may replace the number with a free alarm in your machine builder range (typically 65000..99999). -
GOTO BACKinside aMAINloop is fine; the NCK keeps the subprogram return stack empty in that branch because we never called. -
M30at the bottom ensures a clean program reset on the nextCYCLE START.
String Handling: Length, Trimming, and Special Characters
The default STRING[32] can hold exactly 32 bytes. When a value shorter than 32 characters is assigned, the remainder is padded with BLANK (space, hex 0x20). Two consequences:
-
ISFILE()does not treat trailing blanks as significant — the OS-level lookup ignores them — so an assignment likeNAME = "DRILL"followed by manual padding to 32 chars in the HMI still resolves correctly. - When you concatenate with
<<inISFILE("/SPF.DIR/" << NAME), the trailing blanks are appended to the path.ISFILE()normalizes this;CALL NAMEdoes not, and will fail to find a subprogram whose displayed name has trailing spaces (highly unusual, but possible on older HMIs).
To be defensive, normalize at the entry of the dispatcher:
; Optional safety: left-justify and strip trailing blanks
NAME = NAME ; identity assignment forces evaluation
; Some HMI writes append blanks; CALL with blanks is tolerated,
; but EXTCALL would not. Stick to local NC memory and CALL.
Error Codes and Alarms You Will See
| Alarm | Trigger | Remedy |
|---|---|---|
| 12080 Channel %1 error in instruction name |
CALL is misspelled (e.g. CALLNAME with no space) or the variable has not been declared in any GUD |
Confirm DEF NCK STRING[32] NAME in GUD4.DEF; check spelling |
| 12050 Channel %1 address %2 is not defined | Variable referenced before its GUD is loaded; or wrong GUD number is active | Verify the active GUD set in Start-up > Define; trigger a power-on reset |
| 12750 Channel %1 error in GUD file GUD%2.DEF | Syntax error in the DEF statement (missing semicolon, mismatched bracket, type unknown) |
Open the file in Define and let HMI reformat; check the line number in the alarm clear info |
| 12030 Channel %1 invalid or illegal subprogram call | Target subprogram does not exist (the ISFILE check was skipped or returned stale result) |
Re-run ISFILE immediately before the CALL; do not cache across GOTO spans when the HMI is allowed to edit NAME
|
| 14095 Channel %1 string too long | Concatenation result exceeds 32 chars | Resize the GUD to STRING[64] or STRING[128] (NCK 4.8+) |
| 15370 Channel %1 program not found |
EXTCALL was used by mistake for a local SPF
|
Switch to CALL NAME
|
STRING[64] is the cheapest fix and does not require reloading any user data block.Block-Look-Ahead, LookAhead, and the Safe Place to Dispatch
The NCK reads ahead up to ~1000 lines of NC code so that it can pre-compute path velocity. A CALL <var> statement can be processed by the look-ahead, but the contents of the called subprogram can NOT — they are only loaded once the subprogram counter advances. Two practical rules:
- Place the
CALLin the same line where the operator changes a tool or a work offset, so that the look-ahead has no motion to mis-compute across the jump. - Do not place a
CALL <var>inside a motion block. Use its own line.
Commissioning Procedure (Step by Step)
-
Write the GUD. On the HMI, go to Start-up > NC > GUD and create/append to GUD4.DEF:
Activate with Set active and confirm the HMI shows the values in the Parameters soft key.DEF NCK STRING[32] NAME DEF NCK BOOL ISNAME -
Drop a test subprogram. Upload
TEST_DYN.SPFinto NC active / Subprograms / SPF.DIR via the HMI file manager. Verify it appears under Program Manager > NC active > Subprograms. -
Load MAIN.MPF. Use the dispatcher code from the previous section. Replace
NAME = "DRILL_CYCLE_42.SPF"withNAME = "TEST_DYN.SPF"for the first test run. -
Single-block run. In AUTO > SBL ON, hit CYCLE START. The
ISFILEcheck returnsTRUEandCALL NAMEdispatches. Verify the controller enters the subprogram by looking at the program level display in the HMI status bar. -
Negative test. Change the assignment to
NAME = "DOES_NOT_EXIST.SPF"and reload.ISFILEmust returnFALSE; the GOTO branch should re-prompt (orSETALshould raise the alarm). -
HMI integration. Add a string input field on the operator screen and bind it to
NAMEover the OPC UA / NC variable interface. The string must be a valid.SPFname before the operator can press CYCLE START. - End-to-end. Drive 3–5 different subprograms from a recipe and confirm the subprogram stack is clean (no alarm 14000 series when the cycle ends).
Field-Proven Caveats and Notes
-
Case sensitivity: the NCK file system is case-sensitive on NCU software ≥ 4.5.
drill_cycle_42.spfandDRILL_CYCLE_42.SPFare different files. - GUD activation: changes to GUD files are applied on the next NCK reset or power-on. A RESET alone is not always sufficient on 828D; perform an NCK reset from Start-up > NCK reset.
-
PLC string length: when an S7-1500 / S7-1200 writes into
NAMEthrough the NC variable interface, the PLC must always send 32 bytes, even if the textual name is shorter. Trailing blanks are required so the NCK does not keep the previous content. -
Cycle 840D sl Powerline vs Solutionline: syntax is identical. Behaviour around alarm 15370 differs slightly — Powerline raises it on any external medium; Solutionline is more permissive. Either way, prefer
CALLfor files in local memory. -
Simultaneous channels:
DEF NCKsharesNAMEacross channels. If two channels dispatch concurrently, the value seen by the other channel may already have changed. UseDEF CHANif each channel must hold its own selection. -
Operator security: the dispatcher pattern can call any file in
SPF.DIR. Restrict operator write access to theNAMEGUD to a curated list — otherwise a malicious or curious operator canCALLtool-change or measurement cycles outside the intended flow.
FAQ
Can I pass a subprogram name to CALL using any string variable in SINUMERIK?
Yes, provided the variable is declared in an active GUD with at least STRING[32] scope and the value is a valid .SPF identifier that exists in the local SPF.DIR. Use CALL <name> rather than EXTCALL for local files.
What is the difference between CALL and EXTCALL on SINUMERIK?
CALL calls a subprogram from the local NC program memory (active file system, SPF.DIR). EXTCALL loads a program from the passive file system on the CF card, USB, or network drive, and requires a full path string. Indirect dispatch by string variable works with both, but for this pattern the target usually lives in SPF.DIR, so CALL is correct.
Why does ISFILE always return FALSE on my NCU?
The most common cause is a missing leading slash in the literal, a missing .SPF extension in the variable, or backslashes introduced by a Windows HMI. Verify with a test path such as ISFILE("/SPF.DIR/DRILL_CYCLE_42.SPF") first; if that returns TRUE, the issue is in your concatenation, not the function.
What alarm indicates that the subprogram does not exist at runtime?
Alarm 12030 Invalid or illegal subprogram call or alarm 15370 Program not found is raised when CALL is executed with a target that is not in SPF.DIR. The dispatcher should run ISFILE() immediately before CALL to prevent this.
Can I concatenate a folder and a file name inside the GUD string?
Yes, using the NC string concatenation operator <<. For example ISFILE("/SPF.DIR/" << NAME). Do not rely on the OS to interpret relative paths; always use an absolute path starting with / and the appropriate .DIR segment.
How deep can nested CALL chains go?
Standard NCK software supports 8 nested CALL levels. NCK 4.7+ extends this to 12 on compact 828D sl configurations. The depth is shared between static and dynamic (CALL <var>) calls.