1. Problem Overview
Engineers commissioning a Siemens SIMATIC HMI frequently need to expose a single PLC word (for example DB10.DBW0 with the symbolic name Steuerbits) as a panel of sixteen discrete switches. The PLC only allocates one WORD of memory, but the operator needs to read and toggle every single bit independently. The naive approach—binding each of the sixteen buttons to a separate %DB10.DBX0.0...%DB10.DBX1.7 address—works for read access but does not work for write access on a Word tag, because the HMI writes the entire 16-bit value atomically and overwrites sibling bits.
This reference covers the three production-grade patterns that solve the problem inside Siemens TIA Portal / WinCC V7 environments:
- CheckBox Control bound to the Word process tag with bit index.
- Operator button with VBScript using
HMIRuntime.Tags.SysFct.SetBitInTagandResetBitInTag. - Compound approach with global tags and an auxiliary script that updates only the target bit.
Byte-swap and endianness pitfalls (the reason a bit-toggle sometimes lights the wrong LED) are documented in §6.
2. Word Tag Architecture and Bit Addressing
A 16-bit WORD consists of two BYTEs: the high byte holds bits 8–15 and the low byte holds bits 0–7. In SIMATIC S7 nomenclature the lowest address is always the low byte:
| Bit Index | Byte | Absolute Address | Symbolic (example) |
|---|---|---|---|
| 0 | Low (byte 0) | %DB10.DBX0.0 | Steuerbits.Bit0 |
| 1 | Low (byte 0) | %DB10.DBX0.1 | Steuerbits.Bit1 |
| 7 | Low (byte 0) | %DB10.DBX0.7 | Steuerbits.Bit7 |
| 8 | High (byte 1) | %DB10.DBX1.0 | Steuerbits.Bit8 |
| 15 | High (byte 1) | %DB10.DBX1.7 | Steuerbits.Bit15 |
WinCC Runtime stores the WORD in a single HMI tag, but it stores individual bit addresses as overlay tags of the same memory. Bind the HMI tag as:
- Data type: WORD (UInt)
- PLC tag: the 16-bit word in the controller data block
- Acquisition mode: Cyclic in operation (default 1 s) for visibility, Event-driven for bit toggles
For the HMI to be allowed to write the tag, the PLC connection must include operator authorization for that area. The PLC block typically looks like this in SCL:
FUNCTION_BLOCK FB_ControlWord
VAR
bSteuerbits : WORD; // HMI writes, logic reads
END_VAR
bSteuerbits := 0; // initialise at first scan if needed
// Use bSteuerbits.X0..bSteuerbits.X15 in the program
3. Method 1 — CheckBox Control Bound to the Word Tag (Recommended)
The CheckBox graphic object inside the WinCC screen designer accepts a single 16-bit process tag and exposes a BitIndex property (0–15). When the operator clicks a checkbox, Runtime reads the current WORD, sets/clears the selected bit, and writes the WORD back to the PLC atomically. Sibling bits are never disturbed. Visual feedback is automatic: a checked box equals 1, unchecked equals 0.
3.1 Configuration Steps
- Open the WinCC screen in the TIA Portal graphics designer (or WinCC V7 Graphics Designer).
- Drag a CheckBox from the toolbox onto the screen.
- Repeat fifteen times so you have exactly sixteen checkboxes, or use the CheckBox Group object (WinCC Unified) which produces all sixteen in a single control.
- For every checkbox:
-
Process tag → your HMI tag of type WORD, e.g.
Steuerbits. - BitIndex → 0 for the first, 1 for the second, … 15 for the last.
- BitNumbered → enable if you want the bit number printed in the label.
- Tooltip → enter the human-readable function (e.g. "Pump 1 enable").
-
Process tag → your HMI tag of type WORD, e.g.
- Arrange the sixteen checkboxes in a 4×4 or 2×8 grid, optionally using the Layered arrangement feature for a clean layout.
- Compile and download to the Runtime.
Bit0..Bit15 as member properties. See the Siemens WinCC Unified Help for the property schema.4. Method 2 — Operator Button with VBScript and SetBitInTag
Where the design requires a tactile push-button (not a checkbox) you can attach VBScript to a Button object's Click event. WinCC Runtime exposes two dedicated bit-level helpers in the HMIRuntime.Tags.SysFct namespace:
| Function | Signature | Behaviour |
|---|---|---|
| SetBitInTag | SetBitInTag(ByVal TagName As String, ByVal Bit As Long) | Sets the addressed bit to 1; all other bits of the tag are preserved. |
| ResetBitInTag | ResetBitInTag(ByVal TagName As String, ByVal Bit As Long) | Clears the addressed bit to 0; sibling bits are preserved. |
| ToggleBitInTag | ToggleBitInTag(ByVal TagName As String, ByVal Bit As Long) | Inverts the addressed bit. |
| GetBit | GetBit(ByVal Value As Long, ByVal Bit As Long) As Boolean | Returns the state of a single bit inside a value already read into the script. |
The functions are documented in the Siemens WinCC V7 / WinCC Professional Scripting Reference under the VBScript reference manual. The function names and namespace match the COM automation model used by WinCC Runtime.
4.1 Toggle a Single Bit on Click
Add this VBScript to the Click event of a button labelled, for example, "Toggle Bit 15":
Option Explicit
Sub OnClick(ByVal Item)
Dim sTag
sTag = "Steuerbits" ' HMI tag name (must exist in tag management)
Dim iBit
iBit = 15 ' Bit number 0..15 for a WORD
' Read current value
Dim hmiTag
Set hmiTag = HMIRuntime.Tags(sTag)
hmiTag.Read
If (hmiTag.Value And (2 ^ iBit)) = 0 Then
' Bit is currently 0 → set it to 1
HMIRuntime.Tags.SysFct.SetBitInTag sTag, iBit
Else
' Bit is currently 1 → clear it to 0
HMIRuntime.Tags.SysFct.ResetBitInTag sTag, iBit
End If
End Sub
4.2 The Original Symptom — Wrong Bit Getting Set
The user reported the following call seemingly setting a bit other than bit 15:
HMIRuntime.Tags.SysFct.SetBitInTag "Steuerbits", 15
This is almost always a byte-swap symptom, not a bug in SetBitInTag. See §6 for the full root-cause analysis. The most common causes are:
- The same data is also written through a checkbox or by a separate script that re-orders the bits, causing the bit that is "set" to be displayed at a different visual index.
- Two HMI tags (
Steuerbitson one connection,Steuerbits_HMIon another) point at adjacent or byte-swapped memory. - OPC DA / OPC UA clients are reading the tag with reversed byte order (little-endian vs. big-endian).
To prove that the function itself is correct, run this diagnostic once and verify the result on the PLC (e.g. with VAT or a watch table):
Sub OnClick(ByVal Item)
' Force bit 15 ON and log
HMIRuntime.Tags.SysFct.SetBitInTag "Steuerbits", 15
HMIRuntime.Trace "Steuerbits = " & _
Hex(HMIRuntime.Tags("Steuerbits").Value) & vbCrLf, _
"BitDiag", 1
End Sub
If the trace line reads 0x8000 (i.e. bit 15 is set) and the PLC VAT confirms the same value, the script is correct and the issue is purely visual/byte-ordering.
5. Method 3 — Compound Approach with Internal Tags
For panels that need to perform bit-wise logic (e.g. "set bits 0, 3, 7 simultaneously") you can read the WORD into an internal HMI tag, manipulate it locally, and write it back. This is rarely needed for a simple toggle but is the most flexible pattern.
Sub OnClick(ByVal Item)
Dim oTag, lValue
Set oTag = HMIRuntime.Tags("Steuerbits")
oTag.Read
lValue = CLng(oTag.Value)
' Set bit 4, clear bit 5, toggle bit 6 in one transaction
lValue = lValue Or (2 ^ 4) ' Set bit 4
lValue = lValue And Not (2 ^ 5) ' Clear bit 5
lValue = lValue Xor (2 ^ 6) ' Toggle bit 6
oTag.Value = lValue
oTag.Write
End Sub
Always Read immediately before Write to avoid race conditions if other HMI clients are also writing the tag.
6. Byte-Swap and Endianness Pitfalls
SIMATIC S7 PLCs store multi-byte values in big-endian format (high byte first). WinCC Runtime, OPC DA servers, and most Windows-based visualisation tools can interpret the same WORD as little-endian when it crosses a PC-side boundary. The result is that bit 0 and bit 8 swap visual positions, and the user reports "I'm setting bit 15 but bit 14 lights up".
| Cause | Symptom | Fix |
|---|---|---|
| Two tags configured on overlapping memory (e.g. one reads DBW0, another DBW2) | Visual bit position does not match PLC | Re-create tags, ensure unique addresses |
| OPC DA client connects to WinCC and reads the same tag in a different byte order | External SCADA shows mirrored bits | Force "Word swap" / "Motorola byte order" off in the OPC server |
HMI tag bound as INT but data block declares WORD
|
Sign bit (bit 15) reads as bit 0 in I/O field | Change HMI tag type to UInt / WORD
|
Checkbox BitIndex shifted by 8 because designer assumes byte 0 is the high byte |
First eight checkboxes mirror last eight | Use CheckBox Group (Unified) which auto-corrects; manually verify BitIndex in V7 |
0x8000 means bit 15 is set; 0x0001 means bit 0. The diagnostic value stays correct regardless of checkbox layout, so it is the ground truth.7. Configuration Reference Table
| Parameter | CheckBox Control | VBScript Button | Compound Script |
|---|---|---|---|
| Best for | 16 independent on/off states | Single-bit toggle, momentary action | Multi-bit set/clear/toggle in one event |
| Visual feedback | Automatic, per checkbox | Manual (re-read tag and drive graphic) | Manual |
| Atomicity | Word-level, Runtime-managed | Word-level, Runtime-managed | Read-Modify-Write window (race risk) |
| Tag type | WORD / UInt16 | WORD / UInt16 | WORD / UInt16 |
| Bit range | 0–15 | 0–15 | 0–15 |
| Commissioning effort | Low | Medium | High |
8. S7-1200 / S7-1500 Symbol Exposure for HMI
When the source tag lives on an S7-1200 or S7-1500, expose the data block to the HMI connection:
- In TIA Portal, open the DB that contains
SteuerbitsasWORD. - Right-click the DB → Properties → Attributes → tick "Accessible from HMI".
- Disable "Optimised block access" if the HMI is older than V14 or if the connection is S7-300/400 compatible.
- Drag the variable from the project tree into the HMI tag table; the type is preserved as WORD.
- Verify the symbolic bit accessors (
"Steuerbits".X0...X15) by opening the DB and confirming the row is unchecked in "Not accessible from HMI".
Refer to the Siemens S7-1200 / S7-1500 System Manual for the canonical rules on optimised data blocks and HMI visibility. Word tags marked as non-optimised keep their byte order predictable for the HMI.
9. Verification and Commissioning Procedure
- Compile the HMI project (Build → Rebuild all) and resolve any tag errors. The tag table must show
Steuerbitswith the same name used in the script. - Start the Runtime in simulation mode. The Tag Simulator should show
Steuerbitsstarting at 0. - Click each checkbox in turn. The corresponding bit LED on the simulated PLC should illuminate and the HMI tag value should switch between 0x0001, 0x0002, 0x0004, … 0x8000.
- Bind a numeric I/O field in Hex display. Set all sixteen checkboxes; the field must read
0xFFFF. Clear all; the field must read0x0000. - From a VAT / watch table on the PLC, write a value (e.g.
W#16#1234) into the data block. The HMI checkboxes must reflect the binary breakdown 0001 0010 0011 0100 within one acquisition cycle. - Test race condition: click two checkboxes in rapid succession. Both must end up in the requested state and the I/O field must match the value reported by the PLC.
- Test byte-swap scenario described in §6: temporarily change the HMI tag type to
INTand observe the I/O field. Restore toWORD/UIntfor production.
10. Troubleshooting Matrix
| Symptom | Likely Root Cause | Action |
|---|---|---|
| Checkbox shows correct state but writing it does nothing | HMI has no write privilege on the tag area | Check PLC connection → Operator authorisations; add tag to a write-allowed area |
| Clicking a checkbox sets a different bit | Byte-swap or duplicate tag address | Bind a Hex I/O field to the same tag for ground truth; remove duplicate tag definitions |
| SetBitInTag returns no error but PLC value unchanged | Tag name mismatch between script and tag management | Confirm casing and namespace; use HMIRuntime.Tags("Steuerbits").Name in a trace |
| Two operators toggling the same bit overwrite each other | Read-Modify-Write race in compound scripts | Use SetBitInTag / ResetBitInTag instead of read-modify-write |
| Script error: "Object doesn't support this property or method" | Calling SysFct from the wrong Runtime (Unified uses different API) | For WinCC Unified use HMIRuntime.UI.SysFct or the JavaScript wrapper |
| All sixteen checkboxes appear pressed | Wrong data type (DWORD interpreted as WORD) or signed-int sign extension | Change HMI tag to UInt16 / WORD and reload Runtime |
| Button click toggles bit on the HMI but PLC stays at 0 | PLC connection uses "Read only" put/get direction | Change connection properties to "Read/Write" on the affected DB |
11. Performance and Safety Notes
- Avoid running SetBitInTag in a 100 ms cyclic script. Each call performs a Read-Modify-Write cycle on the HMI tag and round-trips to the PLC; excessive polling starves the S7 connection. Use event-driven acquisition.
- Bit toggles via HMI should always go through authorised operator areas. Combine with SIMATIC Logon for traceability.
- If the WORD drives safety-relevant outputs, treat the HMI as a non-safety interface. The PLC must contain its own plausibility checks (e.g.
AND-mask of allowed bit combinations) before acting on the HMI word. - For 32-bit DWORDs the same APIs apply; the bit range becomes 0–31. Mind the byte-swap risk, which doubles.
Why does my checkbox write a different bit than I selected?
The most common reason is a duplicate HMI tag pointing at overlapping PLC memory, or the HMI tag being declared as INT instead of WORD/UInt16. Bind a numeric I/O field in Hex display to the same tag; if the hex value matches the PLC VAT, the script is correct and the issue is visual layout or a second tag definition.
Can SetBitInTag address bits 16–31 in a DWORD?
Yes. SetBitInTag and ResetBitInTag accept any bit index 0–31 when the HMI tag is a DWORD. Pass 16 for the lowest bit of the high word, 31 for the highest. Sibling bits are always preserved.
Does the CheckBox Control work in WinCC Unified the same as in WinCC V7?
The control is conceptually identical, but in WinCC Unified the VBScript namespace HMIRuntime.Tags.SysFct is replaced by the JavaScript / C# API HMIRuntime.UI.SysFct (or the unified Tags object). Use the CheckBox Group control in Unified for a single UI element that exposes all sixteen bits of a UInt16 process tag.
What is the safest method to write a single bit in a critical application?
Use the dedicated SetBitInTag / ResetBitInTag functions, which perform a read-modify-write atomically inside Runtime and preserve the other bits. Avoid raw Read-Modify-Write in custom scripts because they open a race window if two HMI stations write the same tag concurrently.
How do I display the bit state on the button face when using a script-driven button?
Bind the button's Pressed / Background flash property to the bit address (Steuerbits.Bit0 for bit 0, etc.) or use a separate graphic I/O field next to the button driven by the same bit. The CheckBox Control handles this automatically.