Overview
Engineers routinely need a WinCC HMI to react to PLC events the moment they occur - not on a timer poll, not on a screen open, but exactly when a tag transitions. The canonical Siemens pattern is a tag-triggered VB script: configure an HMI tag (the mirror of a PLC tag) so that a configured event fires a Sub in the project's VB script library. This pattern is available on every TIA Portal version that ships WinCC Comfort/Advanced and on every WinCC Professional Runtime target.
This article walks through three runtime targets:
- Comfort Panels (TP700 Comfort, TP1500 Comfort, KP1500 Comfort, KTP Comfort) running in the integrated HMI runtime.
- WinCC Advanced Runtime on a PC (RT Advanced) where the runtime is hosted on Windows.
- WinCC Professional Runtime on a PC or WinCC Server where Global Scripts and the Scheduled Tasks editor are available.
The same logic applies whether the source tag is Bool, Int, Word, Real, DInt, or String. Misconceptions that "VB scripts cannot run on Bool tags" originate from confusing the typed Function List trigger (where a parameter data type matters) with the untyped Value Change event (which accepts any tag).
The reference configuration was originally documented against TIA Portal V13 SP1 / WinCC Advanced V13 SP1 on a TP700 Comfort panel. The mechanism is unchanged through TIA Portal V17, V18, V19, V20, and V21; only navigation labels shift slightly between versions.
Prerequisites
- TIA Portal V13 SP1 or later with WinCC Comfort/Advanced or WinCC Professional installed.
- A configured HMI device (Comfort Panel or PC Runtime) added to the project.
- An HMI tag already connected to a PLC tag (drag from PLC tag table onto HMI tag table, or manually via the connection editor).
- Project editor permission to create scripts (engineering station account on WinCC Professional; unrestricted on Comfort Panels).
- For bulk import / scripted deployment: TIA Portal Openness API installed on the engineering station.
Runtime Target Selection Matrix
| Target | Script Editor | Trigger Editor | Scope | Recommended For |
|---|---|---|---|---|
| Comfort Panel (TP/KTP) | HMI Scripts (project tree, "Scripts") | Tag properties → Events tab → Value change | Active screen only | Single-machine HMI with screen-local reactions |
| WinCC Advanced Runtime (PC) | HMI Scripts (project tree, "Scripts") | Tag properties → Events tab → Value change | Active screen only | Standalone PC HMI without multi-screen requirements |
| WinCC Professional Runtime | Global Scripts (C, VB) | Scheduled Tasks → Triggers tab → Tag Trigger | Runtime-wide, screen-independent | Multi-screen plants, server projects, batch logging |
| WinCC Professional (per-screen) | Screen scripts | Tag properties → Events tab → Value change | Active screen only | Per-screen animations and overlays |
Choose Scheduled Tasks whenever the script must run independent of the currently displayed screen - common for logging, alarming escalation, recipe save, audit trail, or sending a record to the PLC. Choose tag properties → Value change when the action only makes sense while the operator is interacting with a specific screen.
Tag Configuration and Acquisition Modes
The trigger fires when WinCC detects the tag value has changed within its acquisition cycle. Three acquisition modes exist for HMI tags and each governs how often the runtime samples the value:
| Acquisition Mode | Behavior | Trigger Source for Scripts |
|---|---|---|
| Cyclic continuous | Runtime polls the PLC at the configured update cycle (default 1 s) regardless of whether the value is displayed. | Recommended. Value-change events are reliably detected. |
| Cyclic on use | Runtime polls only while the tag is displayed or referenced by a script. | Unreliable - if no screen references the tag, polling stops and the event never fires. |
| On demand | Runtime reads the tag only when explicitly requested by SmartTags(...).Read. |
Not applicable for trigger-driven scripts. |
For any tag that triggers a VB script, set the acquisition mode to Cyclic continuous in HMI Tags → [tag] → Properties → General. Pair it with an Update Cycle of 250 ms for fast reactions or 1 s for routine logging. Faster cycles (100 ms, 50 ms) are permitted but increase HMI ↔ PLC load; avoid sub-100 ms unless the application explicitly demands it.
Step-by-Step: Triggering VB on a Comfort Panel from a PLC Tag
-
Author the VB script. In the project tree, expand your HMI device → "Scripts" → double-click "VB Scripts" (or right-click → Add new VB function). The VBScript editor opens. Define a public procedure, for example:
' Module: Logging Public Sub LogMeasurementComplete() Dim bReady As Boolean bReady = SmartTags("HMI_MeasurementReady") If bReady = False Then Exit Sub ' Rising-edge guard ' Write a line to the alarm / logging buffer Dim sUser As String sUser = SmartTags("HMI_CurrentUser") HMIRuntime.Trace("Measurement logged by " & sUser & " @ " & Now, 0) ' Acknowledge back to PLC so the next cycle can re-trigger SmartTags("HMI_AckLogBit") = True End Sub - Save and compile. Use the menu "Scripts → Check Syntax" (or Ctrl+F7 in V13 SP1; the same key binding persists in V17/V18/V19/V20/V21). Resolve any compile errors before continuing.
-
Open the tag. In the project tree, expand "HMI Tags" and double-click the tag that mirrors the PLC boolean, e.g.
HMI_MeasurementReady. -
Set acquisition mode. Under Properties → General → Acquisition mode, choose Cyclic continuous. Set Update cycle to
1 s(or your application-specific value). - Attach the event. Switch to the Events tab. Expand "Value change". Click the empty cell on the right; the selection button (three dots or a function icon, depending on version) opens a picker. Choose Scripts → VB function → [Module].LogMeasurementComplete.
- Compile the HMI project. Click "Compile" in the toolbar. The event binding is generated into the runtime database.
-
Download to the panel. Transfer the project (RT → "Download to device → Software"). The runtime will now call
LogMeasurementComplete()every timeHMI_MeasurementReadychanges.
If bReady = False Then Exit Sub. For falling-edge detection, mirror the logic: If bReady = True Then Exit Sub.Step-by-Step: Triggering Global VB in WinCC Professional
- Author the script globally. In the project tree of the WinCC Professional HMI device, expand "Global Scripts" → "VB Actions" (or "VB Functions"). Create a new module and procedure as shown above. Global procedures are visible to the entire runtime, not just one screen.
-
Open Scheduled Tasks. Expand "Global Scripts" → "Scheduled Tasks" and add a new task. Give it a recognizable name (e.g.
Task_LogMeasurementComplete). - Bind the VB function. In the task properties → General, select the function list type and choose your VB procedure.
-
Configure the tag trigger. Switch to the Triggers tab. Click "Add" and select Tag Trigger. Configure:
-
Tag:
HMI_MeasurementReady - Trigger condition: On change (fires on every change) or On rising edge (fires only on 0→1). On Professional, both options are selectable; on Comfort panels, use the rising-edge guard in code instead.
- Acquisition cycle: inherit from the tag, or override here. 1 s is typical.
-
Tag:
- Set the execution scope. In the task's "Properties → Runtime" tab, ensure the task is enabled. Set the start condition to "Start with Runtime" so the task is active immediately.
- Compile and download. Build the WinCC Professional project and download to the RT or WinCC Server.
The scheduled-task approach is what most professional WinCC deployments use for cross-screen automation. It survives navigation events, supports multiple triggers per task, and exposes a centralized audit point in the project tree.
Boolean vs Integer Tags: Clearing the Confusion
Operators new to TIA Portal often report that the function-list picker disables Bool tags while Int / Word / Real remain selectable. The cause is the difference between two trigger mechanisms:
| Trigger Mechanism | Data-Type Constraint | Where to Find It |
|---|---|---|
| Function List (typed parameter) | The selected VB function's argument data type must match the tag's data type. A function declared Sub Foo(iVal As Integer) will not appear for a Bool tag. |
Tag Properties → Events → Value change → Function list |
| Event "Value change" (parameterless) | No constraint. Any tag data type may trigger a parameterless Sub. |
Same location, but choose "Scripts" instead of "Function list" |
For a Bool trigger, author a parameterless Sub as in the example above and bind it via the Scripts (not Function list) selector. The Bool tag is read inside the script via SmartTags("..."), which always returns a Variant that coerces correctly.
Sample Patterns
Pattern A: Rising-Edge Latch with Acknowledgement
' PLC sets "HMI_RequestLog"=TRUE after a measurement completes.
' Script latches the request, writes to log, sets "HMI_LogAck"=TRUE so the PLC drops the request.
Public Sub HandleLogRequest()
If SmartTags("HMI_RequestLog") = False Then Exit Sub
Dim sPath As String
sPath = SmartTags("HMI_LogPath") & "\meas_" & Format(Now, "yyyymmdd_hhnnss") & ".csv"
SmartTags("HMI_ResultString") = SmartTags("PLC_ResultString")
HMIRuntime.Trace("Logged to " & sPath, 0)
SmartTags("HMI_LogAck") = True
End Sub
Pattern B: Integer Threshold Crossing
' Runs when "PLC_CycleCount" changes; logs only when crossing 100, 200, 300...
Public Sub TrackCycleCount()
Dim iCycles As Integer
iCycles = SmartTags("PLC_CycleCount")
If (iCycles Mod 100) <> 0 Then Exit Sub
HMIRuntime.Trace("Cycle milestone: " & CStr(iCycles), 0)
End Sub
Pattern C: Reading Multiple Tags in One Trigger
' Trigger from "PLC_AutoStep" changing; read a block of related values in one call.
Public Sub CaptureAutoStep()
Dim iStep As Integer
iStep = SmartTags("PLC_AutoStep")
HMIRuntime.Trace("Auto Step entered: " & CStr(iStep), 0)
If iStep >= 10 And iStep <= 19 Then
SmartTags("HMI_ShowSubstepScreen") = True
End If
End Sub
Automation via TIA Portal Openness API
For projects with hundreds of tag-triggered scripts, manual configuration does not scale. The TIA Portal Openness API exposes the same binding logic for automation. The official documentation covers the script import surface used when scripts are stored outside the project file:
- Requirement: the TIA Portal Openness application is connected to the TIA Portal and a project is open. See Importing VB scripts - TIA Portal Openness API V21.
- Use the Openness API to enumerate HMI devices, walk tag properties, and attach a
ValueChangeevent handler programmatically. This is the recommended path for engineering shops that regenerate HMI projects from a master template. - The Openness API is available for TIA Portal V15.1 and later (with progressive feature additions in V16, V17, V18, V19, V20, and V21). The script import endpoint documented in the URL above targets the V21 surface; earlier versions require manual binding or a vendor tool.
Troubleshooting Matrix
| Symptom | Root Cause | Resolution |
|---|---|---|
| Script never fires even though the PLC tag toggles. | Tag acquisition mode is "Cyclic on use" or "On demand" - no polling occurs off-screen. | Set acquisition mode to Cyclic continuous; verify Update cycle is reasonable. |
| Script fires only on rising edge, never on falling edge (or vice versa). | Trigger condition selected as "On rising edge" in Scheduled Tasks. | Change to "On change", or add an early-exit guard for the unused edge. |
| Bool tag does not appear in function-list picker. | The bound VB function expects a typed parameter that does not match Bool. | Bind a parameterless Sub via "Scripts" selector instead of "Function list". |
| Script fires but PLC does not see the acknowledgement bit. | Comfort Panel tag area pointer / bit-write handshake not configured. | Verify connection, ensure the tag's "PLC" direction is set to "Read/Write"; check area pointers. |
| Script runs twice in quick succession. | Acquisition cycle is shorter than the PLC's update time, generating two distinct value-change events from one logical transition. | Increase Update cycle to 500 ms-1 s, or debounce in code with a timestamp check. |
| Compile error "Object required: SmartTags". | Typo in tag name or tag is in a different HMI connection scope. | Verify the tag exists in the HMI's tag list; VB requires exact string match including case. |
| Script fires once on download but not again. | Initial value at startup coincides with the PLC's value, so no change is detected. | Add a one-time initialization that sets the HMI tag to a sentinel value at runtime start. |
| Performance drop with many tag-triggered scripts. | Each event runs synchronously on the HMI's main thread. | Consolidate triggers into fewer, parameterized scripts; avoid heavy I/O inside the handler. |
| Script works on Comfort panel but not after moving to Professional Runtime. | Comfort uses screen-local Scripts editor; Professional uses Global Scripts. | Re-author the script in Global Scripts and bind via Scheduled Tasks. |
| VB script crashes with "ActiveX component can't create object". | External COM object not registered on the target runtime. | Register the COM DLL on the runtime PC, or remove the external dependency. |
Verification Procedure
- Simulate the tag change in PLCSIM. With the panel connected to PLCSIM or a soft PLC, force the source PLC tag to TRUE and then FALSE. Confirm the HMI tag mirrors the transition in the tag diagnostics window.
-
Inspect the runtime trace. Use
HMIRuntime.Trace "...", 0in the script and view the output via WinCC's diagnostic tools (e.g. "Tools → Trace Viewer" in Engineering, or the runtime's diagnosis page). Each call leaves a timestamped line. - Verify the acknowledgement handshake. If the script writes back to the PLC, monitor the PLC tag in PLCSIM and confirm it goes TRUE within one update cycle of the trigger.
-
Load-test the trigger. Use the HMI's diagnostic script to toggle the source tag 100 times in a loop and confirm the count of
HMIRuntime.Tracelines matches expectations. - Stress the HMI. Navigate between screens rapidly while the trigger source is being driven externally. Confirm the script continues to fire - this validates that the trigger is attached to the tag (survives navigation) rather than to a screen event (lost on navigation).
Performance and Engineering Notes
- One trigger per logical event. Avoid stacking two Value-Change events on the same tag that call the same script. The runtime will execute it twice per change.
- Avoid tag-triggered scripts on tags updated faster than 100 ms. This starves the HMI's main thread and delays screen refresh. Offload fast loops to a PLC task instead.
- Prefer integer/word tags for high-frequency triggers. Bool tag updates may be coalesced by some PLCs if the underlying DB is updated faster than the HMI's cycle; an Int with a counter is more robust.
-
Guard against re-entrancy. If a script can be re-entered before the previous call completes (e.g. via a second trigger source), add a static Boolean guard at module level:
Static bBusy As Boolean. - Document the trigger in the tag comment. TIA Portal does not surface event bindings in the tag list. Always annotate the tag with "Triggers: LogMeasurementComplete" in the Comment column so the binding is discoverable.
- Migrate V13 SP1 projects carefully. When upgrading from V13 SP1 to V17/V18/V19/V20/V21, event bindings are preserved but the underlying script GUIDs change if the script body is edited. Re-compile the HMI before downloading.
FAQ
Can a Bool PLC tag trigger a VB script on a Comfort panel?
Yes. Bind a parameterless Sub via the tag's Events tab → Value change → Scripts selector. The function-list selector rejects Bool because the typed parameter does not match; the untyped event selector accepts any data type. Use a rising-edge guard inside the script to avoid firing on both edges.
What's the difference between triggering via tag properties and via Scheduled Tasks?
Tag properties → Events → Value change is screen-local: the script fires only while the tag's screen (or a screen referencing the tag) is the active window. Scheduled Tasks is runtime-wide: the script fires regardless of which screen is active, which is required for logging, alarming, and cross-screen automation on WinCC Professional.
Why does my script fire on download but not again afterwards?
The HMI tag's initial value at runtime start matches the PLC's value, so no change is detected. Add a startup routine (e.g. HMIRuntime.Screens("Startup").OnLoaded) that forces the HMI tag to a sentinel value, then let the PLC drive it normally.
Which acquisition cycle should I use for the trigger tag?
1 s is the safe default for routine triggers. Use 250 ms for operator-perceptible reactions such as alarms or button feedback. Avoid sub-100 ms unless the application explicitly demands it; the HMI's main thread will spend more time polling than servicing screens.
Can I trigger the same VB script from multiple tags?
Yes. Bind the script on each tag's Events tab. To avoid executing the same logic twice in one cycle (if two tags change simultaneously), include a debounce timestamp or a static-busy guard inside the script so only the first call performs the action within a defined window.
Where can I find the TIA Portal Openness API documentation for VB scripts?
The official TIA Portal Openness API documentation for V21 covers VB script import under Importing VB scripts. Earlier TIA Portal versions (V15.1+) also expose Openness but the script import endpoint shape differs - consult the version-specific Siemens docs for the exact API surface.