Resolving SetBitInTag Error on Bool Array Tags in WinCC Advanced

David Krause13 min read
SiemensTroubleshootingWinCC
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

Problem: Command Button Set Bit Fails on Bool Array Tags

A common commissioning symptom in TIA Portal projects is a screen Button event that refuses to accept a PLC Bool array tag in the SetBitInTag / ResetBitInTag / InvertBitInTag parameter list. The runtime compiles the screen but the HMI editor immediately returns the validation message:

Tags of this data type are not allowed for this parameter.

The same array tag is fully functional for read-side uses - it drives animations, visibility toggles, I/O field read-out, and dynamic text without complaint. The restriction is therefore not a generic limitation on Bool[] HMI tags; it is specific to the write-side bit-manipulation system functions that TIA binds to Button events. The problem reproduces from TIA Portal V15 through V18 and is not tied to a specific service pack of the engineering software.

A Bool array bound to SetBitInTag is rejected. A Bool UDT element of the form Array[i].Bit is accepted on the same event. The data type that wraps the bit is the only difference, and that single UDT layer is the practical workaround.

Affected Software and Hardware

Component Identifier Notes
Engineering TIA Portal V15.0 / V15.1 / V18 Reproduced on V15 and confirmed still present in V18
Runtime SIMATIC WinCC RT Advanced PC-based runtime, article number 6AV2 104-0xxxx-xxx (the lower three blocks vary with license size)
HMI device type SIMATIC PC Station The PC station is the runtime host; the HMI software can also be Comfort/Advanced panel firmware
PLC S7-1200 / S7-1500 Bool array originates in an optimized data block; symbolic access required
Screen object Button → Click / Press / Release Event handler: SetBitInTag (system function)
Tag Array[0..31] of Bool inside DB Pulled from PLC tag list, not hand-typed

Equivalent runtime products in the WinCC family (Comfort Panels running WinCC Comfort/Advanced firmware, SIMATIC HMI panels that share the same engineering surface) reproduce the same dialog. WinCC Professional (article number 6AV2 105-...) is not affected by this binding restriction because its VB / C scripting allows direct array-element writes.

Root Cause Analysis

The SetBitInTag system function exposed in the HMI event configurator expects a single Bool tag at its parameter pin. The function is generated from the same WinCC script namespace used by VBScript routines, and its parameter definition in the TIA Portal help explicitly lists the accepted data types. The HMI tag table exposes the PLC array as a composite Array of Bool data type; when the engineer drags that array element into the SetBitInTag parameter, the type checker in the screen editor rejects the assignment because the function signature demands a scalar Bool and not a one-dimensional Array of Bool.

The internal reason TIA enforces this is tied to runtime consistency. When the HMI writes to one element of an array, the WinCC Advanced communication driver has to repackage the full array and write it back to the PLC in a single PUT operation. If the PLC program is concurrently writing a different element of the same array on the same scan, the HMI write would clobber the PLC's update - a classic read-modify-write race. Siemens' TIA Portal Help (F1) comment on SetBitInTag documents the constraint: the system function is intended for atomic write of an individual bit, not an array element. Because WinCC RT Advanced does not have the multi-write optimisation that the larger runtime products have, the engineering front-end disables the binding outright rather than silently writing unsafe data.

The GetBitFromTag read-side equivalent does not have the same restriction when the array tag is bound to a non-event property (visibility, text, value), because those properties are refreshed on a poll cycle, not written back to the PLC. That asymmetry is why the same array works for animations but fails for Button events.

Workaround 1 - Wrap Each Bit in a Bool UDT

The cleanest engineering fix is to define a UDT with a single Bool member and build the HMI-facing tag as an array of that UDT instead of an array of Bool. The HMI tag type-checker accepts UDT_Array[i].Bit because the UDT is a structured type, the property .Bit resolves to a scalar Bool, and the array element binding matches the system-function signature.

Procedure:

  1. In the PLC program, create a new UDT named e.g. UDT_CmdBit with exactly one member: Bit : Bool.
  2. In the data block, change the relevant section from Array[0..31] of Bool to Array[0..31] of "UDT_CmdBit" (or use a separate DB that mirrors the command-word structure of the original DB).
  3. If the downstream PLC logic depends on the original flat Bool array, copy the bits with a simple assignment in the PLC program: CMD_OLD[i] := CMD_UDT[i].Bit; for each index, on a low-priority OB. This is a no-cost CPU instruction on S7-1200 / S7-1500.
  4. Recompile the PLC, then in the HMI tag table update the HMI tag's PLC reference to the new Array of UDT_CmdBit.
  5. In the screen, drag HMI_Cmd[1].Bit onto the SetBitInTag parameter of the Button click event. The validation passes.
UDT wrapping is a structural change, not a runtime hack. It survives upgrades, exports cleanly with the PLC source, and keeps the HMI configuration portable. The downside is the mirror copy if you must keep the original flat array, but the cost is one indexed move per cycle per bit - negligible on a 1500.

Workaround 2 - Create Discrete HMI Bool Tags

The simplest, most defensive fallback is to give up the array and create one HMI Bool tag per bit. The HMI tag table accepts scalar tags that mirror individual PLC bits, and SetBitInTag binds them without complaint.

Procedure:

  1. Open the HMI tag table.
  2. Add a new tag for every bit you need to set. Use the same PLC address but a fresh HMI tag name (e.g. HMI_Cmd_00, HMI_Cmd_01, ... HMI_Cmd_31).
  3. Bind each Button event to its dedicated SetBitInTag(HMI_Cmd_NN, 1) call.
  4. If the number of buttons grows past ~16, switch to a tag-prefix convention in the HMI tag table and bulk-edit the address field.

This is the approach the Siemens forum responder recommended. It scales poorly past about 32 tags because the HMI tag table becomes a maintenance burden, but it requires no PLC changes and no scripting. For systems with fewer than a dozen command bits, it is the lowest-risk option.

Workaround 3 - Use a Non-Optimized DB and a Word/DWord Tag

On S7-1500, the optimised block access attribute of a data block prevents the HMI from pulling individual bits through a 16-bit or 32-bit word tag. Disabling optimised access on the DB (block attribute Optimised block access = unchecked) exposes the data as a contiguous WORD or DWORD image. The HMI can then bind a 16-bit or 32-bit Word tag, and SetBitInTag on the word tag writes the desired bit to the correct bit position in the PLC.

  1. Right-click the data block in the project tree, choose Properties, and uncheck Optimised block access. Confirm with the compiler prompt that the change will be downloaded.
  2. Document the starting byte offset of the command array (e.g. %DB20.DBX0.0 for bit 0, %DB20.DBX0.1 for bit 1, etc.).
  3. Create one HMI Word or DWord tag per logical command word. Point its PLC address to the byte area of the DB. e.g. DB20.DBW0 for the first 16 bits, DB20.DBD2 for bits 16 to 47.
  4. Bind each Button event with SetBitInTag("HMI_CmdWord_0", 1) and use the bit-position parameter that the function exposes in its extended form. The function writes the bit through PUT to the addressed word in the PLC.
  5. On the PLC side, use the standard bit-test instructions (DBX0.0 symbolic form) in your logic - the wire format is unchanged.
Non-optimised block access is a S7-1500 tradeoff. It removes the limit-checking of optimised blocks, prevents the compiler from reordering the data layout, and disables some download-without-reinitialise scenarios. Use this workaround only when the command-word pattern matches your existing logic and the project does not require optimised-block guarantees.

Workaround 4 - Use a VBScript Routine

WinCC RT Advanced supports a subset of VBScript attached to events. A script can use the HMIRuntime object and the SmartTags collection to read the array, modify a single bit, and write the whole array back. This is the workaround that the source thread's first responder warned against for Comfort Panels but that is fully usable on a PC-based RT Advanced installation.

' VBScript attached to Button Click event
Dim arr, idx
Set arr = SmartTags("HMI_CmdBits")      ' Array[0..31] of Bool
idx = SmartTags("HMI_ButtonIndex")       ' Bound to a tag for which bit to set
arr(idx) = True
SmartTags("HMI_CmdBits") = arr           ' Write back as a whole array

The write-back is what makes this approach non-atomic: between the read of arr and the assignment back, the PLC may have changed a different element. For commands that are not safety-relevant, the multi-millisecond poll period of the HMI is normally acceptable. For interlocks, use Workaround 1 (UDT) and accept that the bit-set still has to round-trip through the array write - there is no way around the full-array write in WinCC Advanced without a script-side mutex.

VBScript in WinCC RT Advanced is the same engine that the SetBitInTag system function is built on. Using it directly does not give stronger atomicity guarantees; it just lets you bypass the parameter type-check. The conceptual model is documented in the Microsoft .NET BitArray.Set(Int32, Boolean) reference for the general bit-at-index idea, even though the WinCC script runtime is VBScript and not .NET.

Verification and Test Procedure

After applying any of the workarounds, run the following verification sequence to confirm the Button event actually writes to the PLC and the HMI display reflects the change:

  1. Build the HMI and PLC, then download to the PC Station and the S7-1500 (or S7-1200) controller.
  2. Start the runtime. Open the HMI screen that contains the Button.
  3. Open an online watch table in the PLC project for the relevant data block. Force a break in the PLC program if you need deterministic observation.
  4. Click the Button. Verify the corresponding bit in the DB transitions to TRUE within one HMI poll cycle (default 1 s; configurable in the connection properties).
  5. Click the Button again. Verify the bit returns to FALSE if the event uses a toggle, or remains TRUE if the event uses a momentary press/release pattern.
  6. Trigger a different Button in the same screen that uses a different bit of the same array (or UDT array). Verify the first bit is not clobbered. This is the race condition that SetBitInTag was guarding against in the optimised case.
  7. Watch the WinCC RT Advanced diagnostic viewer for the connection status. The connection icon must remain green throughout the test - any loss of connection to the PLC will surface as a write that does not stick.

For the UDT workaround, additionally confirm the mirror assignment in the PLC program executes every cycle. Place a watch on the mirror DB and verify the bit pattern matches the HMI-side array within one PLC cycle.

Troubleshooting Matrix

Symptom Likely Cause Action
Validation error appears immediately on Button click Bound HMI tag is Array of Bool; SetBitInTag only accepts scalar Bool Apply Workaround 1 (Bool UDT) or Workaround 2 (discrete HMI tags)
Button writes to PLC but PLC reads stale value PLC is overwriting the same array element faster than the HMI poll cycle Switch to a non-array scalar tag (Workaround 2) or add a PLC-side handshake tag
VBScript writes do not stick Script modifies a local copy, not the SmartTag reference, before write-back Read the SmartTag into a local arr, mutate arr, assign back to SmartTags(...)
Non-optimised DB download fails with active values retained Optimised-block attribute is checked and the controller is in RUN with retain data Perform download with Reset or stop the CPU before changing the block attribute
Same array works in V15, fails in V18 No regression - the dialog was already wrong in V15 but TIA V18 enforces the type check more strictly Apply UDT workaround; it works in both versions
Tag not visible in tag table for binding HMI tag was typed by hand in the HMI table instead of pulled from the PLC tag list Delete the hand-typed tag and drag the PLC array from the project tree to recreate the HMI tag
Write succeeds but alarm log shows communication error PUT packet collision with concurrent PLC-side array write Move HMI command bits to a dedicated DB that the PLC only writes in a single OB

Version Notes and Upgrade Caveats

The binding restriction is preserved in every TIA Portal release tested through V18. The change between V15 and V18 is in the editor's strictness, not in the runtime behaviour - a screen configured in V15 with a workaround applied continues to work after a V18 upgrade. If you are migrating an existing project that already has working Button events bound to flat Array of Bool tags, recompile in V18 and inspect each event; the editor will re-validate and may downgrade the binding to a warning rather than a hard error in some configurations. Treat that warning as an error in production code.

WinCC RT Advanced is sold in 128 / 512 / 2048 / 4096 power-tag sizes (article number 6AV2 104-1xx02-xxx for 128 PT, ... -2xx02-xxx for 512 PT, etc.). A Bool UDT array counts as one HMI tag per element, just like a flat Bool array. There is no licensing impact of switching from a single array HMI tag to 32 discrete HMI tags - the runtime does not distinguish tag structures for power-tag accounting.

Recommendation

For new projects, define the command-word DB as an array of a Bool UDT from day one. The cost is one UDT type and one indexed mirror assignment; the benefit is that every Button event in WinCC RT Advanced binds cleanly, the HMI tag table is self-documenting, and the configuration migrates without rework between TIA Portal versions. For retrofit projects with a flat Bool array in production, Workaround 3 (non-optimised DB + Word/DWord tag) requires the fewest PLC changes and the fewest HMI tags. Workaround 2 (discrete HMI Bool tags) is the defensive choice when the controller's safety case forbids any structural change to the DB.

Why does TIA Portal reject a Bool array for SetBitInTag on a Button event?

The SetBitInTag system function expects a scalar Bool at its parameter pin, not an Array of Bool. The TIA editor's type-checker rejects the binding to prevent full-array PUT writes from racing with PLC-side array writes. The same array works for read-side properties (visibility, value, animations) because those use polling rather than event-driven writes.

Will upgrading from TIA Portal V15 to V18 break a project that already uses a Bool array with SetBitInTag?

If the V15 project compiled with a Bool array bound to SetBitInTag, the V18 editor will re-validate the binding and flag it. Apply the Bool UDT workaround (Workaround 1) before upgrading, or expect to re-bind each Button event to a discrete HMI tag or to a wrapped UDT element.

What is the simplest fix for a single-screen demo with one command bit?

Create one HMI Bool tag that points to the same PLC bit the array element would have addressed, and bind that scalar tag to SetBitInTag. The array is unnecessary in a single-button scenario and can stay in the PLC DB for other consumers.

Can a VBScript in WinCC RT Advanced write a single bit of an Array of Bool atomically?

No. The script reads the whole array, mutates the local copy, and writes the array back to the PLC as a single PUT. Any PLC-side write to a different element in the same array between the read and the write is lost. For atomic single-bit writes, use the UDT-array pattern or a dedicated scalar HMI tag.

Does the Bool UDT workaround add CPU scan time on S7-1500?

The mirror assignment is one indexed move per bit per cycle. On a 32-bit array, the cost is 32 SCL := operations, on the order of a few microseconds on an S7-1511 and negligible on S7-1515/1516/1518. It is well below the budget of any normal OB1 cycle.

Why does the same array work in visibility animations but not in Button events?

Visibility and value animations are read-only and are refreshed on the HMI poll cycle. Button events using SetBitInTag trigger a write-back to the PLC. The type restriction applies only to the write-side system function; the read-side bindings to the same array remain valid.

Back to blog