Overview
Siemens WinCC faceplate architectures normally assume that every motor, drive, valve, or sensor follows a strict tag-prefix convention such as Instance.Property (for example PUMP001.RUN, PUMP001.FAULT, PUMP001.AUTO). When the runtime tag list provided by the plant PLC programmer does not follow that convention - because the customer data dictionary uses different prefixes, abbreviations, or completely flat names - the standard WinCC faceplate model collapses. The picture window can no longer be opened with a single Tag Prefix property, and dynamic dialogs configured against VSD001_RUN cannot be re-pointed at VSD002_RUN from a button click without editing the picture.
This article documents a working pattern that uses indirect tag addressing with internal text pointer tags, the INDIRECT flag on dynamic dialogs, and a C script fired from a button to remount the picture content. It also incorporates the corrective procedure from Siemens KB 5854227, which explains that a Tag Prefix change alone is not enough - the Picture Name must also be reassigned, or the new tags will not refresh on screen.
Problem Statement and Constraints
Assume the following data dictionary exists in the controller and is exposed one-to-one in the WinCC tag list:
| Logical role | Data type | Example tag name |
|---|---|---|
| Running feedback | BOOL | VSD001_RUN |
| Auto mode active | BOOL | VSD001_AUTO |
| Fault present | BOOL | VSD001_FAULT |
| Actual speed (%) | FLOAT | VSD_SPEED |
| Speed setpoint (%) | FLOAT | VSD_SPEEDSP |
| Description text | STRING | VSD001_DESCRIPTION |
The naming is intentionally inconsistent: the speed tags do not carry the VSD001 prefix, and there is no VSD001.MANUAL, VSD001.OUT, or VSD001.SP alias to fold into a clean structure. The standard Tag Prefix property of a picture window cannot be used because the picture expects six separate absolute tag references that change as the user clicks between drives.
The naive alternatives all fail in production:
- Direct hard-coding requires one picture per drive (not scalable).
- Dynamic dialog cannot read tag names from another tag at runtime - it evaluates the configured tag at compile time only.
- Structure tag / UDT requires the PLC programmer to refactor the data block, which is rarely permitted on a customer acceptance project.
- Picture window with a Tag Prefix works only when every tag inside the picture follows the same prefix hierarchy.
Prerequisites
- WinCC V7.3 SP3, V7.4 SP1, V7.5 SP2, or TIA Portal WinCC Professional V16/V17/V18 installed with the C script option enabled (default for all current versions).
- An HMI tag list synchronized with the PLC where each variable used by the picture exists with its final absolute name (no structure aliases required).
- Editor access to Graphics Designer (WinCC Classic) or HMI screen editor (TIA Portal).
- Read access to Siemens KB 5854227 for the Picture-Name refresh behavior.
- Reference manual: WinCC V7.5 SP2 - Working with WinCC (entry ID 109772930) for tag properties and the dynamic dialog editor.
Architecture of the Indirect Pattern
The pattern introduces a layer of indirection. Instead of pointing dynamic elements directly at VSD001_RUN, every element is pointed at a small internal WinCC tag whose value is the name of the real tag to read. When the user clicks a button, a C script rewrites these internal tags, and the picture elements - because they are configured with the INDIRECT checkbox - dereference the new names and refresh on the next update cycle.
| Element | Source | Holds |
|---|---|---|
Pointer tag (e.g. pPump_Run) |
WinCC internal, Text tag 8-bit | String such as "VSD001_RUN"
|
| Faceplate circle "Running" | Background color via dynamic dialog | Reads pPump_Run with INDIRECT |
| Faceplate I/O field "Current Speed" | Output via dynamic dialog | Reads pPump_Speed with INDIRECT |
| Mouse-click event on VSD001 button | C action | Writes SetTagChar(...,"VSD001_RUN") into each pointer |
The pointer tags are internal WinCC tags - not controller tags. They live only in the WinCC database and participate in no PLC exchange. They are typed as Text tag, 8-bit font because the API SetTagChar expects zero-terminated strings. Using a wider Unicode internal tag is allowed on WinCC V7.5 but is unnecessary and breaks older Runtime builds.
Step-by-Step Implementation
Step 1 - Declare the internal pointer tags
In the WinCC tag management create one internal Text tag per signal that the picture will display. For the canonical pump picture use:
-
pPump_Run(Text tag, 8-bit) -
pPump_Auto(Text tag, 8-bit) -
pPump_Fault(Text tag, 8-bit) -
pPump_Manual(Text tag, 8-bit) -
pPump_Out(Text tag, 8-bit) -
pPump_Speed(Text tag, 8-bit) -
pPump_SpeedSp(Text tag, 8-bit) -
pPump_Description(Text tag, 8-bit)
Leave the initial values empty. They will be written the first time the user selects a drive.
Step 2 - Configure faceplate elements with INDIRECT
Open the picture window's contained picture (for example PumpControl.pdl). For every dynamic dialog or property assignment that must follow the pointer tag:
- Open the dynamic dialog.
- Select the pointer tag (e.g.
pPump_Run) as the source expression. - Mark the checkbox labelled Indirect in the lower half of the dialog.
- Complete the type/format definition as if the pointer were the actual tag. Because
pPump_Runis a string holding a BOOL tag name, use a Type Boolean interpretation on a Numeric field or a direct assignment on a color field.
Step 3 - C script on the selection button
Attach a C action to the Mouse Click event of the button (for example, the VSD001 button on the parent screen). The script performs three jobs: (a) writes the new tag names into the pointer tags, (b) updates the picture window's Tag Prefix if any tags still obey a prefix, and (c) per Siemens KB 5854227, forces a Picture Name refresh so the dialogs re-evaluate.
// C action: Mount pump faceplate for the selected drive
// Trigger: Mouse Click on VSD00x button
// Applies to: WinCC V7.x Graphics Designer
#include "apdefap.h"
void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
// ----- User configuration -----
char* szPumpId = "VSD001"; // change per button instance
char* szSpeedPre = "VSD_"; // speed tags are flat, no instance prefix
// ------------------------------
char szBuf[64];
// Boolean pointers
SetTagChar("pPump_Run", (char*)strcat(strcpy(szBuf, szPumpId), "_RUN"));
SetTagChar("pPump_Auto", (char*)strcat(strcpy(szBuf, szPumpId), "_AUTO"));
SetTagChar("pPump_Fault", (char*)strcat(strcpy(szBuf, szPumpId), "_FAULT"));
SetTagChar("pPump_Manual",(char*)strcat(strcpy(szBuf, szPumpId), "_MANUAL"));
SetTagChar("pPump_Out", (char*)strcat(strcpy(szBuf, szPumpId), "_OUT"));
// Numeric pointers - shared speed namespace
SetTagChar("pPump_Speed", (char*)strcat(strcpy(szBuf, szSpeedPre), "SPEED"));
SetTagChar("pPump_SpeedSp", (char*)strcat(strcpy(szBuf, szSpeedPre), "SPEEDSP"));
// Description string
SetTagChar("pPump_Description", (char*)strcat(strcpy(szBuf, szPumpId), "_DESCRIPTION"));
// ---- KB 5854227 fix: refresh picture window ----
// When only Tag Prefix is changed, WinCC does not refresh the
// contained picture until the next trigger. Setting Picture Name
// (even to the same value) forces the picture to re-evaluate all
// dynamic dialogs immediately.
SetPictureName(lpszPictureName, "PumpWindow", "PumpControl.pdl");
// Optional: also retag any Tag Prefix-bearing objects
// SetPropChar(lpszPictureName, "PumpWindow", "TagPrefix", szPumpId);
}
SetPictureName requires the parent picture name, the picture-window object name, and the new picture PDL. Calling it with the same picture name that the window already displays is intentional - it forces the refresh, exactly as documented in Siemens KB 5854227.
Step 4 - Configure the picture window itself
Place a picture window on the parent screen with object name PumpWindow. Set its initial Picture Name to PumpControl.pdl. If any elements inside the picture still rely on a tag prefix (for example, a description label that uses {Instance}_DESC), set Tag Prefix to a placeholder such as VSD001; the C script can override it at runtime. With pure indirect pointers you may leave Tag Prefix empty.
Step 5 - Repeat the click script per button instance
Copy the C action to each drive button and modify the szPumpId literal. Alternatively, parameterize the script by reading a tag that holds the selected drive ID - this reduces maintenance when many drives exist.
// Parameterized variant - same script for every drive button
char* szPumpId = GetTagChar(lpszObjectName); // button tag carries ID
// fallback if button tag is empty
if (strlen(szPumpId) == 0) szPumpId = "VSD001";
...
Why Dynamic Dialog Cannot Do This Alone
Dynamic dialogs evaluate the configured expression at picture compile time. They support a fixed set of operations (comparison, range, bitwise) against a single tag or a constant. The dialog has no mechanism to read a tag and then dereference its value as another tag. WinCC Professional adds the HMIRuntime.Tags object in VB and GetTagXXX/SetTagXXX in C, but those run inside C/VB actions, not inside the dialog itself.
Indirect addressing closes that gap. The dynamic dialog reads the pointer; the pointer contains the name; WinCC resolves that name against the tag database. The result is a re-targetable dialog without scripting the dialog body.
Limitations of the Pattern
| Limitation | Impact | Workaround |
|---|---|---|
| Only one faceplate instance active at a time | Opening a second drive overwrites the first | Open each instance in its own picture window with its own pointer-tag namespace |
| Pointer tags are runtime-only | Tag list import/export to other engineering tools does not carry them | Document them in the WinCC project documentation |
| C script required | Engineers without C experience need assistance | Generate the script once per project, copy between buttons |
| Text tag 8-bit length | Tag names longer than 255 characters are truncated | Use 32-char abbreviations in the controller where possible |
| Refresh latency | Cycle time is governed by Update cycle setting (default 2 s) | Reduce the Update cycle of the picture window to 250 ms or use 100 ms for fast feedback |
pPump_Run_1, pPump_Run_2, ...) and bind each picture window to its own set. The C script then becomes a function that takes the window index as a parameter.Verification Procedure
- Compile check. Recompile the OS project (WinCC Classic) or the HMI project (TIA Portal). Any dynamic dialog configured against a non-existent pointer tag will appear in the output window as a warning; fix before going online.
-
Tag simulation. In WinCC Classic use Tag Simulation (Tools menu) to drive
VSD001_RUNON/OFF and confirm the running circle on the picture window changes color. -
Click switch. Press the button for
VSD002. The color and I/O fields must update within one update cycle to reflectVSD002_RUNand the new speed value. -
KB 5854227 regression test. Comment out the
SetPictureNameline and observe that the picture no longer refreshes when only the pointer tags change. Restore the line and confirm refresh. -
Runtime diagnostic. Enable GSC diagnostics in WinCC (Start > Programs > WinCC > Tools > GSC diagnostics) and verify that no "tag not found" entries appear for
pPump_*pointers. - Update cycle tuning. In the Graphics Designer open Project Properties > Update Cycle. For fast-changing feedback such as speed, set the cycle of the picture window to 250 ms; for status lamps 1 s is acceptable.
Alternative Approaches
Where the customer accepts refactoring of the data block, the structure tag route is still preferred because it removes all C scripts. Under TIA Portal, the equivalent is the HMI UDT combined with a faceplate that uses the UDT instance as its tag interface. The KB at entry ID 5854227 addresses that case as well - when only the Tag Prefix is changed dynamically, the picture still requires a Picture Name reassignment, otherwise the runtime does not pick up the new instance.
For very small HMI panels where C scripting is unavailable, the only fallback is to create one picture per device. This is acceptable for systems with fewer than ten devices but does not scale.
Field-Proven Tips
- Keep pointer-tag names aligned with the picture role, not the device (
pPump_Run, notpVSD001_Run). When you later copy the picture to a different namespace, only the C script has to change. - Build a small tag-name table in the controller and expose it as a STRING array. Have one startup C script read the array and populate the pointer tags - then per-button clicks only swap instance IDs instead of rewriting six
SetTagCharcalls. - Set the picture window property Independent Window = No when the picture only ever appears once; this prevents accidental overlay confusion during commissioning.
- Wrap
SetPictureNameinif (strcmp(GetPropChar(lpszPictureName, "PumpWindow", "PictureName"), "PumpControl.pdl") == 0)only when you also need to change the picture content - otherwise calling it unconditionally on every click is sufficient and faster. - Validate that
pPump_*pointers are configured with Length adaptation = No in tag management; otherwise WinCC may right-pad short names and produce an invalid tag reference.
Troubleshooting Matrix
| Symptom | Likely cause | Corrective action |
|---|---|---|
| Picture never updates after button click |
SetPictureName missing per KB 5854227
|
Add SetPictureName(lpszPictureName,"PumpWindow","PumpControl.pdl")
|
| Circle stays grey for every drive | INDIRECT checkbox not set on the dynamic dialog | Reopen dynamic dialog and tick Indirect |
| Compile error: pointer not declared | Internal tag created in wrong connection | Move pPump_* to Internal tags folder |
Speed field shows ###
|
Pointer holds full controller path but tag is exposed without it | Strip the controller prefix from SetTagChar argument |
| Click works, second click does nothing | Pointer tag was 16-bit Unicode | Recreate as Text tag 8-bit font |
| Multiple drives show identical values | Single faceplate only - design limitation | Dual-instance picture windows with separate pointer namespaces |
Why is dynamic dialog alone unable to swap tag references at runtime in a WinCC picture window?
Dynamic dialogs evaluate the configured expression at compile time and cannot dereference a tag whose name is read from another tag. WinCC provides indirect addressing through the INDIRECT checkbox on the dialog - the dialog reads a pointer tag whose value contains the real tag name, and WinCC resolves that name at runtime. C scripting is required only to write the new name into the pointer tag, not to interpret the value.
Does changing only the Tag Prefix of a picture window refresh the displayed tags?
No. Per Siemens KB 5854227, the picture window ignores a Tag Prefix change until the Picture Name property is also written. Always call SetPictureName with at least the current picture name after the prefix change to force the refresh.
Which WinCC versions support the indirect tag addressing with C script described here?
WinCC V7.3 SP3, V7.4 SP1, and V7.5 SP2 in the Classic line, plus WinCC Professional V16, V17, and V18 under TIA Portal, all expose SetTagChar, SetPictureName, and the INDIRECT checkbox on dynamic dialogs. Older versions such as WinCC V6.2 also work but require manual inclusion of apdefap.h and a different action trigger syntax.
Can multiple instances of the pump faceplate be open simultaneously?
Not with the basic pattern documented above - the single pointer-tag set can only describe one drive at a time. To support multiple instances, duplicate the pointer tags with a numeric suffix per picture window and parameterize the C script with the window index. Each picture window then maintains its own private namespace and refreshes independently.
What data type must the pointer tags use?
Use Text tag, 8-bit font with length 32 characters or larger. The SetTagChar C API writes a zero-terminated ASCII string, and the indirect dialog reader expects the same format. Unicode (16-bit) pointer tags work on V7.5 but break older Runtime builds and can cause intermittent "tag not found" diagnostics.