Stabilizing Program_Alarm IDs on TIA Portal Recompile S7-1500

David Krause19 min read
SiemensTIA PortalTroubleshooting
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

Stabilizing Program_Alarm IDs on TIA Portal Recompile S7-1500

When you recompile a SIMATIC S7-1500 or ET 200SP program in TIA Portal, every Program_Alarm instruction receives a new auto-generated numeric Alarm ID. The number assigned at compile time is driven by the call position, instance DB, and the internal sequential index of the instruction. Any code edit that adds, removes, or reorders Program_Alarm calls - including unrelated changes such as adding a comment or inserting an unused tag - can shift the entire ID table downstream.

For an operator-facing system this means the alarm log shown in WinCC on a TP700 Comfort panel, the system manual handed to maintenance, and the customer FAT documentation no longer agree. Operators see numeric IDs that no longer correspond to any printed document, and the audit trail breaks the moment the project is recompiled.

This reference documents the root cause, explains why Siemens does not expose a direct "manual Alarm ID" property on the Program_Alarm instruction, and provides three field-proven strategies to deliver a stable user-facing alarm identifier while still using the modern Program_Alarm API. Strategies cover TIA Portal V15 through V20 and apply to ET 200SP CPUs (1510SP-1 PN, 1512SP-1 PN), S7-1500 CPUs (1511-1 PN, 1515-2 PN, 1516-3 PN/DP, 1518-4 PN/DP), WinCC Comfort, WinCC Advanced, and WinCC Professional HMI systems.

Field reality: There is no "Alarm ID" edit field on the Program_Alarm instruction. The ID is compiler-assigned and intentionally not user-editable. The documented workaround is to decouple the customer-facing identifier from the system-assigned Alarm ID by passing a stable value through an associated value (SD_i) and configuring WinCC to display that value in place of the system Alarm ID column.

1. Problem Statement

1.1 Symptoms

  • Program_Alarm IDs change after every PLC project recompile, even when the alarm text and logic are unchanged.
  • The WinCC alarm view on TP700 Comfort, TP900 Comfort, TP1200 Comfort, or TP1500 Comfort shows different numeric IDs than the operator manual, FAT report, or SAT report references.
  • Alarm logging / archiving in WinCC stores new IDs that do not match historical alarm data.
  • Adding or removing a single Program_Alarm call shifts all subsequent IDs in the affected code block.
  • Migrating the project from TIA Portal V15 → V16 → V17 reassigns IDs even if no code is changed.
  • Documentation teams reject the deliverable because alarm numbers are unstable across revisions.

1.2 Affected Components and Versions

Component Affected Versions Notes
TIA Portal STEP 7 V15, V15.1, V16, V17, V18, V19, V20 All versions use the same compile-time ID generator for Program_Alarm.
CPU firmware ET 200SP 1510SP-1 PN (FW ≥ V2.0), 1512SP-1 PN (FW ≥ V2.0), S7-1500 all variants Firmware does not affect ID assignment - assignment is offline/compile-time.
HMI panels TP700 Comfort, TP900 Comfort, TP1200 Comfort, TP1500 Comfort, TP2200 Comfort, IPC All WinCC Comfort/Advanced panels share the same alarm view behavior.
WinCC version Comfort V15–V20, Advanced V15–V20, Professional V15–V20 Alarm view column configuration is consistent across versions.

1.3 Impact

The instability is not a bug - it is by design. The Program_Alarm instruction (an Extended Instruction in TIA Portal under Instructions → Extended Instructions → Alarms) is intended for runtime diagnostic use where the Alarm ID is consumed internally by the PLC diagnostic buffer and the HMI notification system. It is not intended to be a stable customer-visible identifier.

Documentation, operator manuals, and audit trails require identifiers that survive recompilation, code refactoring, and project migration. The PLC-level Alarm ID cannot serve that role, so the field-proven solution is to layer a stable, user-defined identifier on top of the alarm.

2. Program_Alarm Architecture and ID Generation

Understanding how the Alarm ID is generated is the foundation of any workaround. The Program_Alarm instruction creates a program alarm - a diagnostic event raised when the SIG input transitions from FALSE to TRUE. Each call site in your code generates one alarm event; each event has one numeric ID.

2.1 Instruction Block

The Program_Alarm block lives in the TIA Portal project tree under PLC → Program blocks → [FB/OB] as a multi-instance call, or as a standalone DB instance when called from an OB. The block exposes the following interface:

Parameter Direction Type Purpose
SIG Input BOOL Alarm trigger edge (FALSE → TRUE generates alarm).
SD_i (i = 1..10, or 0..10 in V20) Input Variant / typed Associated values appended to the alarm for HMI display.
ACK Input BOOL (optional) Acknowledgement state input.
ENO Output BOOL Enable output - non-zero if generation failed.
Fault Output BOOL TRUE if resource limit exceeded.
Status Output WORD 16-bit status code (0 = OK).

2.2 Compile-Time ID Assignment

During the build process, the TIA Portal compiler walks the call graph of every block containing a Program_Alarm. Each encountered call is assigned the next free integer in a sequential range, starting from a base value defined in the project's alarm configuration. The ID is then bound to the instance DB and the call position. The mapping is not exposed for editing in the standard project tree.

TIA Portal Compiler Call Graph Walk ID Table Assignment Alarm Buffer FB1 "MotorControl" code sequence (pre-recompile) PA @ Line 42 → ID 1001 PA @ Line 88 → ID 1002 PA @ Line 134 → ID 1003 PA @ Line 42 → ID 1001 New PA @ Line 70 → ID 1002 Old Line 88 → ID 1003 Old ID 1001 was "Motor trip" Old ID 1002 was "Overload" Old ID 1003 was "Bearing temp" ID shifts cascade downstream!

The diagram above illustrates the cascading effect: inserting a single new Program_Alarm call at line 70 causes the previously-assigned IDs at line 88 and line 134 to shift by one. The WinCC alarm view will display "ID 1002" against an alarm text that the manual says should be ID 1003.

2.3 Why Manual Editing Is Not Available

The Program_Alarm Alarm ID is a property of the diagnostic infrastructure, not a user-visible tag. Siemens' implementation deliberately ties the ID to the call site so that the PLC diagnostic buffer, the HMI alarm subscription, and the WinCC logging system all use a consistent identifier for the same event. If users were able to assign duplicate IDs, the diagnostic infrastructure would not be able to disambiguate events. The design trades user flexibility for runtime consistency.

For situations where a stable user-facing ID is required, the supported pattern is to embed or pass an additional value that WinCC can display alongside (or instead of) the system Alarm ID.

3. Why IDs Change on Recompile - Root Cause Matrix

Trigger Mechanism Affected IDs Severity
Insert new Program_Alarm call Sequential counter shifts at insertion point All IDs after insertion in same block High
Delete Program_Alarm call Sequential counter compresses All IDs after deletion in same block High
Reorder code segments Call graph walk order changes All reordered IDs High
Move call to different FB/OB Re-enters walk from new base All IDs in new parent block High
Rename FB or instance DB Instance DB index reassigned All IDs under that instance High
Add comment or unused tag None expected - but recompile triggers re-walk None (mostly) Low (but observed in field)
Migrate TIA Portal version Compiler revision may renumber Project-wide High
Library version change Master copy ID table may differ All instances of library types High
Compile PLC program (no source change) No source change - but toolchain regression seen All IDs Critical when change observed

The last row is worth highlighting: in field reports, users have observed full ID table reassignment after a "no-op" recompile following a TIA Portal update or hotfix installation. Always treat the Alarm ID as volatile across any rebuild.

4. Strategy 1: Embed a Stable ID in the Alarm Text

The simplest workaround is to bake the user-facing ID directly into the alarm text. This is the approach widely adopted by integrators for systems where operator manuals must show alarm numbers.

4.1 Implementation

  1. Define a string constant per alarm in a global DB or in the FB's static area, for example:
// Global DB "AlarmTexts"
{ S7_string := 'ID-001 | Motor overload tripped' }
{ S7_string := 'ID-002 | Bearing temperature high' }
{ S7_string := 'ID-003 | Coolant flow low' }
  1. Wire the constant string into the alarm text of the corresponding Program_Alarm call. In TIA Portal, open the alarm properties of the call (Project tree → PLC alarms → [alarm] → Properties), and set the alarm text to reference the string tag.
  2. Repeat for every alarm. The system Alarm ID (e.g., 1001) is no longer displayed because it carries no operational meaning - the operator only sees "ID-001 | Motor overload tripped".

4.2 Pros and Cons

Aspect Evaluation
Stability Excellent - the ID is hard-coded in the alarm text and survives any recompile.
Maintenance effort Medium - each new alarm requires manual text creation and reference.
Localization Easy - the text is a string and can be swapped via language switching.
Searchability in WinCC Excellent - the literal "ID-001" is part of the displayed text.
Drawback Manual IDs cannot be re-used; renumbering requires editing every text instance.
Tip: When using this strategy, configure the WinCC alarm view to hide the system "Alarm number" column. Operators see only the embedded ID, eliminating confusion with the auto-generated numbers. See Section 6 for the column configuration procedure.

5. Strategy 2: Pass a Stable ID via SD_i Associated Values

The recommended Siemens-documented approach for transmitting dynamic data with a Program_Alarm is the associated value interface SD_i. Per the TIA Portal V20 documentation, you can append up to ten associated values to the program alarm at the parameters SD_i (0 ≤ i ≤ 10). The associated values are acquired at the time of the signal edge and are displayed in the WinCC alarm view as configurable columns.

The strategy is to reserve one of these slots (e.g., SD_1) for a user-defined alarm identifier. WinCC can then be configured to display this value as the user-facing ID.

5.1 PLC Implementation

Reserve a constant WORD or DWORD in a global DB for each stable alarm ID. Wire the constant to SD_1 of the corresponding Program_Alarm call:

// Global DB "AlarmIDs"
alarmID_001 : WORD := 1;      // "Motor overload"
alarmID_002 : WORD := 2;      // "Bearing temp high"
alarmID_003 : WORD := 3;      // "Coolant flow low"

// FB "MotorControl"
IF b_overload THEN
    "Program_Alarm_DB"(SIG := TRUE,
                       SD_1 := "AlarmIDs".alarmID_001,
                       // ... other SD_i for process values
                       );
END_IF;

5.2 Alarm Text Configuration

Configure the alarm text in the alarm properties to include a placeholder for SD_1. In TIA Portal V16–V20, the placeholder syntax is @%d% or use the tag reference dialog to bind to SD_1. Example:

Alarm text: "Alarm @1d% active - Motor overload"
             ^^^^^^^^^^ where @1d% references SD_1

When the alarm fires, the placeholder resolves to the value passed via SD_1, which is the stable constant you defined. Operators see a stable numeric ID independent of the system Alarm ID.

5.3 Pros and Cons

Aspect Evaluation
Stability Excellent - SD_1 is a constant you control.
Maintainability High - ID is data, not text, and can be sourced from a single DB.
HMI flexibility High - WinCC can show, filter, and archive on the SD_i value.
Tooling support Native - documented in Siemens Diagnostics Function Manual.
Drawback Requires initial setup per alarm and consumes one of the ten SD_i slots.

5.4 SD_i Usage Limits

Each Program_Alarm call can carry up to ten associated values. In TIA Portal V20 and later documentation, the range is listed as 0 ≤ i ≤ 10 (eleven slots); in earlier versions, it is 1 ≤ i ≤ 10 (ten slots). Verify against your project's documentation help (F1 on the instruction in TIA Portal). The values can be any elementary type (BOOL, INT, WORD, REAL, STRING, DTL, etc.) but each slot consumes a fixed amount of the diagnostic buffer; do not pass large strings unnecessarily.

6. Strategy 3: WinCC Alarm View Column Configuration

Whichever strategy you choose to generate a stable identifier, the operator-facing presentation is controlled in the WinCC alarm view. The default alarm view shows the system Alarm ID column, which is the value that shifts on recompile. To deliver a stable experience, hide the system column and surface the embedded ID (from Strategy 1 or 2) instead.

6.1 Configure Alarm View Columns

  1. In the HMI project tree, open the screen containing the alarm view (e.g., Overview_screen).
  2. Select the Alarm view object.
  3. In the Properties pane, navigate to Properties → Columns.
  4. Clear the checkbox for Alarm number (this is the auto-generated ID).
  5. Add a new column from the available selection. Choose either:
    • Alarm text (which contains the embedded ID per Strategy 1), or
    • Associated value 1 (which contains the SD_1 value per Strategy 2).
  6. Adjust column widths so the ID is the leftmost visible field.
  7. Compile the HMI project and download to the panel.

6.2 Hide the System ID in the WinCC Alarm Log

The WinCC alarm log (when enabled on a Comfort panel or PC runtime) also stores the Alarm ID. To prevent log entries from showing the unstable ID, configure the log view columns identically to the runtime alarm view. Alternatively, enable the Show extended properties option and choose only the user-defined ID column for log display.

6.3 Filter on the User-Defined ID

With Strategy 2 in place, you can configure WinCC alarm filters to search for a specific user ID. Open the alarm view properties → Filter → define a filter expression [Associated value 1] = 1 (or whichever constant is used for "Motor overload"). This is more robust than filtering on alarm text because it is data-driven and stable.

7. Step-by-Step Implementation - Recommended Approach

The following procedure combines Strategy 2 (associated values for stable ID) with Strategy 3 (WinCC column configuration) - this is the most maintainable pattern for production systems.

7.1 Prerequisites

  • TIA Portal V16 or later (procedure identical V15 through V20).
  • S7-1500 or ET 200SP CPU with firmware supporting program alarms (all S7-1500 CPUs from FW V1.5 onward; ET 200SP CPUs from FW V2.0 onward).
  • STEP 7 Professional license (Basic edition does not include Program_Alarm for S7-1500).
  • WinCC Comfort or Advanced for TP700 Comfort / TP1200 Comfort / TP2200 Comfort panels.

7.2 PLC-Side Configuration

  1. Create a global DB AlarmIDs with stable WORD constants:
DATA_BLOCK "AlarmIDs"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
  STRUCT
    motor_overload_id  : WORD := 1001;   // user-facing ID
    bearing_temp_id    : WORD := 1002;
    coolant_flow_id    : WORD := 1003;
    e_stop_id          : WORD := 1099;   // reserved for safety
  END_STRUCT;
END_DATA_BLOCK
  1. In each FB containing alarms, instantiate Program_Alarm as a multi-instance and wire SD_1 to the corresponding constant:
// FB "MotorControl"
"Program_Alarm_Instance_1"(SIG := #b_overload,
                            SD_1 := "AlarmIDs".motor_overload_id,
                            SD_2 := #r_motor_current,
                            SD_3 := #i_motor_speed_rpm);
  1. For each alarm instance, open the alarm properties (right-click the call → Properties → Alarm) and configure:
    • Alarm text: Use placeholder @1d% for the user ID and include process value placeholders for SD_2, SD_3, etc. Example: Alarm @1d% | Motor overload, current @2f% A, speed @3d% rpm.
    • Alarm class: Select an appropriate class (e.g., "Alarm", "Warning", "Fault") with the desired acknowledgement behavior.
    • Info text: Optional - include detailed remediation steps.
  2. Compile the PLC program (Build → Compile → Software (rebuild all)).

7.3 HMI-Side Configuration

  1. Open the HMI configuration in the same TIA Portal project.
  2. Configure the HMI alarm subscription to receive the PLC program alarms. The standard mechanism is the HMI alarm subscription on the PLC connection (HMI device → Connections → [connection] → Properties → Alarm subscription).
  3. Open the screen containing the alarm view (e.g., screen Alarms_screen).
  4. Select the alarm view object. Configure columns as per Section 6.1: hide "Alarm number", show "Associated value 1" (which displays the SD_1 user ID).
  5. Optionally, reorder columns so the user ID is leftmost.
  6. Configure the alarm filter if needed (Section 6.3).
  7. Compile the HMI project and download to the panel.

8. Verification Procedures

After implementation, verify stability under realistic conditions.

8.1 Single Recompile Stability Test

  1. Note the displayed user IDs in the HMI alarm view for all configured alarms.
  2. In TIA Portal, make a trivial edit (add a comment, add an unused tag) and recompile.
  3. Download to PLC and HMI.
  4. Trigger each alarm (set the SIG input true).
  5. Confirm each alarm displays the same user ID as before.

8.2 Structural Change Stability Test

  1. Add a new Program_Alarm call near the top of the affected FB.
  2. Recompile and download.
  3. Trigger all existing alarms. Their user IDs (via SD_1) must remain unchanged.

8.3 Project Migration Stability Test

  1. Save a backup of the project.
  2. Migrate the project to the next TIA Portal version (e.g., V16 → V17).
  3. Compile and download.
  4. Trigger each alarm and confirm user IDs match the documentation baseline.

8.4 PLC Diagnostic Buffer Cross-Check

Open the PLC online → Diagnostic buffer. Confirm the system Alarm ID is still present (it has not been hidden from the PLC; only the HMI presentation changed). This preserves the ability for service engineers to correlate with Siemens' diagnostic infrastructure.

9. Best Practices

  • Centralize user IDs in a single DB. Define all stable alarm identifiers in one global DB (e.g., AlarmIDs) to make renumbering a single-edit operation.
  • Use a numbering convention that reflects severity or system area. Example: 1xxx for utility alarms, 2xxx for process alarms, 9xxx for safety-critical alarms.
  • Reserve blocks of IDs for future expansion. If alarms 1001–1099 are motor alarms, do not interleave coolant alarms (1003, 1023) in the same block.
  • Document the ID space in the system manual. Include a complete list of "Alarm ID" → "Alarm text" → "Remediation" entries as part of the operator manual.
  • Hide the system Alarm ID in the operator-facing view. Operators should never see the unstable ID.
  • Keep the system Alarm ID visible in the engineering view. Service engineers can correlate with PLC diagnostic buffer and Siemens support tools.
  • Cross-reference PLC and HMI project texts. When localization is required, ensure both PLC alarm text and HMI language tables are updated.
  • Use libraries for repeated alarm types. If multiple instances of a motor FB exist, use a library master copy so the alarm text and SD_1 assignment propagate consistently.
  • Test stability after every TIA Portal update. Before applying a TIA Portal service pack in a live engineering environment, validate on a representative test project.

10. Troubleshooting Matrix

Symptom Likely Cause Resolution
User ID displays as "0" or "@1d%" literal Alarm text placeholder not configured, or SD_1 not wired Open alarm properties; verify placeholder syntax matches TIA Portal version; confirm SD_1 input is connected to a constant
Operator still sees shifting numeric IDs Alarm view "Alarm number" column not hidden Properties → Columns → uncheck "Alarm number"
Alarm appears in WinCC but shows no associated value SD_i parameter not assigned at call site, or type mismatch Verify each SD_i has a wired input of a supported elementary type
Alarm ID changes after TIA Portal upgrade Compiler revision renumbered IDs (expected) Confirm Strategy 2 is in place - the user ID via SD_1 should be unaffected
WinCC alarm filter on Associated value 1 returns nothing Filter syntax incorrect, or alarm class mismatch Use [Associated value 1] = N syntax; verify alarm class is enabled in the view's filter
EN0 output of Program_Alarm is TRUE Diagnostic buffer resource exhausted (max concurrent program alarms) Reduce concurrent program alarms; consider ALARM_8P or notify-only pattern for non-critical events
Status word returns non-zero Internal error - see PLC diagnostic buffer for hex status Reference Siemens diagnostic manual; typical codes: 0x8001 (resource), 0x8002 (config), 0x8003 (signal state)
Alarm log shows old system ID but new user ID Log column configuration not updated to match runtime view Configure log view columns identically to runtime alarm view
Renumbering the user ID requires touching every alarm text Strategy 1 used (embedded in text) instead of Strategy 2 Migrate to Strategy 2 (SD_i) for data-driven IDs
Alarm text placeholder shows raw value instead of formatted string Wrong placeholder format specifier Use @iW%d% for WORD, @iR%f% for REAL; refer to TIA Portal help for placeholder syntax

11. Platform-Specific Notes

11.1 ET 200SP CPU 1510SP-1 PN / 1512SP-1 PN

ET 200SP CPUs support the same Program_Alarm instruction set as standalone S7-1500 CPUs from firmware V2.0 onward. The diagnostic buffer for program alarms is shared with the I/O diagnostic alarms of the connected ET 200SP modules; if many PROFINET I/O faults are active, program alarm resources may be throttled. Plan for a maximum of 50 concurrent program alarms on a typical ET 200SP CPU configuration.

11.2 TP700 Comfort / TP1200 Comfort

Comfort panels support up to 8 simultaneous alarm subscriptions on the standard model and up to 16 on the larger TP1500 / TP2200 variants. Program alarms count against this subscription limit. The alarm view refresh rate is 250 ms by default - configure to 500 ms if the panel CPU is heavily loaded with script-driven screens.

11.3 WinCC Professional (PC Runtime)

On PC-based HMI systems, the alarm log can be persisted to SQL Server. Configure the log table to include the user ID (via SD_1 value) as a separate column to enable SQL-level queries for alarm analysis. The default WinCC alarm log stores only the system Alarm ID, so this configuration is necessary for full auditability.

11.4 Alternative: Use ALARM_8P Instruction for Legacy Compatibility

For projects migrated from STEP 7 Classic, the legacy ALARM_8P instruction exposes user-assigned alarm numbers. However, ALARM_8P is not recommended for new S7-1500 development because it is marked as legacy in TIA Portal and may be deprecated in future firmware. Stick with Program_Alarm + associated-value strategy for new projects.

12. FAQ

Can I directly edit the Alarm ID of a Program_Alarm instruction in TIA Portal?

No. The Alarm ID is compiler-assigned based on call position and instance DB. The TIA Portal interface does not expose a manual Alarm ID edit field on Program_Alarm properties. Use an associated value (SD_1) to deliver a stable user-facing identifier and hide the system Alarm ID column in WinCC.

Why do my Program_Alarm IDs change even when I did not edit the alarm code?

Any recompile of the PLC program runs the full call-graph walk that assigns Alarm IDs. TIA Portal updates, library version changes, and even toolchain revisions can cause full ID table reassignment. Treat the system Alarm ID as volatile across any rebuild and rely on a user-defined value passed via SD_i for stable documentation.

How many associated values can a Program_Alarm carry?

Per the TIA Portal V20 Extended Instructions documentation, up to ten associated values can be appended using parameters SD_i (with indices 0–10 in V20, 1–10 in earlier versions). Values can be any elementary type and are captured at the time the SIG input edge occurs.

Does hiding the system Alarm ID in WinCC affect PLC diagnostics?

No. The PLC diagnostic buffer always retains the system Alarm ID. Hiding the column in WinCC is purely a presentation change - the PLC continues to raise, log, and acknowledge alarms using the original ID. Service engineers can still access the diagnostic buffer in TIA Portal online view.

Can I use Strategy 1 (embedded text) and Strategy 2 (SD_i) together?

Yes. Many production systems use a hybrid: the alarm text contains a human-readable description, and SD_1 carries the stable numeric ID. WinCC then displays both - the embedded ID in the alarm text and the user ID in the associated value column. This gives operators a search-by-ID capability (via the SD column) and a search-by-keyword capability (via text search).

Will this workaround work for S7-1200 CPUs as well?

The Program_Alarm instruction is available on S7-1200 from firmware V4.0 onward with the same SD_i interface. The same strategy applies - pass a stable user ID via SD_1 and configure the WinCC alarm view accordingly. S7-1200 has fewer SD_i slots available (typically 8) compared to S7-1500 (10).

Where can I find official Siemens documentation for Program_Alarm?

Refer to the TIA Portal V20 Extended Instructions manual and the SIMATIC Diagnostics Function Manual. Both cover the associated value interface and alarm text configuration in detail.

Back to blog