WinCC Flexible Discrete Alarm Number to PLC Complete Integration

David Krause13 min read
HMI / SCADASiemensTechnical Reference
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

WinCC Flexible Discrete Alarm Number to PLC: Complete Integration Guide

When a Siemens Comfort Panel, Multi Panel, or Mobile Panel running WinCC Flexible (2008 SP5 and later) raises a discrete alarm, the alarm is identified by a unique internal number assigned in the alarm configuration. Operators see this number (or a derived text) in the alarm view, but the PLC has no native visibility into that number unless the integration is designed in. This reference shows four production-ready methods to expose the active alarm number from the HMI to the PLC, the engineering trade-offs of each, and the path forward to WinCC Unified discrete alarms when the project is migrated.

Scope of this document. WinCC Flexible is the legacy HMI configuration suite replaced by TIA Portal / WinCC Comfort and WinCC Unified. Tag syntax, alarm IDs, and scripting APIs in WinCC Flexible differ from the Unified runtime. Verify every tag and script against the project-specific WinCC Flexible version (Help → About WinCC Flexible) and the target panel firmware before commissioning.

1. Problem Definition and Engineering Constraints

A discrete alarm in WinCC Flexible is bound to a single boolean tag. The HMI runtime evaluates the trigger tag on every acquisition cycle; when the bit transitions, the alarm is raised and the HMI logs it with:

  • An internal alarm number (1…65,536) defined in the alarm editor.
  • A configurable acknowledgement state and state machine (raised, cleared, acknowledged, locked).
  • Optional events that fire on activation, deactivation, acknowledgement, or lock/unlock.

The PLC only knows the bit that was the source of the alarm. It does not natively receive the HMI-side alarm number, timestamp, priority, or text. If a downstream system (SCADA, MES, third-party dashboard) needs the WinCC Flexible alarm number, the HMI must publish it. Three core constraints drive the design:

Constraint Engineering impact
HMI acquisition cycle is decoupled from the PLC OB1 cycle Alarm events arrive asynchronously; the PLC must tolerate gaps of 100–2000 ms between updates.
Multiple alarms can transition in the same HMI cycle Sending a single register only exposes the last alarm written; the application must define a queue or use a different mechanism.
WinCC Flexible scripts run on the panel CPU Heavy VBScript on a 177-series panel or KTP can starve the runtime; prefer PLC-side logic whenever possible.
Alarm numbers are project-local A change in the HMI alarm list breaks the mapping to the external system unless the source of truth is documented and version-controlled.

2. Architecture Overview

The integration pattern is one-directional from HMI to PLC for status and a small back-channel from HMI to PLC for the alarm number. The PLC remains the source of truth for process state; the HMI is the source of truth for the alarm number and operator-facing metadata.

Process / Field Sensors, drives, I/O PLC (S7-300/400/1200/1500) DB of trigger bits + alarm number HMI (WinCC Flexible) Discrete alarms + events External visualization SCADA / MES / dashboard Field signals Trigger bits Alarm number (back-channel) Alarm number + state

The two data flows between PLC and HMI are:

  1. Trigger bits (PLC → HMI): one boolean tag per alarm. The PLC sets/clears these as the source of truth.
  2. Alarm number (HMI → PLC): a 16-bit word (or 32-bit dword) plus a hand-shake bit/strobe carrying the most recent alarm number and optional metadata.

3. Method A — Mirror the Alarm List in the PLC (Recommended)

This is the production-preferred method. The PLC maintains a data block that mirrors the WinCC Flexible alarm table one-for-one. The PLC, not the HMI, is the source of the alarm number, so the back-channel disappears entirely.

3.1 PLC data block layout (S7-300/400 example, STEP 7 V5.x)

Create a shared DB (default DB100) of sufficient size for the project alarm count. For 256 alarms, allocate 32 bytes of bits plus 256 words of metadata:

Address Symbol Type Description
DB100.DBX0.0 … DBX31.7 HMI_Alarm_Trigger[1..256] BOOL One bit per discrete alarm. Bound 1:1 to WinCC Flexible alarm trigger tag.
DB100.DBW32 Active_Alarm_Count INT Number of currently raised alarms (computed in PLC).
DB100.DBW34 Latest_Alarm_Number INT Highest-numbered alarm currently raised; used by external SCADA.
DB100.DBW36 Latest_Alarm_Time INT Seconds since top of hour; combined with date in DW38.
DB100.DBD38 Latest_Alarm_Timestamp DATE_AND_TIME Full timestamp of last transition.
DB100.DBW44 Latest_Alarm_Priority INT Priority field mirrored from HMI project.

3.2 STEP 7 STL snippet to compute the latest alarm number

Scan from the highest alarm number down; the first raised bit wins. This is O(N) but executes in microseconds for N≤512 on an S7-300/400:

// FC 200 "Compute latest alarm"
// Input:  none (uses DB100)
// Output: DB100.DBW34 = latest alarm number, 0 if none
      L     256                      // highest alarm number
      T     #i
NEXT: L     DB100.DBX [#i - 1]      // bit addressed by index
      A     DB100.DBX0.0 + (#i - 1)  // alternative absolute
      JC    FOUND
      L     #i
      LOOP  NEXT
      L     0                        // no alarm raised
      JU    WRITE
FOUND:L     #i
WRITE:T     DB100.DBW34
For S7-1200/1500 in TIA Portal, use a FOR loop over an array of Bool tagged HMI_Alarm_Trigger[1..256] declared in a global DB. The pattern is identical; the address arithmetic is replaced by the array index.

3.3 WinCC Flexible alarm editor binding

  1. Open Alarm Logging and create a new discrete alarm, e.g. number 1.
  2. In the Trigger tag field, browse to the PLC and select DB100.DBX0.0 (Alarm 1), DB100.DBX0.1 (Alarm 2), and so on.
  3. Set the alarm number in the Number column to match the bit offset: bit 0.0 → 1, bit 0.1 → 2, …, bit 31.7 → 256.
  4. Disable any PLC-side logic that would also re-write the same bit; the PLC owns the bit, the HMI only reads.

3.4 Why this wins

  • No back-channel: the alarm number is computed where the data already exists.
  • Deterministic timing: the PLC cycle is the source of timestamps.
  • Survives HMI restart: re-connection automatically re-synchronises the bits.
  • Script-free: no VBScript load on the panel.

4. Method B — HMI Action on Alarm Event (Back-Channel)

When the alarm list cannot be mirrored in the PLC (e.g. alarms are generated inside the HMI because they are local operator prompts, audit prompts, or conditions the PLC cannot see), use the WinCC Flexible event-driven action system.

4.1 Configure the alarm event

  1. In the alarm editor, select the alarm and open Properties → Events.
  2. Click On appearance (or On raising in some builds).
  3. Add a Set tag function that writes the alarm number to a 16-bit PLC tag, e.g. HMI_Last_Alarm_Number.
  4. Optionally, set a second bit HMI_Last_Alarm_Strobe for the PLC to detect the update.

4.2 Hand-shake protocol with the PLC

Step HMI (WinCC Flexible) PLC
1 Alarm n raises Idle, waiting on Busy flag
2 Action: HMI_Last_Alarm_Number := n; HMI_Last_Alarm_Strobe := 1 Detects Strobe rising edge
3 Monitors HMI_Ack_Busy Copies number to PLC_Last_Alarm, sets HMI_Ack_Busy := 1
4 Sees Busy = 1, clears Strobe := 0 Sees Strobe = 0, clears Busy := 0
5 Idle Idle

4.3 Limitations of the action method

  • If two alarms raise in the same acquisition cycle, the action fires twice in undefined order; only the last write is visible to the PLC.
  • The panel must be configured with the VBScript runtime option enabled (default on Comfort Panels).
  • On a 177-series panel with 800 tags, VBScript execution can be 200–800 ms; budget accordingly.

5. Method C — Global VBScript on Runtime Cycle

For projects that need to publish the current alarm number (not the last one to raise), a global VBScript running on the runtime cycle can poll the alarm state and write it to a tag. The relevant API is the HMIRuntime.Alarm object.

5.1 VBScript example (WinCC Flexible 2008 SP5 and later)

' Stored in the project under "Scripts\Global\Project"
Function OnCycle( ByVal lparCycSeconds )
    Dim oAlarm, oResult
    Set oAlarm = HMIRuntime.Alarm

    ' Filter to discrete alarms with priority > 0
    oAlarm.Filter.AlarmClass = 1     ' 1 = discrete in most projects
    oAlarm.Filter.State = 1         ' 1 = active (raised)

    Set oResult = oAlarm.GetCurrent

    If oResult.Count > 0 Then
        SmartTags("HMI_Active_Alarm_Count") = oResult.Count
        SmartTags("HMI_Latest_Alarm_Number") = _
            oResult.Item(oResult.Count).Number
        SmartTags("HMI_Latest_Alarm_Time") = _
            oResult.Item(oResult.Count).RaiseTime
    Else
        SmartTags("HMI_Active_Alarm_Count") = 0
        SmartTags("HMI_Latest_Alarm_Number") = 0
    End If

    Set oResult = Nothing
    Set oAlarm  = Nothing
End Function
The exact member names (HMIRuntime.Alarm vs HmiRuntime.Screens with .Alarms collection) depend on the WinCC Flexible SP level. Always confirm the API against the project Help → Programming Reference → VBScript Reference → Alarm object.

5.2 When to use this method

  • You need a continuous current state (count, latest number) without writing custom logic for every alarm.
  • The HMI is a PC Runtime (not a 177-series panel) and CPU load is not a concern.
  • The PLC supports the SmartTags namespace, which is created automatically in WinCC Flexible/Comfort.

6. Method D — Structured Tag (Array) for Bulk Transfer

When 256+ alarms must be visible to the PLC simultaneously (rare; usually only for synchronous cross-coupling between two PLCs), the HMI can publish the whole array of BOOL states plus a WORD status code per alarm. The PLC then computes the highest active bit locally, exactly as in Method A. This method is functionally identical to Method A from the PLC's perspective; the difference is that the HMI may add metadata (priority, group, suppression state) in a second array.

WinCC Flexible tag Type Direction PLC counterpart
HMI_Alarm_Trigger[1..256] BOOL array PLC → HMI DB100.DBX0.0..DBX31.7
HMI_Alarm_Priority[1..256] INT array HMI → PLC (constant) DB110.DBW0..DBW510
HMI_Alarm_TextID[1..256] INT array HMI → PLC (constant) DB110.DBW512..DBW1022
HMI_Latest_Alarm_Number INT HMI → PLC DB100.DBW34 (read-only)

7. Commissioning and Verification

Once the chosen method is implemented, verify with the following checklist before going live. Use a SIMATIC Panel or HMI simulator and STEP 7 / TIA Portal online watch.

7.1 Static checks (offline)

  1. In WinCC Flexible, open Project → Compiler → Consistency check and resolve every warning related to alarm trigger tags.
  2. In the PLC, compile the project (Build → Rebuild all). Confirm no implicit type conversions on the alarm number word.
  3. Open the WinCC Flexible Tag simulation and force every alarm trigger bit high in turn; confirm the alarm appears with the correct number in the alarm view.

7.2 Dynamic checks (online with simulator)

  1. Start WinCC Flexible Runtime on the engineering PC with the S7-PLCSIM coupled.
  2. In PLCSIM, set DB100.DBX0.10 (alarm 11) to TRUE. Confirm the alarm appears in the runtime within one HMI acquisition cycle.
  3. Watch DB100.DBW34 in PLCSIM and confirm it reads 11.
  4. Set DB100.DBX0.10 to FALSE and DB100.DBX0.50 (alarm 51) to TRUE. Confirm DB100.DBW34 updates to 51.
  5. Toggle 3 alarms in the same PLC cycle; verify the HMI logs all three and the PLC word shows the highest number.

7.3 Acceptance criteria

Criterion Target How to verify
Latency from PLC bit set to PLC word update ≤ 2 HMI acquisition cycles Cross-trigger an oscilloscope on the bit and the word via HMI trace
Alarm-number correctness for 100 random triggers 100% match Auto-test with a watch table forcing sequential bits
PLC CPU load after enabling the FC ≤ +2 ms on a 315-2 PN/DP Compare OB1 execution time before/after
HMI script CPU on a 177B 6" ≤ 30% Use System Diagnostics → CPU load

8. Edge Cases and Field-Proven Caveats

  • Alarm number vs. alarm ID. WinCC Flexible exposes a project-local number (1…65,536) and a runtime-assigned ID (a GUID-like handle). The external system must use the number, not the ID, because IDs are not stable across project rebuilds.
  • Alarm number reuse. If you delete alarm 200 and re-create it as a different condition, the number 200 now refers to new semantics. Maintain a separate change-log CSV in source control.
  • Multilingual projects. The number does not change with language switching, but the text does. If the external system needs the localized text, the HMI must also publish a text-ID word that the SCADA can map to its own string table.
  • Acknowledgement state. WinCC Flexible tracks four states: raised, cleared, acknowledged, locked. A bit-only transfer cannot distinguish these. If the external system needs the state, add a second word per alarm (16 bits) or use the structured-array method.
  • Acquisition cycle vs. update cycle. Setting the trigger tag acquisition to 1 s on a 50-ms PLC OB1 is a common cause of "missed" alarms. Use 100 ms or 200 ms for fast processes; use 1–2 s for slow ones.
  • Panel restart. After a panel reboot, the HMI re-reads the trigger bits. If the PLC does not re-assert them, the alarms clear on the panel. The PLC must keep the trigger bits latched until the condition is genuinely gone, not just until the operator acknowledges the alarm.
  • Tag length limits. WinCC Flexible on a 177-series panel limits a single tag to 200 bytes. An array of 256 INTs is 512 bytes, exceeding the limit; split into two tags of 128 INTs each, or use Method A (bit-only). The Comfort Panel (TIA Portal) raised the limit to 4096 bytes per tag.

9. Migration to WinCC Unified

WinCC Flexible is end-of-life and has been superseded by WinCC Unified discrete alarms in TIA Portal. The migration is non-trivial because:

  • The trigger tag model changed: Unified uses alarm conditions in the PLC or HMI, evaluated by a separate alarm engine.
  • The VBScript API is replaced by JavaScript with the HMIRuntime.Alarming namespace.
  • Alarm numbers are now 32-bit (DWORD) and include a configurable source ID.

For projects that already use Method A, the migration is straightforward: the PLC-side DB remains, the alarm list in the Unified project points to the same trigger tags, and the optional metadata is published via the new alarm-state tag interface. For projects that rely on the VBScript global cycle, the equivalent code in Unified is:

// TIA Portal V18+, JavaScript in a global module
import { Tag } from "HMIRuntime";

export function OnAlarmCycle() {
    let active = HMIRuntime.Alarming.GetActiveAlarms("DiscreteAlarms");
    if (active.length > 0) {
        Tag("HMI_Active_Alarm_Count").Write(active.length);
        Tag("HMI_Latest_Alarm_Number").Write(active[active.length - 1].Number);
        Tag("HMI_Latest_Alarm_Time").Write(active[active.length - 1].RaiseTime);
    } else {
        Tag("HMI_Active_Alarm_Count").Write(0);
        Tag("HMI_Latest_Alarm_Number").Write(0);
    }
}
Before any migration, run the TIA Portal Project migration wizard on a copy of the WinCC Flexible project. The wizard reports every alarm that cannot be converted automatically, which is the starting list for the engineering effort.

10. Comparison of Methods

Criterion A. PLC mirror B. Action event C. Global VBScript D. Bulk array
PLC load +0.1–0.5 ms 0 0 +0.5–1.0 ms
HMI load 0 low medium–high low
Survives HMI restart yes yes (re-fires events on re-eval) yes yes
Multi-alarm same cycle handled by PLC only last visible handled by VBS handled by PLC
Configuration effort medium high (per alarm) low (one script) medium
Best fit any project ≤1024 alarms small projects, few events PC Runtime cross-PLC coupling

11. Frequently Asked Questions

What is the maximum number of discrete alarms in WinCC Flexible?

Up to 4,000 discrete alarms are supported on a Comfort Panel, 2,000 on a 177-series, and 8,000 on a WinCC Flexible PC Runtime. The limit is defined in the project settings; increasing it requires recompilation of the runtime.

Can the PLC read the alarm text, not just the number?

Not directly. WinCC Flexible stores the text in the panel's string table, indexed by the alarm number. The PLC must reference a parallel text table it maintains itself, or the SCADA must read the HMI text via OPC UA on a Unified panel. The pattern shown in Method A uses a Word tag and a documented CSV in source control.

Why does the alarm appear in the HMI but DB100.DBW34 still reads 0?

Three common causes: (1) the FC that computes the latest number is not called in OB1; (2) the alarm trigger tag is the wrong DB byte offset, so the bit does not actually exist; (3) the HMI acquisition cycle is still loading the tag after a project download. Force a tag refresh on the panel (System → Tag simulation → Update) and check the HMI diagnostics buffer.

What happens if the HMI goes offline while an alarm is raised?

The PLC keeps the trigger bit latched. When the HMI reconnects, it re-evaluates all trigger tags and the alarm reappears in the alarm view with a fresh timestamp. The PLC Latest_Alarm_Number word does not change because the source state did not change; if the external system needs to know the alarm re-appeared, use the alarm's Appearance event (Method B) or have the SCADA poll the HMI status OPC tag.

Can the alarm number be exposed via OPC DA/UA to a non-Siemens SCADA?

Yes. Expose the PLC tag holding the number (e.g. DB100.DBW34) as an OPC item on the S7-1500 OPC UA server, or use a WinCC Comfort OPC DA server. The tag is read-only on the HMI side, so security policies can be set to deny write access. The SCADA then receives the number in real time without needing a direct PLC driver.

Back to blog