WinCC Tag Value Transformation: PLC, Scripts, Best Practices

David Krause18 min read
HMI / SCADASiemensTechnical Reference
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

WinCC Tag Value Transformation: PLC-Side Calculation vs Global Scripts vs Calculated Tags

Overview: The Tag Value Transformation Problem

SCADA and HMI deployments frequently require that a raw value read from a PLC be transformed before it is displayed, logged, or used in further calculations. Typical examples include unit conversion (raw counts to engineering units), polynomial compensation curves for sensors, lookup-table corrections for non-linear transmitters, encryption of operator-entered setpoints, and presentation logic such as f(x) = 2x + 1 where x is the raw tag from the controller.

WinCC V7.5, WinCC Professional (TIA Portal), and WinCC Unified V20 all expose multiple ways to apply such a function to a tag. Each method has a different impact on the runtime performance, the project lifecycle, and the long-term maintainability of the installation. The wrong choice leads to sluggish HMI updates, lost logging samples, and avoidable controller scan-time load. This reference describes every supported transformation path, quantifies the cost, and shows working code for each platform.

Engineering rule of thumb. Push the transformation into the PLC whenever the controller is under your control. Use WinCC-side transformation only when the PLC program is owned by a third party, locked, or when the transformation is purely a presentation concern (for example, "show the value with two decimal places") that is already handled by the I/O field format.

Tag Taxonomy in WinCC V7.5 and WinCC Unified

Before choosing a transformation method you must understand which tag classes are available in the platform you are running.

WinCC V7.5 Tag Types

Per the official WinCC V7.5 Working with WinCC manual (ID 109760739), every tag in the WinCC tag management belongs to one of the following data type classes:

Type Source Writes back to PLC? Typical use
External tag Process connection (S7, OPC, Modbus, etc.) Optional Raw I/O, setpoints, status words
Internal tag WinCC memory only No Intermediate results, recipe data, scripts
Calculated tag Formula evaluated by WinCC No Sum, average, count over a time window
Text tag WinCC memory only No Text lists, messages
Raw data tag Byte array from connection Optional Decoded by raw data manager

Calculated tags in V7.5 are limited to a fixed set of aggregate functions: sum, average, min, max, count, and a small number of conditional expressions. They are not an arbitrary-expression engine. A transformation such as f(x) = 2x + 1, a square root, or a polynomial correction does not fit inside the calculated-tag framework, so the engineer must use one of the methods described in sections 4 through 6.

WinCC Unified V20 Tag Types

Per the Configuring logging tags (RT Unified) reference, WinCC Unified separates the tag database from the data flow:

  • HMI tags – the variable in the WinCC Unified runtime database, can be internal or connected to a PLC via S7, OPC UA, Modbus TCP, or symbolic IO.
  • Logging tags – a tag that participates in the runtime logging database. A logging tag is always linked to an HMI tag; the link is configured in the editor table by clicking <Add> in the Name column.
  • Tags with limits – HMI tags that carry scalable or absolute limits (substitutes for V7.5 linear scaling).

WinCC Unified does not retain the V7.5 "Calculated tag" concept. Transformations in Unified are performed by JavaScript, by an expression in an I/O field, or by a derived tag whose value is updated through a scheduled script. The runtime is built on a JavaScript VM, which makes the scripting layer faster and more capable than the VBScript/C-Script engine used in V7.5.

Method 1: PLC-Side Calculation (Recommended)

Performing the transformation inside the PLC is the only option that is fully deterministic in terms of update rate and does not require any WinCC-side engineering effort beyond mapping a tag. For most installations this is the correct path. The WinCC tag simply reads the pre-calculated value through the existing connection.

Why PLC-Side is Fastest

  • The PLC task is cyclic and runs in OB1, an OB with a defined priority, or a watchdog OB. Every cycle, the new value is written to the process image and the next WinCC poll sees it.
  • There is no scripting language interpreter in the loop.
  • The result can be logged, archived, used by the PLC logic, and displayed on a third-party HMI simultaneously.
  • Diagnostic, alarm, and trending all use the same single source of truth.

Implementation in SCL on S7-1200/S7-1500

The following Structured Text code performs y = 2x + 1 in a cyclic OB. Drop it into TIA Portal V17 or later, compile, and download.

// FB_TagTransform: y = 2 * x + 1
// TIA Portal V18, S7-1500
FUNCTION_BLOCK "FB_TagTransform"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      i_rawValue : Int;     // raw tag from PLC, e.g. IW100
   END_VAR
   VAR_OUTPUT
      o_result : Int;       // transformed value written to WinCC
   END_VAR
   VAR_TEMP
      t_local : Int;
   END_VAR
BEGIN
   t_local := i_rawValue * 2;     // MUL saturates on S7-1500
   o_result := t_local + 1;       // ADD with overflow check
END_FUNCTION_BLOCK

Call the FB in OB1:

// OB1 - Main
"DB_Tag"(i_rawValue := "RawInput");
"WinCC_Tag" := "DB_Tag".o_result;

Implementation in STL on S7-300/S7-400

Classic STL implementation suitable for legacy controllers:

// FC_TagTransform: y = 2 * IW0 + 1, result in MW10
// STEP 7 V5.6, S7-314
FUNCTION FC1 : VOID
BEGIN
      L     IW0           // load raw input word
      L     2
      *I                  // signed 16-bit multiply
      L     1
      +I                  // signed 16-bit add
      T     MW10          // store result for WinCC
END_FUNCTION
Note on integer overflow. If the raw value can exceed 16383, switch the working registers to DInt and use *D / +D. For floating point work, use L with real literals, e.g. L 2.0, and the *R / +R instructions.

Implementation in TIA Portal LAD/FBD

For engineers who prefer graphical languages, the same operation fits in a single network with two boxes:

Network 1: y = 2*x + 1
--[ MUL_I EN=true IN1="RawTag" IN2=2 ]--[ ADD_I EN=true IN1="Result" IN2=1 ]--

Map the Result tag in WinCC as a normal external tag with the same address the PLC writes to.

Method 2: WinCC V7.5 Calculated Tags

Use calculated tags only when the transformation is one of the supported aggregate operations. They are evaluated by the WinCC data manager on a configurable cycle time (default 500 ms) and do not require any script.

Configuring a Calculated Tag in V7.5

  1. Open the Tag Management editor and select the connection under which the calculated tag should be created.
  2. Right-click and choose New Tag. Set the data type (e.g. Float) and switch the tag type to Calculated.
  3. Click the calculator icon. The formula editor supports the following tokens:
    • Aggregate functions: SUM(n, tag), AVG(n, tag), MIN(n, tag), MAX(n, tag), CNT(n, tag) – where n is the number of samples.
    • Arithmetic: +, -, *, /, parentheses.
    • Conditional: limited IF...THEN...ELSE support.
  4. Set the update cycle. A 1 s cycle with a 60-sample average on 1000 calculated tags is realistic; a 100 ms cycle on the same load is not.

Limits of Calculated Tags

Calculated tags cannot call a user-defined function, cannot perform a lookup, and cannot apply trigonometric or logarithmic operators. They are intended for trend-style aggregates, not for engineering-unit conversion. For f(x) = 2x + 1 the calculated-tag path is technically usable, but in practice engineers who reach for it usually discover that they also need clamp, hysteresis, and deadband logic, all of which require a script anyway.

Method 3: Global Scripts (VBScript / C-Script) in WinCC V7.5

Global scripts are the only path in V7.5 that supports arbitrary expressions on a tag. They execute in the WinCC background and write the result to an internal tag that the I/O field displays.

VBScript Example

Create a global VBS action that runs on a 1 s trigger:

' Module: modTagTransform
' Action: actTransformX
' Trigger: 1 second, standard cycle

Dim rawValue, result
rawValue = HMIRuntime.Tags("PLC_RawTag").Read
result   = 2 * rawValue + 1
HMIRuntime.Tags("WinCC_TransformedTag").Write result

C-Script Example

For installations that need higher throughput, C-Script compiles to native code and runs roughly 5-10x faster than equivalent VBScript.

/* Project module: modTagTransform */
/* Action: actTransformX, trigger 1 s standard cycle */

#include "apdefap.h"

BOOL actTransformX()
{
    DWORD   dwResult;
    LONG    lRaw;
    LONG    lOut;

    lRaw = GetTagWord("PLC_RawTag");
    lOut = (lRaw * 2L) + 1L;
    SetTagWord("WinCC_TransformedTag", (WORD)lOut);

    return TRUE;
}

Performance Cost of Global Scripts

Per the field experience documented in WinCC performance KB articles and Siemens support notes, a single VBScript action triggered at 1 s typically consumes 0.1-0.5 % of a single CPU core per action, depending on the number of tags read and written. The cost is not linear; actions share a script host, so a system running 200 one-second VBS actions on a four-core HMI runtime server can saturate the script host and starve the picture update path.

Performance warning. Never place a calculation in a global script if the value is read in a picture that has a fast update cycle (250 ms or less). The script will be queued behind the picture update and the operator will see stale data.

Picture-Level C-Script Alternative

When the transformation is used by a single picture and not by the rest of the project, attach a C-Script to the I/O field's Output/Input event. The script runs only when the picture is open, the script context is per-picture, and there is no global scheduling cost.

/* I/O field "iofTransformed", property "OutputValue", C-Script */
LONG lRaw = GetTagWord("PLC_RawTag");
return (SHORT)(lRaw * 2 + 1);

Method 4: WinCC Unified JavaScript Expressions

WinCC Unified V20 is built on a JavaScript runtime. Transformations can be written as scheduled scripts, as faceplate events, or as expressions attached directly to an I/O field. The JavaScript engine is single-threaded per context but JIT-compiled, so the cost per transformation is an order of magnitude lower than VBScript on V7.5.

Scheduled Script in WinCC Unified

Open the project tree, navigate to Scripts > Scheduled tasks, and add a new JavaScript task triggered every 1 s.

// Scheduled task: transformTag, trigger 1 s
const raw = Tags("PLC_RawTag").Read();
const result = 2 * raw + 1;
Tags("WinCC_TransformedTag").Write(result);

I/O Field Expression in WinCC Unified

On the Output property of an I/O field, bind a JavaScript expression instead of a tag. This evaluates synchronously on every picture update and does not require a separate tag.

// Expression on I/O field "iofTransformed"
const raw = Tags("PLC_RawTag").Read();
return 2 * raw + 1;

Limits Object in WinCC Unified

WinCC Unified supports scaling on the tag itself through the Limits object. This is a linear mapping only and is the right tool for raw-count to engineering-unit conversion. For a non-linear curve, use a JavaScript scheduled task that performs a lookup in a recipe data block.

Method Comparison Table

Criterion PLC-side V7.5 calculated tag V7.5 global script V7.5 picture C-script Unified JS scheduled Unified expression
Update latency PLC cycle (typ. 1-10 ms) Cycle time (typ. 500 ms) Cycle time (typ. 1 s) Picture cycle (typ. 250 ms) Schedule period (typ. 1 s) Picture cycle (typ. 100-250 ms)
CPU cost on HMI None Very low High (VBS), low (C) Low, scoped to picture Low (JIT) Low (JIT)
Supports non-linear Yes No Yes Yes Yes Yes
Logging compatibility Direct Direct Indirect (must be on internal tag) Indirect Direct (write to logging tag) Indirect
Third-party PLC support Yes if controller exists Yes Yes Yes Yes Yes
PLC program required Yes No No No No No
Skill required PLC engineer (STL/SCL/LAD) WinCC tag editor VBScript / C C-Script JavaScript JavaScript

Performance Impact Analysis

The discussion in the source thread raises a recurring concern: "avoid global scripts, they will slow down your system performance." The statement is correct in the context of WinCC V7.5, where the script host was a single-threaded VBScript interpreter shared with picture changes, alarms, and logging. In WinCC Unified the engine is JIT-compiled JavaScript, the script host is multi-context, and the cost is much lower. The decision still depends on the deployment scale.

Quantitative Sizing for V7.5

Empirical sizing rules for a single-core WinCC V7.5 Runtime on a typical IPC:

Transformation method Tag count Trigger Recommended max per HMI server
1 s VBS global action 10 tags read + 10 written 1 s 100 actions
1 s C global action 10 tags read + 10 written 1 s 2000 actions
Picture C-script (OutputValue) 1 tag read 250 ms 500 instances
Calculated tag n/a (aggregate) 500 ms 5000 tags

For reference, the same workload done PLC-side has effectively zero HMI CPU cost; the controller is the one doing the math.

Quantitative Sizing for Unified V20

Transformation method Trigger Recommended max per Unified server
Scheduled JS task 1 s 5000 tasks
Picture expression Picture update No hard cap; profile with stress test
PLC-side pre-compute n/a Unlimited

Best Practices and Field-Engineer Guidelines

  1. Default to the PLC. If you own the controller program, write the transformation in SCL, STL, or LAD and expose the result as a normal tag. This is the only option that is independent of the HMI brand and survives an HMI platform migration.
  2. One source of truth. Never calculate the same value in two places. If the PLC writes TransformedTag and a WinCC global script also writes TransformedTag, the last writer wins and the operator gets nondeterministic behavior.
  3. Use the limits object in Unified for linear scaling. Do not write a script to multiply by a constant; the Limits property of the HMI tag handles this with no runtime cost.
  4. Prefer picture C-script over global action. When the transformation is purely a display concern, attach the C-script to the I/O field. The action runs only when the picture is open, freeing background cycles.
  5. Avoid 250 ms global VBS actions. The cost of a 250 ms trigger on a heavily loaded V7.5 system is much higher than a 1 s trigger. Increase the trigger period to 1 s or 2 s and rely on the picture update cycle for the visual refresh.
  6. Profile before commissioning. Use the WinCC Performance Editor (V7.5) or the Unified ProDiag trace to measure the cost of every script before sign-off. A 5 % script-host load looks small until you add a faster picture cycle.
  7. Document the formula in the tag comment. Open the tag properties and write the formula and the unit into the comment field. The next engineer to read the project will not have to reverse-engineer the script.
  8. Validate against the PLC on a round-trip test. For every transformed tag, force a known PLC value, read the WinCC value, and confirm the result. Do this for the boundary values (0, max, negative, NaN for floats).

Step-by-Step: PLC-Side Implementation in TIA Portal V18

Prerequisites

  • TIA Portal V18 with S7-1500 CPU support package installed.
  • S7-1500 project already compiles and downloads.
  • WinCC Professional or WinCC Unified V20 project linked to the same TIA Portal project.

Procedure

  1. Open the TIA Portal project and navigate to Program blocks > Add new block > Function block. Name it FB_TagTransform, language SCL.
  2. Paste the SCL source from section 3.3 into the block and compile.
  3. In OB1, drag the FB onto a network and wire i_rawValue to the existing raw tag (for example, "DB_Process".iwRaw).
  4. Create a new global tag WinCC_Transformed in a data block or as a standalone tag. Wire the FB output to it.
  5. Compile and download to the CPU. Force the raw tag to a known value using the watch table and confirm that the new value appears in the online view of WinCC_Transformed.
  6. In the WinCC project, open the HMI tags editor and add a new tag with the connection to the same PLC, address the new WinCC_Transformed tag (DB number, byte offset, data type). Compile and download the HMI.
  7. Open the runtime, place an I/O field on a test picture, bind it to the new tag, and verify the displayed value matches the PLC value.

Verification

  • Force the raw tag to 0, expect transformed value 1.
  • Force the raw tag to 100, expect transformed value 201.
  • Force the raw tag to -50, expect transformed value -99.
  • Force the raw tag to the maximum positive value, confirm that overflow handling is correct (saturation or wrap, per the IEC 61131-3 standard configuration of the S7-1500).
  • Open the HMI diagnostic view, confirm that the tag update is at the picture cycle rate, not the global script cycle rate.

Troubleshooting Matrix

Symptom Likely cause Fix
Tag value flickers between two values PLC and global script both write the same tag Remove the script or remove the PLC write; keep one source
Displayed value is one step behind the PLC VBS global action on 1 s trigger while picture cycle is 250 ms Move calculation to PLC or use a C-script on the I/O field
WinCC Runtime unresponsive on startup Global action error stops the script host Open the WinCC diagnostics window, locate the action in red, fix the bug
Calculated tag shows ??? Formula references a tag that has not yet been updated Increase the start delay of the calculated tag or initialize the source tag
Unified expression returns undefined Read returned a null because the PLC connection dropped Add a null guard: if (raw === null) return 0;
HMI logs the raw value, not the transformed value Logging tag was bound to the raw external tag Rebind the logging tag to the internal/PLC tag that holds the result (per the Configuring logging tags (RT Unified) reference)

Migration Notes: V7.5 to Unified V20

When migrating a V7.5 project that uses global VBS actions for tag transformation to Unified V20:

  1. Inventory every global VBS action. Use the WinCC migration tool output as a checklist.
  2. Re-implement each action as a scheduled JavaScript task or as a tag expression. The HMIRuntime.Tags(...).Read and ...Write calls map to Tags("...").Read() and Tags("...").Write(...).
  3. Convert calculated tags to scheduled tasks if the formula uses non-supported operators.
  4. Keep linear scaling using the Limits object on the HMI tag; do not write a script for it.
  5. Run the migration tool, recompile, and validate the round-trip test for every transformed tag.

Edge Cases and Safety Considerations

  • Division by zero. Any formula that divides by the raw value must guard against x = 0. SCL does not raise a hardware exception; it returns 0.0 silently, which can be misinterpreted as a valid measurement.
  • NaN propagation in floating point. If the raw tag is a Real and the sensor is disconnected, WinCC may read NaN. A naive multiplication in the script will produce NaN for the result, which the I/O field displays as ######. Add an explicit check: if (!isFinite(raw)) return 0;.
  • Signed/unsigned mismatch. Mapping a signed Int to an unsigned Word in the tag editor silently truncates negative values. Always match the IEC data type to the PLC declaration.
  • Watchdog impact. A non-linear transformation that uses sqrt or log runs in microseconds on an S7-1500, but on an S7-300 with an OB1 time of 50 ms it can be 5-10 % of the cycle. Profile with the PLC's cycle-time monitor.
  • Operator write-through. If the I/O field is configured to write back, and the script writes the same tag on the same trigger, the operator's value will be immediately overwritten. Either use a different tag for the result or block the write-back path.

Summary Recommendation

For new projects, push the transformation into the PLC. For projects inherited from a third party, use a WinCC picture C-script in V7.5 or a JavaScript expression in Unified V20. Avoid global VBS actions except for very small scripts on a 1 s trigger. Use the V7.5 calculated-tag framework only for the aggregate functions it was designed for. Use the Limits object in Unified for linear scaling. The WinCC V7.5 Working with WinCC manual and the WinCC Unified V20 logging-tag reference are the authoritative starting points for any tag-engineering task.

FAQ

Can I apply f(x) = 2x + 1 to a WinCC tag without global scripting?

Yes. The best path is to perform the calculation in the PLC and expose the result as a separate tag; WinCC then reads a normal external tag. In WinCC V7.5, a picture-level C-script on the I/O field is the lightest HMI-side alternative. In WinCC Unified V20, bind a JavaScript expression to the I/O field's Output property.

Do global VBS scripts really slow down WinCC?

Yes, in WinCC V7.5 the script host is single-threaded VBScript and is shared with picture changes, alarms, and logging. A 1 s VBS action on ten tags typically costs 0.1-0.5 % of a CPU core per action; a few hundred actions will starve the picture update path. WinCC Unified V20 uses a JIT JavaScript engine, so the cost is much lower, but the PLC remains the recommended location for any calculation that drives multiple consumers.

What is the difference between a calculated tag and a global script in V7.5?

A calculated tag is a tag whose value is evaluated by the WinCC data manager on a configured cycle, using a fixed set of aggregate functions (sum, average, min, max, count) and basic arithmetic. A global script is a VBScript or C function that runs in the script host and can implement arbitrary logic. Calculated tags are very fast; global scripts are flexible but cost CPU.

How do I log the transformed value in WinCC Unified V20?

Create an HMI tag that holds the transformed value (either written by a scheduled JavaScript task or read from the PLC), then open the Logging Tags editor and double-click <Add> in the Name column to create a logging tag linked to it. The link is the configuration step that makes the value visible to the runtime logging database.

Is the Limits object in Unified a replacement for the V7.5 linear scaling?

Yes. The Limits object on a Unified HMI tag performs a linear mapping from raw counts to engineering units with no script cost. For non-linear curves (square root, polynomial compensation, lookup tables) you must use a JavaScript scheduled task or compute the result in the PLC.

Back to blog