Reading PCS7 SFC_STATE DWORD in WinCC VBScript: Complete Guide
When integrating a Siemens PCS 7 sequential function chart (SFC) into a WinCC HMI screen, the operating state of the chart is published through the SFC block's SFC_STATE attribute. This attribute is a 32-bit unsigned double word (DWORD) and exposes flags such as AUTO, MAN, operator-requested transitions, and chart-in-operation. VBScript in WinCC does not understand the STEP 7 hex literal 16#..., so the comparison you write in your faceplate must use decimal values or a bit-masking expression. This reference covers the SFC_STATE bit layout, decimal equivalents, the HMIRuntime.Tags read path, three comparison strategies, and the animation wiring that links the result to screen objects.
SFC_STATE DWORD is exposed by the SFC chart instance DB and is also reachable through the SFC visualization (SFC Visualization / SFC Control) on the OS.1. Overview of the SFC_STATE Attribute
The SFC_STATE DWORD is a status word maintained by the SFC runtime inside the SFC instance DB. It encodes the chart's operating mode, transition flags, and the active step's control word. The values that WinCC HMI developers encounter most often are the AUTO and MAN indicators:
| Mode | Hex (STEP 7) | Decimal (WinCC) | Binary layout (bit 31..0) |
|---|---|---|---|
| Manual (operator request) | 16#20001000 | 536875008 | 0010 0000 0000 0000 0001 0000 0000 0000 |
| Automatic (operator request) | 16#20000080 | 536870016 | 0010 0000 0000 0000 0000 0000 1000 0000 |
| Manual (internal state) | 16#00001000 | 4096 | 0000 0000 0000 0000 0001 0000 0000 0000 |
| Automatic (internal state) | 16#00000080 | 128 | 0000 0000 0000 0000 0000 0000 1000 0000 |
| Chart held / aborted | 16#00000040 | 64 | 0000 0000 0000 0000 0000 0000 0100 0000 |
| Chart in operation | 16#20000000 | 536870912 | 0010 0000 0000 0000 0000 0000 0000 0000 |
The 0x20000000 bit is the "operator request" or "operator switch" flag set whenever the AUTO/MAN command originated from the OS faceplate rather than from the AS program. SFC charts that run purely in automatic mode without any operator intervention report 16#00000080 instead of 16#20000080. The same rule applies to the MAN side.
1.1 Why VBScript Cannot Parse 16#20001000
VBScript (VBS 5.8 / Windows Script Host) supports the prefix &H for hexadecimal literals. The prefix 16# is a STEP 7 (S7-STL / SCL) convention and is rejected at parse time by the VBScript engine, producing runtime error 800A0401 ("Expected end of statement"). Two paths are available:
- Write the literal in VBScript hex form:
&H20001000. - Convert to decimal and compare against the integer value:
536875008.
Both forms produce the same DWORD; choose whichever yields the most readable code in your faceplate script.
2. Prerequisites
Before wiring a VBScript action to the SFC_STATE DWORD, confirm the following:
- The OS is built on a PCS 7 project so that the SFC Visualization plug-in is registered in WinCC Explorer.
- The SFC chart has been compiled and downloaded to the AS. The instance DB must exist in the S7 program; WinCC only sees the symbol after the OS compilation re-runs (right-click OS project → "AS-OS Conversion" or "Compile OS").
- The tag
S7$Program(2)/<SFCName>.SFC_STATEis visible in the WinCC tag management under "SIMATIC S7 PROTOCOL SUITE → TCP/IP" or "Named Connections", depending on the channel slot used in your project. - The WinCC graphics designer is launched on the engineering station that owns the project, and the script is invoked with the runtime execution rights of the user logged in to the OS (typically
CCOperatoror equivalent Windows user in theSIMATIC HMIgroup).
S7$Program(2) refers to the second S7 program block in the connection configuration. If your PCS 7 project has a single S7 program, the path is S7$Program/<SFCName>.SFC_STATE (no numeric suffix).3. Reading the SFC_STATE Tag with HMIRuntime
WinCC VBScript exposes the runtime environment through the global object HMIRuntime. The most common read pattern is:
Dim objTag
Set objTag = HMIRuntime.Tags("S7$Program(2)/REACTOR.SFC_STATE")
objTag.Read
Dim lngState
lngState = objTag.Value
The .Value property is a Long (32-bit signed in VBScript terms, but the value range of a DWORD is preserved because the WinCC tag manager stores it as unsigned). The VBScript Long type wraps negative when the most significant bit is set, so 16#80000000 (2,147,483,648) is reported as -2147483648. For SFC_STATE the relevant values are all well below 0x80000000, so plain decimal comparison works without CLng or CDbl conversion.
3.1 Reading Quality Code and Timestamp
The Tag object also exposes a quality code, which is useful for diagnostics:
Dim objTag, intQuality
Set objTag = HMIRuntime.Tags("S7$Program(2)/REACTOR.SFC_STATE")
objTag.Read
intQuality = objTag.Quality
If (intQuality <> 0) Then
' 0x00000000 = Good, 0x00000040 = Uncertain, 0x00000080 = Bad
HMIRuntime.Trace "SFC_STATE quality=" & intQuality & " value=" & objTag.Value & vbCrLf
End If
Quality codes 64 (0x40) and 128 (0x80) indicate the AS connection is degraded or the tag is not being polled; the read result is stale in that case.
4. The Three Comparison Strategies
4.1 Strategy A — Decimal Literal (Simplest)
Convert the STEP 7 hex value to decimal and compare directly. The two constants for the operator-requested modes are 536875008 (MAN) and 536870016 (AUTO). For internal modes, use 4096 and 128 respectively.
Function Visible_Trigger(ByVal Item)
Dim objTag
Set objTag = HMIRuntime.Tags("S7$Program(2)/REACTOR.SFC_STATE")
objTag.Read
Select Case CLng(objTag.Value)
Case 536875008, 4096 ' MAN (operator or internal)
Visible_Trigger = 1
Case Else ' AUTO, held, aborted, transition
Visible_Trigger = 0
End Select
End Function
The CLng() cast is defensive: it forces the VBScript Variant into a 32-bit signed integer so that bitwise operations and the Select Case dispatch behave predictably.
4.2 Strategy B — VBScript Hex Literal
Equivalent code using the &H prefix keeps the visual parity with the STEP 7 source:
Function Visible_Trigger(ByVal Item)
Dim objTag
Set objTag = HMIRuntime.Tags("S7$Program(2)/REACTOR.SFC_STATE")
objTag.Read
If (CLng(objTag.Value) = &H20001000) Or _
(CLng(objTag.Value) = &H00001000) Then
Visible_Trigger = 1
Else
Visible_Trigger = 0
End If
End Function
Tip: group operator and internal states with Or when the faceplate should display MAN regardless of who initiated the request.
4.3 Strategy C — Bit Masking (Most Robust)
When you only need to know "is MAN set?" regardless of any other flag bits, mask the relevant bit. The MAN bit is bit 12 (0x1000); the AUTO bit is bit 7 (0x80). The operator-request bit is bit 29 (0x20000000).
Function Visible_Trigger(ByVal Item)
Dim objTag, lngVal
Set objTag = HMIRuntime.Tags("S7$Program(2)/REACTOR.SFC_STATE")
objTag.Read
lngVal = CLng(objTag.Value)
' Bit 12 = MAN, bit 7 = AUTO
If (lngVal And &H1000) <> 0 Then
Visible_Trigger = 1
ElseIf (lngVal And &H80) <> 0 Then
Visible_Trigger = 0
End If
End Function
Bit-masking is the only approach that survives PCS 7 service packs adding new state flags: if a future release sets additional bits while keeping MAN active at bit 12, the visibility animation still works.
5. Driving HMI Animations with the SFC_STATE Result
To bind a faceplate object's Visible property to the function above:
- In Graphics Designer, right-click the icon → Properties → Animations → Visibility.
- Add a new dynamic of type VBScript for the
Visibleattribute. - Replace the default stub with the
Visible_Triggerfunction (the parameterItemis provided by the animation framework). - Configure the update cycle: for state bits, a 2 s polling cycle is adequate. Faster cycles (250 ms, 500 ms) waste channel bandwidth without visual benefit.
For two-color icon swapping (one symbol for AUTO, another for MAN), use two Visibility animations on two overlapping icons with inverted conditions, or use the Graphic property with a Case dynamic in C scripting.
6. Verification Procedure
After wiring the script, perform these checks on the runtime OS (or in WinCC Runtime Simulator):
-
Tag visibility test. Open WinCC Tag Management and confirm
S7$Program(2)/REACTOR.SFC_STATEshows the expected data type (DWORD) and the correct AS connection. - Online value test. In Graphics Designer, press Toolbar → Start Runtime Simulator and add a Numeric I/O field bound to the SFC_STATE tag. Switch the SFC chart between AUTO and MAN from the SFC faceplate; the decimal display must toggle between 536870016 (or 128) and 536875008 (or 4096).
-
Quality code test. Disconnect the network cable from the AS, or stop the S7 communication driver. The numeric field freezes and the quality code in the trace window reports
0x80(Bad). This confirms the read path is real, not a cached value. - Animation test. With the network restored, the icon's visibility should switch within one polling cycle (default 1 s, configured to 2 s above) of pressing the AUTO/MAN toggle button on the SFC faceplate.
7. Common Errors and Troubleshooting
| Symptom | Root Cause | Fix |
|---|---|---|
Runtime error 800A0401 on the line If test = 16#20001000
|
STEP 7 hex literal 16# is not valid VBScript syntax. |
Replace with &H20001000 or the decimal equivalent 536875008. |
| Tag read returns -1 (0xFFFFFFFF) on every cycle | Tag path wrong: Program(2) is the second S7 program in the connection, or the SFC instance DB is in a different program block. |
Re-run "Compile OS", then verify the tag path in WinCC Tag Management. Use the WinCC tag dialog "Find Tag" to locate the actual SFC_STATE symbol. |
| Script returns 0 (AUTO) when the chart is actually in MAN | Bit-mask mismatch: 0x20001000 includes the operator-request flag, and the faceplate also responds to 0x00001000 (internal MAN). |
Use bit masking on bit 12 (0x1000) instead of an exact equality check, or add both 0x20001000 and 0x00001000 to the case list. |
| Value flickers between AUTO and MAN every cycle | Two SFC instances share the same name across programs, or the SFC chart is in the middle of a step transition and the state is being sampled during a transient. | Confirm the SFC instance name is unique. If the chart is in a step-transition, suppress the animation during the cycle in which the SFC_STATE is observed as 0x00000040 (held). |
Quality code reports 0x40 (Uncertain) on a healthy link |
The SFC chart is in the "Completed" or "Aborted" state, which the WinCC channel maps to Uncertain. | This is expected. Treat Uncertain as "not in either AUTO or MAN"; the visibility animation will go to default (false). |
| Read returns the previous value after a server restart | The Tag object was cached. WinCC does not auto-refresh on every read unless objTag.Read is called explicitly. |
Always call objTag.Read before accessing .Value in the script; the runtime will fetch the current PLC value. |
8. WinCC C Scripting Alternative
For high-frequency polling or when the project is built on WinCC Professional (TIA Portal), the C scripting variant is preferred because the VBScript engine is single-threaded and can stall large projects:
#include "apdefap.h"
BOOL _main(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, long lValue, long lResult)
{
DWORD dwState = 0;
dwState = GetTagDWord("S7$Program(2)/REACTOR.SFC_STATE");
if ((dwState & 0x1000) != 0) // MAN bit
return TRUE;
else
return FALSE;
}
C scripting uses the native DWORD type and the bitwise & operator, eliminating the hex-literal conversion and the CLng() cast. The function is registered the same way as the VBScript equivalent, in the Dynamic dialog under the VBScript or C tab.
9. Reading the SFC_STATE on TIA Portal / WinCC Professional
On TIA Portal-based PCS 7 V9 projects, the SFC instance is exposed through the same SFC block in the S7 program. The HMI tag is created by "HMI tags → Add new tag → Connection → S7 connection → SFC chart", and the name is resolved to <SFC chart name>~SFC_STATE in the PLC tag table. WinCC Professional scripts on TIA access it through the JavaScript API:
export function Visible_Trigger(item) {
var tag = Tags("S7$Program(2)/REACTOR.SFC_STATE");
var v = tag.Read();
return (v & 0x1000) !== 0; // MAN bit
}
Note the difference in script language: WinCC Professional uses JavaScript (or VBScript with identical APIs) while WinCC 7.x uses VBScript exclusively. The bit layout of SFC_STATE is identical across both platforms.
10. Quick-Reference: Bit Map of SFC_STATE
| Bit | Hex mask | Decimal | Meaning |
|---|---|---|---|
| 0 | 0x00000001 | 1 | Chart active (running) |
| 1 | 0x00000002 | 2 | Step active in left branch |
| 2 | 0x00000004 | 4 | Step active in right branch |
| 3 | 0x00000008 | 8 | Transition active |
| 4 | 0x00000010 | 16 | Step with confirmation active |
| 5 | 0x00000020 | 32 | Chart aborted |
| 6 | 0x00000040 | 64 | Chart held / completed |
| 7 | 0x00000080 | 128 | AUTOMATIC mode |
| 8 | 0x00000100 | 256 | Restart flag |
| 12 | 0x00001000 | 4096 | MANUAL mode |
| 29 | 0x20000000 | 536870912 | Operator request flag |
The full bit map is documented in the PCS 7 manual SFC for SIMATIC S7 (function manual, entry ID 109751706) and the SFC block help in the S7 program. Always cross-check against the live binary value with the WinCC tag's online display before assuming a bit is unused in your release.
11. Performance and Channel Considerations
Each call to HMIRuntime.Tags(...).Read consumes one cycle slot of the S7 channel. With dozens of SFC faceplates on a single screen, the cumulative channel load can exceed the configured partner connection limit (default 8 connections per CP, 32 connections per AS). Strategies for large projects:
- Cache the SFC_STATE value in a WinCC internal tag updated by a global action at 1 s, and have the VBScript functions read the internal tag instead of polling the AS directly.
- Group the state check into a single C-script function that returns a packed integer with the AUTO/MAN bits, reducing the number of cross-references per faceplate.
- Use Tag prefixing to identify which SFC instance each faceplate is bound to, then maintain a single SFC State Multiplexer script that reads all SFC_STATE tags at the start of every screen.
12. Frequently Asked Questions
Why does VBScript reject the literal 16#20001000?
The 16# prefix is a STEP 7 (S7-STL/SCL) convention. VBScript only accepts the &H prefix for hex literals; use &H20001000 (or the decimal form 536875008) in your faceplate script.
What is the difference between 16#20001000 and 16#00001000 for the SFC_STATE?
Both indicate MANUAL mode. The 0x20000000 bit (present in 0x20001000) is the operator-request flag, set when the AUTO/MAN switch was pressed from the HMI. The lower value 0x00001000 indicates the SFC chart went to MAN via the AS program logic. Faceplate animations should treat both as MAN.
How do I read the SFC_STATE tag from a VBScript faceplate in WinCC 7?
Use HMIRuntime.Tags("S7$Program(2)/<SFCName>.SFC_STATE").Read and read .Value. Cast with CLng() before comparison and prefer bit-masking with And on bit 12 (0x1000) for MAN, bit 7 (0x80) for AUTO.
Does SFC_STATE change during a step transition?
Yes. During a transition, the chart briefly reports the transition-active flag (bit 3, 0x08) and may oscillate between AUTO and MAN depending on the run-time logic. If the icon flickers, lengthen the animation update cycle from 1 s to 2 s, or add a hysteresis on the visibility result.
Can I use the same script on WinCC Professional (TIA Portal)?
Yes. The bit layout of SFC_STATE is unchanged. TIA Portal HMI uses JavaScript (or VBScript) instead of pure VBScript; replace the HMIRuntime.Tags call with the TIA Tags(...).Read() pattern and use the JavaScript bitwise & operator on the result.
What is the decimal value of 16#20001000?
536,875,008. The decimal value of 16#20000080 (AUTO with operator request) is 536,870,016. These two are the most frequently used SFC_STATE values for HMI visibility logic.