Overview
The Siemens SINUMERIK 802D sl custom-screen runtime executes XML-defined screens on the operator panel. The XML instruction set includes <let>, <op>, <print>, <function>, <function_body>, and <control> tags. The HMI parser supports references to NCK setting data, NCK machine data, channel parameters, R parameters, GUD variables, and PLC data blocks, plus the NCK-PLC exchange area conventionally starting at VB49000000.
This reference covers three recurring engineering tasks that appear across 802D sl commissioning projects:
- Defining Global User Data (GUD) variables and sizing the machine-data arrays that control the GUD count.
- Mirroring GUD values into the PLC data block DB20 so that ladder logic can read or write them.
- Transferring floating-point values between the custom HMI and the PLC using the double-word (DBD) access path and the
VB49000000exchange area.
The reference also documents the <function>/<function_body> tag pair used to create subroutines, the let/op/print base instruction set, and the file-system workaround for the documented STRING-GUD critical-error condition on firmware versions prior to 06.06.04.
Prerequisites
- SINUMERIK 802D sl control with the HMI Programming Package (ConfigDesign or HMI-Advanced sl configuration tool) installed on the engineering workstation.
- PLC firmware compatible with the GUD mirror block DB20 (toolbox PLC 06.06.xx or later recommended).
- NCU access level "Service" (or manufacturer) to edit machine data and GUD definition files in
/_N_DEF_DIR/. - Read/write permission on the HMI project directory, typically
/user/sinumerik/hmi/, to deploy the custom screen XML. - STEP 7 / S7-200 MicroWIN tool for PLC-side verification of DB20 offsets and the VB49000000 exchange area.
- For STRING GUD write: 802D sl firmware 06.06.04 or later, or a working file-system cover-cycle alternative.
Custom-Screen XML Tag Reference
Each custom screen is a single XML file placed in the HMI project tree. The tags form a small instruction set executed in interpreter order; the parser evaluates <let> declarations first, then walks the screen in document order, executing <op>, <function>, <print>, and rendering <control> blocks.
| Tag | Role | Example |
|---|---|---|
| <let> | Declare a local variable with explicit type and optional initial value. | <let name="result" type="FLOAT">0.0</let> |
| <op> | Execute an arithmetic or assignment operation, including path references like gud/... and plc/.... |
<op> result = "plc/db1000.dbd0" * 2 </op> |
| <print> | Format and emit text to the HMI info line. | <print text="value %f"> result </print> |
| <function> | Call a function body or a predefined library function by name. | <function name="my_calc"/> |
| <function_body> | Define a named subroutine that can be invoked by <function>. |
<function_body name="my_calc"> ... </function_body> |
| <control> | Render an HMI widget (input field, label, button, list) and bind it to a path or local variable. | <control name="f1" xpos="20" ypos="20" refvar="plc/db1000.dbd0"/> |
Local types supported inside <let> include INT, FLOAT, DOUBLE, STRING, and BOOL. The FLOAT type is implemented in 802D sl firmware 06.06.xx and later; older reference manuals only list INT and DOUBLE for script-local floats, but FLOAT works on shipping firmware.
GUD Definition Files and Syntax
Global User Data are defined in plain-text *.DEF files stored on the NCU file system under /_N_DEF_DIR/. The most common location is SGUD.DEF (Siemens-defined default GUD), which is loaded automatically at NCK startup. Customer-specific definitions can also be created in MGUD.DEF, UGUD.DEF, or in GUD4.DEF through GUD9.DEF.
Definition line syntax follows the pattern:
DEF <area> <type> [<access-read>] [<access-write>] <name>[<array-dim>] ; comment
| Token | Meaning | Common values |
|---|---|---|
| area | Validity scope of the GUD. | NCK (global), CHAN (per channel) |
| type | Data type. | INT, REAL, DOUBLE, BOOL, CHAR, STRING, AXIS, FRAME |
| access-read (APR) | Access level required to read. | 0 (Siemens), 1 (user), 2...7 (custom) |
| access-write (APW) | Access level required to write. | 0 (Siemens), 1 (user), 2...7 (custom) |
| name | Variable identifier; leading underscore convention indicates Siemens-defined names. | User-defined, case-sensitive |
| array-dim | Optional array dimension in square brackets. |
[16], [32]
|
Example SGUD.DEF block:
; Siemens GUD defaults
DEF NCK INT APR 7 APW 0 _GC_PARR[32] ; global integer parameters
DEF CHAN REAL APR 1 APW 1 _CH_RPAR[16] ; per-channel real parameters
DEF NCK STRING APR 1 APW 1 _WP_NAME ; workpiece program name
DEF NCK INT APR 1 APW 1 _SPINDLE_SPEED ; spindle speed reference
Important constraint on STRING-type GUD: writing a STRING GUD from a custom-screen XML control on 802D sl firmware prior to 06.06.04 raises a critical HMI error and restarts the HMI. The same control binding to an INT or DOUBLE GUD operates normally. The workaround section below provides a file-system-based method that is independent of the STRING GUD handler.
Machine Data for GUD Array Sizing
The maximum number of user-defined variables per data type is controlled by machine data. The field report cites the legacy 802D numbering N14504/N14506/N14508, which correspond to the modern 802D sl MDs 14510/14512/14514. The standard Siemens identifier is $MN_USER_DATA_INT/HEX/FLOAT (older docs use $MN_MAXNUM_USER_DATA_*). Verify the actual MD number on the installed firmware using the HMI startup screen's machine data browser before commissioning.
| Source MD reference | Standard 802D sl MD | Identifier | Default | Description |
|---|---|---|---|---|
| N14504 $MN_MAXNUM_USER_DATA_INT | MD14510 $MN_USER_DATA_INT | UserDataIntCount | 0 | Maximum number of INT GUDs. |
| N14506 $MN_MAXNUM_USER_DATA_HEX | MD14512 $MN_USER_DATA_HEX | UserDataHexCount | 0 | Maximum number of HEX/BOOL GUDs. |
| N14508 $MN_MAXNUM_USER_DATA_FLOAT | MD14514 $MN_USER_DATA_FLOAT | UserDataFloatCount | 0 | Maximum number of REAL/DOUBLE GUDs. |
_N_OSTART or power-on). The values take effect only after the next warm restart. Persistence is controlled by saving the active NCK data via the _N_SAVE_MD PI service or the HMI menu Commissioning > Save Data.Example MD adjustment to reserve 16 REAL GUDs and 32 INT GUDs:
MD14510 USER_DATA_INT = 32
MD14512 USER_DATA_HEX = 0
MD14514 USER_DATA_FLOAT = 16
; After write:
PI: _N_OSTART
; Persist:
PI: _N_SAVE_MD
; Verify:
DIAGNOSIS > GUD ; should show _GC_PARR[0..31], _CH_RPAR[0..15]
Diagnostic verification: open MENU SELECT > DIAGNOSIS > GUD on the operator panel. The screen lists every defined GUD, its current value, and the symbolic offset it occupies inside DB20. The order in the diagnostic screen matches the order of definition in the *.DEF file.
Mapping GUD to PLC Data Block DB20
Once GUDs are defined and the count MDs are sized, the current values are mirrored into PLC data block DB20. The NCK computes the offset layout inside DB20 at startup. The HMI GUD diagnosis screen reports the symbolic offset; STEP 7 symbolic notation can be used to address them once the DB20 symbolic file is imported.
Offset rules of thumb:
- INT and HEX GUDs occupy 4 bytes each (DBD width) in the DB20 mirror, even though their nominal width is 2 bytes. This is a known 802D sl quirk that simplifies alignment for the double-word access path.
- REAL and DOUBLE GUDs occupy 8 bytes (two DBDs) each, with the value aligned to the lower 4 bytes.
- STRING GUDs occupy 32 bytes each (16 characters + 16-byte header).
For example, if _GC_PARR[1] is the first INT GUD, the value is typically accessible at DB20.DBB0 (byte), DB20.DBW0 (word), or DB20.DBD0 (double word). For REAL (4-byte float) GUDs, always use the DBD offset.
Reading the float GUD in STEP 7 STL:
; STL snippet
L DB20.DBD 0 ; load REAL from offset 0
T MD 100 ; transfer to flag area
; or directly:
L DB20.DBD 0
T DB100.DBD 0 ; mirror to user DB
Writing from the PLC back into the GUD is done by writing to the same DB20 offset:
L MD 110
T DB20.DBD 12 ; write to GUD at offset 12
*.DEF file is corrupted or syntactically invalid, the DB20 offsets may be empty or shifted. Always check the NCK startup log (under DIAGNOSIS > STARTUP LOG) for GUD-related warnings before trusting DB20 values. Common errors: missing semicolon terminator, mismatched brackets, lowercase keywords, or duplicate variable names across SGUD/MGUD.Accessing GUD Variables from a Custom Screen
Inside an 802D sl custom screen, GUD variables are addressed using the path syntax:
gud/<variable_name>
The path is case-sensitive. The leading underscore is part of the identifier and must be included. Example assignments and bindings:
<!-- Read GUD INT into a local variable -->
<op> my_int = "gud/_GC_PARR[1]" </op>
<!-- Read GUD REAL into a local variable -->
<op> my_real = "gud/_CH_RPAR[5]" </op>
<!-- Bind a control directly to a GUD INT -->
<control name="field_int" xpos="20" ypos="40" width="100"
refvar="gud/_GC_PARR[1]" />
For REAL display, the control must declare the DISPLAY_FORMAT attribute to force float formatting; without it, the HMI may render the value in scientific notation or as a raw hex word, depending on the active HMI locale and the user-key setting.
<control name="label1" xpos="32" ypos="23" height="36" width="80"
fieldtype="readonly" refvar="gud/_CH_RPAR[5]"
DISPLAY_FORMAT="FLOAT" hotlink="true" />
PLC Float Transfer to a Custom Screen
Floating-point values stored in the PLC cannot be addressed using a "float" type in the custom-screen path syntax. The correct access is the double-word (DBD) form. For example, the REAL stored at DB1000.DBD0 is referenced as:
plc/db1000.dbd0
Assigning to a local FLOAT variable in the XML script:
<let name="db_displ" type="FLOAT">1.0</let>
...
<op> db_displ = "plc/db1000.dbd0" </op>
<print text="db_displ %f"> db_displ </print>
Displaying in a control with a label bound directly to the PLC DBD address:
<control name="label1" xpos="32" ypos="23" height="36" width="80"
fieldtype="readonly" refvar="plc/db1000.dbd0"
DISPLAY_FORMAT="FLOAT" hotlink="true" />
Notes on float handling:
- The local variable type
FLOATin<let>is not officially documented in older 802Dsl reference manuals but is implemented in firmware 06.06.xx and later. UseDOUBLEfor wider compatibility if a precision loss is acceptable. - Always use
DISPLAY_FORMAT="FLOAT"on controls bound to a DBD; otherwise the value is rendered as integer. - If the float is read but appears wrong (e.g., value is doubled, halved, or zero), verify the byte order. 802D sl uses little-endian (Intel) byte order, which matches STEP 7 default. If the source is a third-party PLC emulator, the byte order may need to be byte-swapped in the script before use.
- For negative values, ensure the source REAL in the PLC is stored as IEEE-754 single precision (32-bit). 802D sl does not automatically convert fixed-point or BCD representations to IEEE-754 float.
Function and Function_Body Tags
The <function> and <function_body> tags implement subroutines in the custom-screen XML instruction set. A function body defines a named block of instructions, and a function call executes it.
Defining a function body
<function_body name="my_function">
op result = "nck/channel/parameter/r[1]" * 3
print text="result %f" result
</function_body>
Calling a function
<function name="my_function" />
Common use cases:
- Encapsulating repetitive math on GUD or PLC values.
- Wrapping
doc.writetofileordoc.readfromfilecalls to log data to the NC file system. - Implementing a "Reset" or "Initialize" routine that resets several GUDs to default values.
- Building a state-machine step that advances based on a PLC handshake bit.
Predefined functions delivered with the HMI include string operations (string.length, string.sub), math operations (math.abs, math.sqrt), file I/O (doc.writetofile, doc.readfromfile), and time/date utilities (time.now, date.format). These can be invoked directly without a function_body.
Let, Op, and Print Instruction Set
The base instruction set used inside a custom screen is composed of three primary tags plus the <function>/<function_body> pair.
| Tag | Purpose | Attributes / example |
|---|---|---|
| <let> | Declare a local variable with type and initial value. |
name="x" type="FLOAT" → <let name="x" type="FLOAT">0.0</let>
|
| <op> | Execute an arithmetic or assignment operation. | <op> x = "plc/db1000.dbd0" * 2 + 1 </op> |
| <print> | Emit formatted text to the HMI info line. | <print text="x=%f"> x </print> |
| <function> | Call a function body or library function. | <function name="my_calc"/> |
| <function_body> | Define a named subroutine. | <function_body name="my_calc"> ... </function_body> |
Format specifiers follow C printf conventions: %d for int, %f for float/double, %s for string, %x for hex. A variable declared with <let> is scoped to the screen (and any embedded function bodies). It is not persistent across screen transitions; to persist, write to a GUD or to a PLC DB.
String GUD Workaround Using the NC File System
On 802D sl firmware prior to 06.06.04, attempting to write a STRING-typed GUD from a custom-screen XML control raises a "critical error" and restarts the HMI. The same control binding to an INT or DOUBLE GUD operates normally. The recommended workaround is to write the desired string (typically a part-program file name) to a known MPF file using the doc.writetofile predefined function, then have a cover cycle read that file and CALL the program by name.
Example XML fragment to write a dynamic file:
<!-- line feed constant -->
<let name="LF" type="string">\n</let>
<!-- m30 program terminator -->
<let name="M30" type="string">M30</let>
<let name="cover_cycle_content" type="string"></let>
<let name="pname" type="string"></let>
...
<op> cover_cycle_content = pname + LF + M30 + LF </op>
<function name="doc.writetofile">
_T"\mpf\wp_call.mpf", cover_cycle_content
</function>
...
<control name="cprog_name" xpos="440" ypos="190" width="100"
type="string" refvar="pname"/>
The cover cycle program wp_call.mpf then reads the file name and calls it:
; wp_call.mpf
DEF STRING[32] WP_NAME
WP_NAME = "selected.mpf" ; or read from a GUD / PLC byte stream
CALL "selected.mpf"
M30
This approach avoids the STRING GUD critical error and works on all 802D sl firmware versions because the file system API is independent of the GUD string handler. The cost is one extra NC file write per selection; the file is on the NCK compact flash and survives power cycle.
Exchange Area VB49000000 (NCK-PLC HMI Data)
The NCK-PLC exchange area is a memory region visible to both NCK and PLC, conventionally starting at VB49000000 in 802D sl projects. This area is bidirectional and survives power cycle (when the relevant MD is configured for retentive behavior). It is the recommended channel for transferring data between a custom HMI screen and the PLC when:
- The data does not need to be visible inside the part program (use GUD/setting data instead).
- The PLC is the data owner and the HMI is presenting it.
- Bit-level handshake signals are required alongside a multi-byte payload.
- High-frequency updates are needed and the NCK GUD write path is too slow.
Standard layout convention (verify against the actual 802D sl toolbox project before committing):
| Address | Length | Direction | Typical use |
|---|---|---|---|
| VB49000000–VB49000015 | 16 B | HMI → PLC | User-data input from custom screen |
| VB49000016–VB49000031 | 16 B | PLC → HMI | User-data output to custom screen |
| VB49000032–VB49000033 | 2 B | HMI → PLC | Handshake bits (toggle, ack, request) |
| VB49000034–VB49000047 | 14 B | reserved | Per project |
Reading a float from the exchange area in a custom screen:
<op> my_float = "plc/vb49000000.dbd0" </op>
Writing a float into the exchange area:
<op> "plc/vb49000000.dbd0" = my_float </op>
Handshake convention — HMI sets bit, PLC acks:
; Custom screen side
<op> "plc/vb49000032.0" = 1 </op>
; ... wait for ack ...
<op> my_ack = "plc/vb49000033.0" </op>
; PLC side (STL)
U E 32.0 ; HMI request bit
S A 100.0 ; set internal acknowledge
U A 100.0
R E 32.0 ; clear HMI request once read
On the PLC side, the exchange area is typically declared in the symbol table as a P-bus data block (or addressed as V-memory on the 802D sl toolbox PLC). Verify the byte order, which is little-endian on 802D sl and matches STEP 7 / MicroWIN conventions.
Commissioning Procedure
- Plan the GUD array sizes: count the INT, REAL/DOUBLE, and HEX/BOOL variables you need. Add 20% headroom for future extensions.
- Edit the appropriate
*.DEFfile (start withSGUD.DEF) and add theDEFlines with correct access levels (APR/APW) and a comment. - Set MD14510/14512/14514 to the planned counts. Trigger
PI _N_OSTARTand verify no startup alarm is logged. Save withPI _N_SAVE_MD. - Open DIAGNOSIS > GUD on the HMI and confirm every defined variable appears with its symbolic offset inside DB20.
- From STEP 7, add a watch table on DB20 at the reported offsets. Cycle NCK power and verify the values are mirrored correctly.
- Create the custom-screen XML. Use
DISPLAY_FORMAT="FLOAT"on any control bound to a REAL or DBD. Validate the XML externally before deployment. - Test the round trip: change the value in a control, confirm it appears in DB20, modify from PLC, confirm it appears on the HMI.
- For string transfer, prefer the file-system cover-cycle pattern. If the firmware supports STRING GUD writes (06.06.04+), still test the critical-error path under fault conditions before relying on it in production.
- For high-frequency or PLC-owned data, use the VB49000000 exchange area with a handshake bit pair.
- Document every GUD, its units, and its range in the project commissioning log. Train operators on access levels so that write-protected variables cannot be modified from the HMI.
Troubleshooting Matrix
| Symptom | Likely cause | Verification | Resolution |
|---|---|---|---|
| HMI restarts when writing a STRING GUD | STRING GUD critical error on firmware < 06.06.04. | Check NCK version on HMI startup screen. | Use file-system cover cycle (write to wp_call.mpf). |
| DB20 shows zeros for all GUDs | GUD definition file failed to load. | DIAGNOSIS > STARTUP LOG. | Fix syntax, reload GUD via _N_OSTART. |
| DB20 offsets shifted by 4 bytes | Forgot an INT GUD declared as HEX (or vice versa). | Compare DIAGNOSIS > GUD with the .DEF file order. | Recompute offsets, update STEP 7 symbolic file. |
| Float displayed as integer or scientific | Missing DISPLAY_FORMAT. |
Inspect control attributes in the deployed XML. | Add DISPLAY_FORMAT="FLOAT". |
| Float value doubled or shifted | Wrong byte offset or wrong DB. | Cross-check with HMI GUD diagnosis. | Correct DBD offset; verify endianness. |
| Memory reorganization alarm on MD change | Modifying GUD-count MDs during production. | Check alarm log after NCK start. | Schedule change during downtime; NCK reset. |
| Function call has no effect | Function name mismatch (case-sensitive). | Verify function_body name attribute. |
Match name exactly, including underscore prefix. |
| Custom screen does not load | XML syntax error (unbalanced tag, illegal character). | HMI log on operator panel. | Validate XML with an external parser; correct tag balance. |
| Control shows old value |
hotlink not enabled or NCK not updating. |
Toggle hotlink="true". |
Set hotlink="true" on the control. |
| GUD write from PLC has no effect | DB20 offset wrong or write-protected GUD. | Check APW access level in the .DEF file. | Adjust access level in DEF; verify offset. |
| HMI shows 0.0 for all REAL controls | Wrong DBD width used (e.g., DBW instead of DBD). | Inspect the path syntax in the control. | Use .dbdN for REAL, never .dbwN. |
| STRING GUD reads back garbage | Mirror expects 16-char fixed format but source is variable. | Check actual string length on the HMI. | Pad or truncate the source string to 16 chars. |
| Exchange area updates lost on power cycle | VB area not configured retentive. | Check PLC retentivity flags. | Set the relevant PLC retentive flag for VB49000000 range. |
Best Practices
- Always declare
DISPLAY_FORMAT="FLOAT"on controls bound to REAL or DBD addresses. - Reserve the GUD-count MDs at commissioning; changing them in production causes memory re-layout.
- Use a cover cycle (file-system approach) for any dynamic string transfer; do not depend on STRING GUD write support.
- Encapsulate repetitive logic in
function_bodyblocks; the screen XML is much easier to maintain and to unit test in isolation. - For high-frequency data, prefer the exchange area
VB49000000over GUD, because GUD write goes through NCK processing and can be slow at 100 ms+ cycle times. - Use symbolic comments in the
*.DEFfile to document each variable's intent, units, and valid range. - Validate any custom-screen XML externally before deploying to the HMI to catch unbalanced tags.
- Configure access levels (APR/APW) so that operator-level users can read but not modify critical GUDs.
- Keep a GUD cross-reference table: column = GUD name, column = DB20 offset, column = STEP 7 symbolic name. Update it whenever the .DEF file changes.
- Use
hotlink="true"only on controls that genuinely need real-time update; it costs CPU on every NCK tick.
How do I create a new GUD variable in 802Dsl?
Edit SGUD.DEF (or MGUD/UGUD/GUD4…GUD9) in the /_N_DEF_DIR/ path, add a line like DEF NCK INT APR 1 APW 1 _MY_VAR ; comment, ensure MD14510/14512/14514 are sized appropriately, then trigger an NCK reset (PI _N_OSTART) and save (PI _N_SAVE_MD). The value becomes accessible in PLC DB20 and from custom screens via gud/_MY_VAR.
Why does writing a STRING GUD restart the HMI?
On 802D sl firmware versions prior to 06.06.04, the custom-screen HMI STRING GUD write path raises a critical handler error. The reliable workaround is to write the desired string to a known MPF file using the doc.writetofile predefined function and have a cover cycle read and CALL the resulting part program. Alternatively, upgrade the firmware to 06.06.04 or later.
How do I display a PLC float in a custom screen?
Bind the control to the double-word address, for example refvar="plc/db1000.dbd0", and add DISPLAY_FORMAT="FLOAT" to the control tag. For script-side use, assign to a <let name="x" type="FLOAT"> local and reference it in <op> or <print> with the %f format specifier.
Where do I find the DB20 offset for a specific GUD?
Open the HMI diagnosis screen (MENU SELECT > DIAGNOSIS > GUD) and inspect the symbolic offset list, or read the NCK startup log where the offset is reported. The offsets are computed from the GUD count MDs (MD14510/14512/14514) and the order of definitions in the *.DEF file. INT and HEX GUDs each occupy 4 bytes in the mirror; REAL and DOUBLE each occupy 8 bytes.
What is the exchange area VB49000000 used for?
It is a shared memory area between the NCK and the PLC, used to exchange data that does not need to appear in the part program. Custom screens can read/write it using plc/vb49000000.dbd0 syntax. Reserve a handshake-bit pair (for example VB49000032.0 and VB49000033.0) to confirm data acceptance on both sides.
How do function_body and function tags work together?
<function_body name="X"> defines a named subroutine in the screen XML. <function name="X"/> invokes that subroutine from anywhere in the screen, including inside other function bodies. Predefined library functions such as string.length or doc.writetofile can be called with the same <function> tag without a corresponding function_body block. Names are case-sensitive.