WinCC Unified V17 IO Field Tag Limits: Step-by-Step Configuration

David Krause18 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

WinCC Unified V17 (part of the SIMATIC WinCC Unified PC-based and Unified Comfort Panel HMI system) exposes every faceplate-style screen object — including the IO field — to a tightly integrated tag database. The IO field can be bound to a single HMI tag, a tag from a connected PLC, or a script-driven expression, and it can be configured as an input/output, input only, or output only element. The question most engineers hit during the first commissioning is deceptively simple: "How do I take a tag from my PLC and put it into the IO field, and how do I apply min/max limits to it?"

This reference walks through the entire chain — from declaring the PLC tag, exposing it on the HMI side, binding it to the IO field, and applying value-range clamping. It also addresses the well-known limitation that built-in min/max limit fields in the tag properties are silently rejected for complex data types (arrays, structures, byte strings) and for the elementary 8-bit data type Byte. For those cases, the article details a deterministic script-based clamping pattern using the OnChange of the process value and the OnInputFinished event.

Throughout the article the term PLC tag refers to any tag that originates in the S7-1200, S7-1500, ET 200SP, S7-300/400, or third-party controller that is reachable through the SIMATIC HMI connection, and the term HMI tag refers to the WinCC Unified internal tag that is the binding surface for IO fields, scripts, animations, and logging.

Prerequisites

Before the IO field will accept a PLC tag and respect a value clamp, verify the following engineering baseline:

  1. TIA Portal V17 Update 4 or later is installed on the engineering station. Unified Comfort Panels require matching firmware (V17.x) to load the project without compatibility downgrade warnings. See the Siemens TIA Portal V17 release notes for the exact build identifiers.
  2. WinCC Unified V17 runtime is installed on the panel or on the Unified PC station. The minimum firmware for the MTP700/MTP1000/MTP1200/MTP1500/MTP1900/MTP2200 Unified Comfort Panels is V17.0.0.0; later feature packs added faceplate improvements that are not strictly required for this workflow.
  3. The HMI connection between the panel and the controller is configured (S7-1200/1500, S7-300/400, Modbus TCP, OPC UA, or a third-party driver). Confirm the connection is online in the TIA project tree under Devices & Networks.
  4. The PLC tag is declared with a simple, scalar, signed integer or real data type (recommended: Int, DInt, LInt, Real, or LReal). If the tag is an array or a UDT, the built-in limit is silently ignored — this is the core constraint that drives the script-based solution described below.
  5. The IO field is configured with "Output/Input" mode under Properties > General > Mode if the operator is expected to write back to the controller.
Design note: An IO field bound directly to a PLC tag in Unified V17 uses a process-image read/write. The cycle is governed by the configured acquisition cycle (default 1 s) for read and an event-driven write on the operator's commit action. Tightening the acquisition cycle to 100 ms is allowed but must be done sparingly — Unified Comfort Panels warn at 250 ms or below for S7-1200/1500 connections on panels in the MTP700/MTP1000 class because of the CPU-side resource cost.

Built-in Tag Limit Configuration (Scalar Tags)

For scalar tags whose data type is in the supported list — Int, DInt, LInt, UInt, UDInt, ULInt, Real, LReal — the IO field limit is configured directly in the HMI tag properties and is enforced by the runtime. The configuration is performed in the TIA Portal HMI tag editor.

  1. In the project tree, expand HMI > HMI tags and double-click the tag to open its properties.
  2. Select Properties > Range in the inspector window.
  3. Enter the low limit and the high limit. The IO field will reject any operator entry outside the range and raise a system alarm 300205 ("Value outside the limits of the tag").
  4. Compile and download the HMI. The new range takes effect at the next runtime start.
HMI tag data type Built-in min/max accepted? IO field honors the clamp? Notes
SInt / Int / DInt / LInt Yes Yes Default if not configured: full signed range of the type.
USInt / UInt / UDInt / ULInt Yes Yes Range defaults to 0..max-of-type.
Real / LReal Yes Yes Real comparison honors NaN by always failing the bound check.
Bool No No (use check box) Use a checkbox or toggle, not an IO field.
Byte / Word / DWord / LWord Partially Often ignored Byte limits are silently rejected by the HMI tag editor in many V17 builds; use USInt instead.
String / WString No No String length is bounded by tag configuration, not by an arithmetic limit.
Array of … No No No "Apply limits" button is shown for arrays; use script or expose element tags.
UDT / struct No No No compound limit; use member-level tags or scripts.

The crucial line in the matrix is the Array of Real row. TIA Portal V17 simply does not render the range fields for array HMI tags — the controls are grayed out — and any attempt to use an array tag as the IO field's Process value without a clamp script allows the operator to write a value of 9.9E+30 directly into the controller's data block. This is the failure mode described in the original engineering report.

Root Cause: Why Complex Tags Reject Built-in Limits

WinCC Unified's tag editor binds the "Range" UI to a single scalar value descriptor in the tag's metadata block. An HMI tag whose data type is Array[0..15] of Real carries a metadata block that is structurally identical to a C array descriptor — a base address, an element type, an element count, and a stride — and the V17 tag property sheet does not have a widget that captures one pair of (low, high) limits for the whole array. Internally, the editor would have to either:

  • store one limit per element (which would make the configuration dialog quadratic in the array length and would not survive a tag-type change), or
  • store a single (low, high) pair and silently apply it to every element (which would be misleading if the user actually wants per-element ranges).

Siemens chose the conservative path: the range UI is hidden whenever the tag's data type is not a scalar integer or real. The same suppression applies to the Byte type in V17 — a regression carried forward from the early V16 unified builds — even though Byte is conceptually a USInt. The fix in the V17 service pack train was to use USInt explicitly if you need unsigned 8-bit semantics with a range check.

Engineering takeaway: If a tag carries a built-in clamp, the runtime refuses to write a value outside the clamp and logs a system alarm. If the tag does not carry a built-in clamp, the runtime writes the value verbatim to the controller. Always confirm the clamp is active by deliberately entering an out-of-range value in the simulation table of TIA Portal before going on-machine.

Solution Strategy Overview

Three pragmatic strategies are available to the engineer. They are listed in order of preference.

Strategy Where the clamp lives Best use case Downsides
1. Expose array element tags HMI tag (per element) Small fixed-size arrays, stable structure Many tags to maintain; renaming the array breaks the bindings.
2. Script on the IO field JavaScript in the screen Variable-length arrays, derived bounds, alarms to the operator More code to maintain; clamp is not enforced at the HMI tag level.
3. Clamp in the PLC S7-1500 SCL or ladder Hard process limits (e.g. 0..10 bar on a pressure transmitter) Operator does not see why an entry was rejected unless the PLC also raises an alarm.

For most production cells, strategy 1 (expose element tags) is the most maintainable: bind the IO field to a single Real element tag that already has a built-in range, and let the array simply stay a passive buffer in the controller. If the array is large and the IO field needs to walk through it (an indexed recipe, a tuning array, a multi-point setpoint table), strategy 2 (script-based clamping) is the right answer. Strategy 3 should be reserved for the cases where the clamp is a hard process safety limit and not a UI convenience.

Strategy 1: Expose Array Element Tags

Suppose the controller exposes a data block DB_Recipe with an array:

// S7-1500 SCL
DATA_BLOCK "DB_Recipe"
  STRUCT
    Temperature : ARRAY[1..10] OF REAL;  // °C, 0..250
    Pressure    : ARRAY[1..10] OF REAL;  // bar, 0..10
  END_STRUCT;
END_DATA_BLOCK

In the TIA Portal HMI tag editor, create ten HMI tags HMI_Recipe_Temp_01 through HMI_Recipe_Temp_10 with PLC address %DB17.DBX0.0 (Real) for index 1, then +4 bytes for each subsequent element. Configure the range on the HMI tag as 0..250.0. Bind the IO field to HMI_Recipe_Temp_01 directly. The runtime will reject any out-of-range entry and the IO field will stay within the safe window.

Tip: When the array length is small and the recipe is stable, the per-element-tag approach is more robust than a script because the clamp survives a screen re-load, a script compile error, or a faceplate dynamic instantiation. The cost is one extra HMI tag per array element.

Strategy 2: Script-Based Clamping (Array of Real)

When the array is large, when the bounds are derived, or when the IO field index changes dynamically, the cleanest solution is to add a JavaScript to the IO field that clamps the entered value. The recommended events are "Input finished" for an operator-driven clamp, and "Process value change" for a controller-driven clamp.

Step-by-step: Bind the IO field to the array element

  1. Open the screen in the WinCC Unified editor.
  2. Drag an IO field from the toolbox onto the canvas.
  3. In Properties > General > Process value, bind the IO field to the HMI tag of the array element. If you do not have a per-element tag, bind to the array itself — the array is read/write in V17 even though it cannot carry a built-in clamp.
  4. Set the mode to "Output/Input".
  5. Switch to the Events tab in the property sheet.

Event 1 — "Input finished" (operator commit)

This is the right place to validate what the operator typed before the value is written to the controller. The event fires when the operator leaves the IO field (Tab, Enter, focus loss, or screen change). The script receives the entered value as a parameter.

// WinCC Unified — JavaScript on the IO field "Input finished" event
// Clamp the entered Real value to the range [MIN, MAX] and re-display the result.
// 'item' is the IO field screen object, 'value' is the operator-entered value.

var MIN = 0.0;       // °C, lower process limit
var MAX = 250.0;     // °C, upper process limit
var rounded = Math.round(value * 10) / 10;   // 0.1 °C display resolution

if (isNaN(rounded)) {
    HMIRuntime.Trace("IO field rejected NaN entry");
    item.OutputValue = MIN;
    return;
}
if (rounded < MIN) {
    HMIRuntime.Trace("IO field below MIN: " + rounded);
    item.OutputValue = MIN;
    return;
}
if (rounded > MAX) {
    HMIRuntime.Trace("IO field above MAX: " + rounded);
    item.OutputValue = MAX;
    return;
}

// Value is in range — accept it
item.OutputValue = rounded;

The key line is item.OutputValue = …. Writing back to OutputValue forces the IO field to display the clamped value, which the operator will see as an automatic correction. If you also need to write the corrected value into the controller tag, follow this with Tags("HMI_Recipe_Temp_NN").Write(rounded);.

Event 2 — "Process value change" (controller side)

If the controller is the source of the value (a sensor, a calculated setpoint, a parameter that the PLC updates periodically), the clamp must run on every read cycle. Attach a script to Process value change of the IO field:

// WinCC Unified — JavaScript on the IO field "Process value change" event
// Reject out-of-range values coming from the controller and re-display the clamped one.

var MIN = 0.0;
var MAX = 250.0;
var v = Tags("HMI_Recipe_Temp_NN").Read();   // current value from the controller

if (v < MIN) v = MIN;
if (v > MAX) v = MAX;

item.OutputValue = v;

This pattern is deterministic: the script runs on every acquisition cycle, the IO field shows the clamped value, and the operator can never see a transient that violates the range. The downside is that it makes the screen busier than necessary if the controller is already well-behaved — in that case, do not attach a script to "Process value change" and rely on the controller-side clamp instead.

Optional: Surface the violation as an alarm

When the operator has typed a value outside the range, silently rewriting it to the limit can be confusing. A common improvement is to raise a system alarm so the operator understands what happened:

// inside the "Input finished" script, after detecting an out-of-range entry
var now = new Date();
HMIRuntime.Alarming.CreateSystemInformation(
    "IO field clamp",
    "Entered value " + rounded + " was clamped to [" + MIN + ", " + MAX + "] at "
    + now.toLocaleTimeString()
);

The CreateSystemInformation function adds a single-line entry in the alarm log without triggering an audible horn, which is the right escalation level for a UI-side correction.

Strategy 3: Clamp in the PLC

For process safety limits (for example, a hydraulic pressure that must never exceed the relief-valve setpoint), the clamp belongs in the PLC, not in the HMI. In an S7-1500 SCL block, the pattern is:

// S7-1500 SCL — write-side clamp for an array of Real
FUNCTION_BLOCK "FB_RecipeClamp"
VAR
    i : INT;
END_VAR
BEGIN
    FOR i := 1 TO 10 DO
        IF "DB_Recipe".Temperature[i] < 0.0 THEN
            "DB_Recipe".Temperature[i] := 0.0;
        ELSIF "DB_Recipe".Temperature[i] > 250.0 THEN
            "DB_Recipe".Temperature[i] := 250.0;
        END_IF;
    END_FOR;
END_FUNCTION_BLOCK

Call FB_RecipeClamp in a cyclic OB (typically OB1 or OB35) so the array is always bounded. The HMI's IO field then becomes a passive display — the operator can still type whatever, but the controller will overwrite it within one cycle. This is the safest pattern for limit values that have a real process consequence.

Verification Procedure

After the configuration is downloaded, run the following verification steps on the panel (or in the Unified PC simulation):

  1. Scalar tag with built-in range. In the IO field, type a value above the configured high limit. The runtime must reject the entry, leave the previous value displayed, and raise system alarm 300205 in the alarm log.
  2. Scalar tag with built-in range, low side. Type a value below the configured low limit. The runtime must reject the entry.
  3. Array element with no built-in range, script clamp on "Input finished". Type a value above the script's MAX. The IO field must immediately show MAX. Inspect the alarm log for the CreateSystemInformation entry.
  4. Array element with no built-in range, script clamp on "Process value change". Force the controller tag to an out-of-range value (use the watch table). The IO field must show the clamped value within one acquisition cycle.
  5. Boundary values. Enter exactly MIN, exactly MAX, MIN+0.1, MAX-0.1. All four must be accepted.
  6. NaN / empty string. Clear the IO field, leave it empty, then leave focus. The script must substitute MIN and not crash.

Troubleshooting Matrix

Symptom Likely root cause Fix
Range fields in tag properties are grayed out Tag is an array, UDT, or Byte Use scalar member tag or attach a clamp script
Out-of-range entry is accepted HMI tag has no built-in range and the IO field has no "Input finished" script Add the script in Properties > Events > Input finished
Script fires but the value still goes through Script writes to item.OutputValue but the IO field is bound to a different tag than the one being clamped Confirm Process value binding matches the tag referenced in Tags(...).Read/Write
Alarm 300205 fires constantly Controller is writing out-of-range values faster than the operator can correct them Move the clamp into the PLC, or attach a script on Process value change as well
NaN appears in the IO field Controller wrote an uninitialized real; IO field displays NaN Add an isNaN check in the script and substitute MIN
Tag not visible in the IO field tag picker Tag has not been compiled into the HMI, or the connection is offline Recompile the HMI; check Devices & Networks for the connection status
IO field accepts the value but the controller shows the old value Acquisition cycle is too long, or the controller's optimized block access prevents the write Reduce the acquisition cycle; ensure the PLC tag is declared "Accessible from HMI" or that the DB is non-optimized for S7-1200/1500 with absolute addressing
Faceplate shows the IO field without a clamp The faceplate is using a typed wrapper that swallows the Input finished event Use strategy 3 (PLC-side clamp) for faceplate-bound fields, or rebuild the faceplate to expose the event

Engineering Notes and Field Caveats

Real number comparison. Never compare two Real values with == in the JavaScript; use a tolerance (e.g. Math.abs(a - b) < 1e-6). This is especially relevant when the IO field's display format is rounded to one decimal place but the underlying Real is at full precision.

Acquisition cycle vs. operator write. A write to a PLC tag from the IO field is event-driven; a read is cycle-driven. If the acquisition cycle is 2 s and the operator enters a clamped value, the next read may briefly show the old controller value before the new one settles. The fix is to also write the clamped value to the tag in the script, so the next read returns the same value the operator sees.

Locales and decimal separators. The IO field respects the project's configured decimal separator. In a German project the separator is , and the script's Math.round(value * 10) / 10 will still work because it operates on the numeric value, not the string. If the script is doing string manipulation, force parseFloat(value.replace(',', '.')) first.

Bulk tags from third-party controllers. When the controller is a non-Siemens PLC (Allen-Bradley, Beckhoff, Codesys, Modbus), the HMI tag is often created as a "raw" tag without a data type. The Acquisition mode in the tag properties must be set to Cyclic continuous (not On demand) for the IO field's "Process value change" event to fire predictably. See the Siemens SIMATIC HMI connection manual for driver-specific guidance.

Optimized block access on S7-1500. An optimized DB hides the absolute addresses that the HMI tag editor wants to use. Either uncheck Optimized block access on the DB, or use the symbolic address (the data block name and tag name) in the HMI tag's PLC address field. Optimized DBs are the recommended pattern in TIA Portal V17, so prefer the symbolic approach.

Audit trail. The Input finished script runs in the Unified runtime, not in the controller, and therefore is not part of the S7-1500 audit trail. If the recipe values are regulated (e.g. pharmaceutical batch records), use strategy 3 (PLC-side clamp and PLC-side audit log) instead of an HMI script.

Quick Reference: Tag Data Type and Limit Support

PLC tag type Bound to IO field directly? Built-in range usable? Recommended approach
Bool Yes (use checkbox) No Toggle / checkbox
Int, DInt, LInt Yes Yes Set range in tag properties
Real, LReal Yes Yes Set range in tag properties
Byte Yes Often ignored Use USInt for clamping
Array of Real Yes (whole array) No Per-element tag or script clamp
UDT/struct Yes (whole struct) No Per-member tag or script clamp
String Yes No (length only) Set string length in tag properties

Summary

Putting a PLC tag into a WinCC Unified V17 IO field is a one-line binding under Properties > General > Process value. Applying a min/max clamp to that tag depends entirely on the tag's data type: scalar integer and real tags accept the built-in range fields and reject out-of-range entries with system alarm 300205; arrays, UDTs, and Byte tags do not. For arrays, the pragmatic answers are to expose per-element HMI tags (and use the built-in range), to attach a JavaScript to the IO field's Input finished or Process value change event that clamps to the desired window, or to push the clamp into the PLC and treat the IO field as a passive display. Whichever strategy is chosen, the verification procedure above must be executed on the live panel before the screen is released to operations.

Why is the "Range" section in my HMI tag properties grayed out?

The tag's data type is not a scalar integer or real. WinCC Unified V17 hides the range fields for Array, UDT, String, and the Byte type. Use a per-element HMI tag, an USInt-typed tag, or a clamp script attached to the IO field event.

How do I apply a min/max limit to an IO field bound to a Real tag?

Open the HMI tag's Properties > Range and enter the low and high values. Compile and download the HMI. The runtime will reject any out-of-range operator entry and raise system alarm 300205. For Array of Real tags, attach a JavaScript to the IO field's Input finished event that clamps value to the desired window and writes the result back via item.OutputValue = ….

Why does the operator-entered out-of-range value get written to the controller anyway?

The HMI tag carries no built-in clamp (because it is a complex type or a Byte) and the IO field has no Input finished script. Add the clamp script shown above, or move the clamp into the PLC. Confirm with a deliberately invalid entry in the watch table that the value is rejected before going on-machine.

Can the IO field's clamp be enforced from the controller side?

Yes. In an S7-1500 SCL function block, run a FOR loop over the array and overwrite out-of-range elements on every cycle (or on every write). The IO field then becomes a passive display. This is the recommended pattern for process safety limits and for regulated audit trails.

Where can I find the official documentation for the "Input finished" event and item.OutputValue?

The WinCC Unified V17 scripting reference is included in the TIA Portal Help under WinCC Unified > Programming Reference > JavaScript API > Screen items > IO field. The full system manual is also available on the Siemens Industry Online Support portal under the WinCC Unified V17 product page.

Back to blog