802Dsl Custom Screen: GUD Variables and PLC Float Transfer

David Krause17 min read
HMI ProgrammingSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

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:

  1. Defining Global User Data (GUD) variables and sizing the machine-data arrays that control the GUD count.
  2. Mirroring GUD values into the PLC data block DB20 so that ladder logic can read or write them.
  3. Transferring floating-point values between the custom HMI and the PLC using the double-word (DBD) access path and the VB49000000 exchange 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.
Warning — Memory Reorganization: Changing any of these MDs forces an NCK memory reorganization. The NCK briefly becomes unavailable, any active part program is interrupted, and the entire GUD memory layout is re-computed. Schedule the change during commissioning downtime, not during production. After modification, perform an NCK reset (PI service _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
Critical: The GUD is mirrored into DB20 only after the NCK has processed the GUD definition file. If the *.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 FLOAT in <let> is not officially documented in older 802Dsl reference manuals but is implemented in firmware 06.06.xx and later. Use DOUBLE for 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.writetofile or doc.readfromfile calls 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

  1. Plan the GUD array sizes: count the INT, REAL/DOUBLE, and HEX/BOOL variables you need. Add 20% headroom for future extensions.
  2. Edit the appropriate *.DEF file (start with SGUD.DEF) and add the DEF lines with correct access levels (APR/APW) and a comment.
  3. Set MD14510/14512/14514 to the planned counts. Trigger PI _N_OSTART and verify no startup alarm is logged. Save with PI _N_SAVE_MD.
  4. Open DIAGNOSIS > GUD on the HMI and confirm every defined variable appears with its symbolic offset inside DB20.
  5. From STEP 7, add a watch table on DB20 at the reported offsets. Cycle NCK power and verify the values are mirrored correctly.
  6. Create the custom-screen XML. Use DISPLAY_FORMAT="FLOAT" on any control bound to a REAL or DBD. Validate the XML externally before deployment.
  7. Test the round trip: change the value in a control, confirm it appears in DB20, modify from PLC, confirm it appears on the HMI.
  8. 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.
  9. For high-frequency or PLC-owned data, use the VB49000000 exchange area with a handshake bit pair.
  10. 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_body blocks; the screen XML is much easier to maintain and to unit test in isolation.
  • For high-frequency data, prefer the exchange area VB49000000 over GUD, because GUD write goes through NCK processing and can be slow at 100 ms+ cycle times.
  • Use symbolic comments in the *.DEF file 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.

Back to blog