Overview
SINUMERIK 840D controllers emit alarm 12550 ("Channel %1 Block %2 identifier %3 not defined or option not installed") when a defined GUD, macro, LUD, or program name is referenced in an NC block but is not present in the active scope. On a lathe retrofit running Cycle 95 / CYCLE97 thread-cutting, the alarm typically points at the channel-global array _C97_NR[11] declared in GUD7.DEF. The cycle cannot resolve a spindle-to-machine-axis mapping, so downstream calls into _C97_NR[n] fail with 12550 at NC-Start. This reference covers the diagnostic path for that specific failure, the machine-data checks that underpin it, and the recovery sequence for restoring CYCLE95 / CYCLE97 operation without reloading the entire cycle pack.
Siemens documents the general meaning of alarm 12550 in the SINUMERIK MC alarms catalog (SINUMERIK 840D sl / ONE). The catalog entry confirms that the alarm fires when a definable identifier (macro, GUD, LUD, program name, or program block) is referenced before it is defined, or when an option bit required for that identifier is not installed. The remediation logic described below resolves the most common field cases of the _C97_NR variant on 840DE retrofit hardware.
Alarm 12550 Reference
| Field | Value |
|---|---|
| Alarm number | 12550 |
| Alarm text (literal) | Channel %1 Block %2 identifier %3 not defined or option %4 is not installed |
| Reaction | NC-Start inhibit, alarm display, interface signals are not set |
| Acknowledgement | RESET (clear alarm with NCK reset, not just C-Reset) |
| Cause class | Error in the NC program / definition; configuration mismatch |
| Typical field triggers | Missing GUD, missing macro, missing cycle file, unloaded GUD, missing option bit, protection level higher than user authorization |
| Cancellation block (C) | Disables the block containing the undefined identifier so the operator can re-enter a corrected call |
Per the Siemens alarms catalog, the 12550 family fires only on identifiers that should exist; it is not an MD validity check. The check is performed by the interpreter against the symbol table populated at NCK power-on and after any explicit GUD reload. If the symbol exists but the value the cycle reads is 0 or the array element is empty (REP of the wrong default), the alarm will still appear, because the cycle passes the empty element back to a higher-level statement that calls it without first verifying validity.
Hardware and Software Environment
Documented from a real 840DE retrofit case (lathe X/Z spindle, threading CYCLE95 / CYCLE97):
| Item | Article number / version |
|---|---|
| NCU | NCU 571.3 — 6FC5357-0BB10-0AE1 |
| NCK software | 05.03.39 (840DE export line) |
| HMI / PCU | PCU 50 — software 06.04.21 |
| Standard cycles | 06.04.21 |
| Support cycles | 06.04.24 |
| Active cycle | CYCLE95 (call) → CYCLE97 (SPF) in _N_CST_DIR
|
| GUD file |
_N_GUD7_DEF in _N_DEF_DIR
|
GUD7.DEF issued with the 06.05.14.00 standard cycle pack (Dec 2004) is not necessarily compatible with NCK 05.03.39. Confirm that the DEF file timestamp (;CHANGE / ;VERSION lines) matches the standard cycle version on the CF card before modifying values.
The cycle file shown in the source contains the standard header banner ;VERSION: 06.05.14.00 Dec 07, 2004 while the loaded standard cycles on the controller are 06.04.21. Mismatched cycle/DEF versions are a frequent retrofit symptom: the user copies a newer CYCLE97.SPF from a development pack onto an older system. The interpreter then calls symbols whose GUD entries are not yet defined on the older NCK, which is the immediate trigger for 12550.
Root Cause Analysis
Three independent root causes converge on the same alarm text. Diagnose in this order:
-
Empty spindle lookup table.
CYCLE97builds_C97_NR[]dynamically by scanning all configured machine axes and storing$MA_SPIND_ASSIGN_TO_MACHAX[Ax]for each spindle-capable axis. If the lathe has only one main spindle but the spindle-to-axis assignment inMD 30500 / 30550 / 30350is missing or set to 0, the loop populates only_C97_NR[0] = 0(the initialREP(0)). Subsequent statements that address_C97_NR[1..5](e.g. for the counterspindle or the C-axis mapping) read a zero that was never written, and the interpreter raises 12550 on the GUD symbol referenced as the assignment target. -
GUD file not actually loaded. The DEF file is present on the CF card in
user/_N_DEF_DIR/_N_GUD7_DEFbut the active GUD set on the NCK is older. NCK reads the GUD set only at power-on or after an explicitPI service _N_GUD. A file-system update without an NCK reset is the most common field cause of "files are present, no data is visible in the parameter screen". -
Protection level. GUD definitions are stored under the current access level. The operator-level (level 4) and setup-level (level 3) parameter displays do not see definitions stored at the manufacturer (level 1) or service (level 2) level unless the password for that level is set.
CYCLE97reads_C97_NRat the protection level of the calling program (typically level 0 or 1), but the values defined in the GUD are written by the cycle at the access level of the active_C97_NR[0] = REP(0)statement. Mismatched levels cause the read to return an undefined symbol.
Diagnostic Procedure
-
Confirm the alarm block. On the HMI, read the alarm screen and note the channel, block, and identifier. The third parameter of alarm 12550 is the symbol that the interpreter cannot resolve. In the source case it is
_C97_NR(or_C97_NR[k]depending on the controller build). Compare the literal symbol against the symbol table. -
List GUDs from the HMI. Navigate to Startup > GUD (or Parameters > User Data depending on HMI build). Open
GUD7(channel-specific) and check that_C97_NR,_C97_AXNAM, and_C97are listed with the expected data type and array size. If the entries are missing entirely, the GUD file is not active. -
Inspect the live value. From the same GUD screen, open
_C97_NR[0]and read its value. A value of 0 indicates the cycle has just been initialized but has not yet populated the array. A value of 1, 4, or 5 indicates a real spindle number was assigned by$MA_SPIND_ASSIGN_TO_MACHAX. -
Check the active file system. Use HMI Startup > File System and confirm the active partition. On a 840DE the partition is normally
/card/user/.... The expected path for the GUD definition is/card/user/_N_DEF_DIR/_N_GUD7_DEFand for the cycle/card/user/_N_CST_DIR/_N_CYCLE97_SPF. -
Read the cycle version banner. Open
CYCLE97.SPFin the HMI editor. The first non-comment line should contain;VERSION:and;CHANGE:with a date. If the version date is newer than the loaded standard cycles (Startup > Version → Standard Cycles), you have a mixed version installation and the array layout in the DEF file may no longer match the cycle's expectations. -
Cross-check machine data. Verify
MD30350 $MA_SPIND_ASSIGN_TO_MACHAX[AX1]andMD30350 $MA_SPIND_ASSIGN_TO_MACHAX[AX2]. Both must be non-zero for a lathe that uses one main spindle and one C-axis. A value of 0 for one of them causes the FOR loop in CYCLE97 to skip the affected index, leaving_C97_NR[1] = 0and triggering 12550 on a later reference. - Check option bits. Some cycles are option-gated on 840DE export systems. In Startup > Licenses > Options, confirm that the threading option (commonly listed as "Thread cutting") is enabled. A missing option shows up in alarm 12550's fourth parameter ("option %4 is not installed").
Machine Data Verification
The spindle-to-axis assignment is the most common single point of failure. The following MDs must be set in a coordinated way for CYCLE97 to populate _C97_NR correctly:
| MD | Name | Typical value (lathe) | Purpose |
|---|---|---|---|
| MD20070 $MC_AXCONF_MACHAX_USED[0..n] | Machine axis number used in channel | 1, 2, 3, 4 (one per configured axis) | Declares which physical machine axes are present in the channel. CYCLE97 loops over this list to find spindles. |
| MD20080 $MC_AXCONF_CHANAX_NAME_TAB | Channel axis name | X, Z, SP, C | Names the channel axes. CYCLE97 writes these into _C97_AXNAM[] after the spindle is found. |
| MD30350 $MA_SPIND_ASSIGN_TO_MACHAX[Ax] | Spindle number assigned to machine axis | 1 (main), 2 (counterspindle), 3 (C-axis) | The CYCLE97 read source. If 0, the loop skips the axis. |
| MD30500 $MA_INDEX_AX_ASSIGN_POS_TAB | Indexing axis assignment | 0 (off) for non-C axes, 1+ for C axis | Establishes whether an axis can act as a spindle when commanded as such. |
| MD30550 $MA_AXCONF_ASSIGN_MASTER_CHAN | Master channel of axis | 1 (current channel) | Determines the channel ownership for the axis/spindle. |
| MD35000 $MA_SPIND_ASSIGN_TO_AC_AXIS | Spindle assignment to AC axis | 0 or 1 | On drives with a 1:1 spindle-to-drive mapping, this is the deciding bit for CYCLE97. |
| MD38010 $MC_MM_NUM_SPINDLES | Number of spindles | 1 to 4 | Allocates runtime memory for spindle structures. Must be ≥ the highest index used in 30350. |
Read the live values with MD > Display MD on the HMI. For a retrofit on 840DE export, MD38010 is frequently left at the default 1 even when the mechanical scope includes a counterspindle. CYCLE97 then writes _C97_NR[1] = 0 (because no second spindle is allocated) and downstream blocks that address _C97_NR[1] raise 12550. Increasing MD38010 to 2 (or 3) and re-powering is the fix.
GUD File Verification
The GUD file GUD7.DEF declares the symbol table that the cycle writes into. The relevant block from the source case is:
;$PATH=/_N_DEF_DIR
;VERSION: 06.05.14.00 Dec 07, 2004
;CHANGE : 06.05.11.00 Oct 28, 2003
APR 11 APW 11
N10 DEF CHAN INT _ZSD[10]=0
N20 DEF CHAN REAL _C97[4]
N30 DEF CHAN INT _C97_NR[11]=SET(1,0,0,0,0,4,0,0,0,0,1)
N40 DEF CHAN STRING[8] _C97_AXNAM[5]=SET("C")
N50 DEF CHAN REAL _CONT2[10]
N51 DEF NCK INT _SC_MASK[10]=SET(0,0,0)
N300 REDEF $MC_TOOL_CARRIER_RESET_VALUE APR 7 APW 7
Three structural checks apply to this file:
-
Attribute match (APR / APW).
APR 11 APW 11sets the read and write access level to 1 (manufacturer). The cycle's write statements are at the level of the running program. If the running program has access level 4 (operator) and the GUDs are at level 1, the cycle fails to write. The standard fix on a retrofit is to change APR/APW to 7 (operator read, operator write) or to match the calling program's level. TheREDEFline for the tool carrier reset must also keep the new level (hereAPR 7 APW 7). -
Initial values. The
SET(1,0,0,0,0,4,0,0,0,0,1)initializer primes the array with two non-zero entries (index 0 = 1, index 5 = 4) so the cycle has a valid starting point before the FOR loop overwrites the spindle entries. If this initializer is corrupted (e.g. truncated toSET(0,0,0,0,0,0,0,0,0,0,0)), the cycle cannot resolve_C97_NR[0]after the first overwrite pass. -
Array sizes.
_C97_NR[11]matches an 11-slot layout expected by the CYCLE97 implementation at 06.05.14.00. A copy of an older or newer DEF file (e.g. 10-slot or 12-slot) desynchronizes the cycle's addressing and raises 12550 on slot 10 or 11. Re-extract the file from the matching standard-cycles archive before editing.
Cycle 97 Code Analysis
The interpreter block that drives the 12550 alarm is the spindle-search loop at the head of CYCLE97:
KK=0
_C97_NR[0]=REP(0)
_C97_AXNAM[0]=REP("")
_AXZAHL=$ON_NUM_AXES_IN_SYSTEM-1
SBLOF
FOR II=0 TO _AXZAHL
JJ=$MC_AXCONF_MACHAX_USED[II]
IF JJ<>0
IF $MA_SPIND_ASSIGN_TO_MACHAX[AXNAME("AX"<<JJ)]<>0
_C97_NR[KK]=$MA_SPIND_ASSIGN_TO_MACHAX[AXNAME("AX"<<JJ)]
_C97_NR[KK+5]=JJ
_C97_AXNAM[KK]=$MC_AXCONF_CHANAX_NAME_TAB[II]
KK=KK+1
ENDIF
IF (KK>_SPIZAHL)
GOTOF _END_SPISUCH
ENDIF
ENDIF
ENDFOR
_END_SPISUCH:
Two key observations from this block:
-
REP(0)andREP("")are valid initializers but the entries they write are *not* real spindle numbers. The block is intended to clear the array before the search. If the FOR loop never finds a valid$MA_SPIND_ASSIGN_TO_MACHAXvalue (because all the MD entries are 0), the array stays atREP(0). CYCLE97 then tries to assign_C97_NR[0] = 0to a local variable of typeINT, and the interpreter (depending on build) raises 12550 on the symbol because the runtime binding is "defined as zero, not undefined at this point". -
SBLOFsuppresses single-block stop inside the loop, so the alarm is reported against the calling program block (the CYCLE95 call), not against lineSBLOF. The operator sees the alarm at the CYCLE95 call site, which is why the alarm message is reported as "_C97_NR not defined" even though the cycle 95 source is correct.
Resolution Procedure
-
Back up the active GUD and the cycle file. In HMI Startup > GUD > Save to export the current GUD set. Use File System > Copy to copy
CYCLE97.SPFandCYCLE95.SPFto a USB stick before any change. -
Verify machine data for the spindle assignment. Set
MD30350 $MA_SPIND_ASSIGN_TO_MACHAXfor the main spindle axis to 1, and for the C-axis (or counterspindle axis, if used) to 2 or 3 as applicable. If a second spindle is mechanically present, raiseMD38010 $MC_MM_NUM_SPINDLESfrom 1 to 2 (or 3) so the runtime can address the extra index. -
Reload the matching DEF file. Copy the
GUD7.DEFfrom the standard-cycles archive that matches the running cycle version (06.04.21). Do not edit the array initializers or the array sizes by hand unless the cycle is also updated. The file must reside at/card/user/_N_DEF_DIR/_N_GUD7_DEF. -
Adjust the access levels. In the DEF file header, change
APR 11 APW 11toAPR 7 APW 7(or to the access level of the calling program). TheREDEFline for the tool carrier reset must be updated to the same level. Save the file on the HMI. -
Trigger an NCK reload. Either power-cycle the NCU (proper way) or use the HMI Startup > GUD > Activate to force a reload. The PI service
_N_GUDexecutes the same effect without a power cycle but requires service-level access. -
Clear the alarm and test. Press NC-Reset to clear 12550, then run a dry motion in JOG on the spindle (no thread). Run a single CYCLE95 call with a short thread (e.g. 1 mm pitch, 1 mm thread length) to confirm
_C97_NR[0]and_C97_NR[1]populate correctly. Read them back from Parameters > GUD > GUD7 — the values should now show 1 and 2 (or whatever the MD assignment is), not 0.
Verification and Commissioning
After the fix, run a verification matrix to confirm the cycle behaves across the lathe's operating envelope:
| Check | Expected behavior | Pass criterion |
|---|---|---|
| NC-Start of CYCLE95 with valid thread parameters | Cycle runs, 12550 does not appear | No 12550 in the alarm history |
Read _C97_NR[0..10] after CYCLE95 |
Index 0..n-1 populated with spindle numbers, rest zero | Indices match the configured spindles |
Read _C97_AXNAM[0..4] after CYCLE95 |
Names of the channel axes that carry a spindle | Names match MD20080 entries |
| Thread pitch and depth from CYCLE95 parameters | Output geometry matches the part program | Thread profile measured to drawing tolerance |
| Override ramp on the spindle during threading | Spindle speed is held, feed override inactive | Override has no effect inside the thread (per Siemens thread-cutting rules) |
| Dry run with rapid retract | Cycle returns to start without alarm | Return position matches start; no 12550 |
| Repeat the same CYCLE95 with multi-start threading |
NUMTH parameter honored |
Number of thread starts equals NUMTH |
Related Cycles and Common Variants
| Cycle | Function | Relation to _C97_NR
|
|---|---|---|
CYCLE95 (_N_CST_DIR/_N_CYCLE95_SPF) |
Contour turning with thread element support | Calls CYCLE97 internally for the thread passes; the 12550 on "cycle 95" is often actually raised inside CYCLE97. |
CYCLE97 (_N_CST_DIR/_N_CYCLE97_SPF) |
Thread cutting (single / multi-start, taper, run-in, run-out) | Owns the _C97_NR array and the FOR loop that builds it. |
CYCLE98 (_N_CST_DIR/_N_CYCLE98_SPF) |
Thread chaining (string of thread segments) | Reads _C97_NR as a continuation; same dependency on spindle MDs. |
CYCLE99 (_N_CST_DIR/_N_CYCLE99_SPF) |
Thread undercut / relief | Reads _C97_AXNAM for tool-side geometry. |
802D variant (_ktl_ alarm 12550) |
Similar CYCLE95 implementation on 802D / 802D sl | Same root cause (GUD not loaded, MD not set, option bit missing) but the symbol is _ktl_ instead of _C97_NR. |
For the 802D variant of the same failure, the symbol reported in alarm 12550 is _ktl_not (or _ktl_ followed by an index). The recovery sequence is the same: verify the GUD file is active, verify the spindle MD assignment, and verify the threading option bit. The 802D controller does not use the same DEF file naming, so do not copy a 840D GUD7.DEF across to an 802D platform — the GUD layout is different.
Troubleshooting Matrix
| Symptom | Likely root cause | First check | Fix |
|---|---|---|---|
12550 on CYCLE95 call, symbol _C97_NR
|
GUD not loaded | HMI > GUD > GUD7 | Re-copy GUD7.DEF, activate, NCK reset |
12550 on CYCLE95 call, symbol _C97_NR[1] specifically |
MD38010 = 1, second spindle not allocated | MD38010 value | Raise MD38010, power-cycle |
12550 on CYCLE95 call, symbol _C97_NR, array all-zero |
MD30350 = 0 for all axes | MD30350 for AX1..AXn | Set MD30350 to the spindle number for the spindle-capable axes |
| 12550 with fourth parameter non-zero ("option not installed") | Thread cutting option missing | Startup > Licenses > Options | Enable the threading option (license required) |
12550 on 802D controller, symbol _ktl_not
|
802D-specific GUD _ktl_ not loaded |
802D GUD editor | Re-copy the 802D DEF, activate |
| 12550 appears at the line after CYCLE95, not inside it |
SBLOF in CYCLE97 hides the source |
CYCLE97.SPF source | Diagnostic only — fix the underlying MD / GUD issue, alarm site will follow |
| 12550 clears on Reset but returns on every CYCLE95 call | DEF access level too high for operator program |
APR/APW in DEF header |
Change APR/APW to 7 (operator) in GUD7.DEF
|
12550 only on multi-start thread (NUMTH > 1) |
Array size insufficient, or _C97_NR initial SET missing slots |
CYCLE97 / GUD7 version match | Restore matching standard cycle and DEF pair |
FAQ
What does SINUMERIK alarm 12550 with identifier _C97_NR mean on a lathe retrofit?
Alarm 12550 fires when CYCLE97 (called internally by CYCLE95 for thread passes) cannot resolve the channel-global array _C97_NR[11] declared in GUD7.DEF. The most common cause is that the GUD file is not active on the NCK, or that MD30350 $MA_SPIND_ASSIGN_TO_MACHAX is 0, so the FOR loop inside CYCLE97 leaves the array empty.
How do I confirm that GUD7 is active on the NCK?
Open HMI > Startup > GUD, select the channel, and look for _C97_NR, _C97_AXNAM, and _C97. If the entries are missing, copy GUD7.DEF from the matching standard-cycles archive into /card/user/_N_DEF_DIR/ and trigger an NCK reset (or use the GUD Activate PI service with service-level access).
What machine data controls the spindle-to-axis mapping that CYCLE97 needs?
MD30350 $MA_SPIND_ASSIGN_TO_MACHAX is the decisive entry. It must be set to 1, 2, 3, or 4 for each machine axis that carries a spindle. MD20070 $MC_AXCONF_MACHAX_USED, MD20080 $MC_AXCONF_CHANAX_NAME_TAB, and MD38010 $MC_MM_NUM_SPINDLES are the supporting entries; raise MD38010 to at least the number of spindles the lathe actually has.
Why does alarm 12550 point at CYCLE95 even though the error is in CYCLE97?
CYCLE97 starts with the SBLOF (suppress single-block) command and the alarm is raised at the next interpreter check, which is the calling block in the part program (the CYCLE95 call). The alarm site therefore always reads as "cycle 95 block _C97_NR" even though the offending line is inside cycle 97.
Can a missing option bit cause alarm 12550 with identifier _C97_NR?
Yes. The fourth parameter of alarm 12550 reports the option bit number when the referenced identifier is option-gated. Thread cutting is an option on some 840DE export configurations. Enable the threading option in Startup > Licenses > Options and re-test. The 12550 catalog entry in the Siemens SINUMERIK MC alarms documentation confirms this is a valid trigger for the alarm.