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.
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_Alarmcall 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.
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
- 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' }
- Wire the constant string into the alarm text of the corresponding
Program_Alarmcall. 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. - 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. |
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
- In the HMI project tree, open the screen containing the alarm view (e.g.,
Overview_screen). - Select the Alarm view object.
- In the Properties pane, navigate to Properties → Columns.
- Clear the checkbox for Alarm number (this is the auto-generated ID).
- 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_1value per Strategy 2).
- Adjust column widths so the ID is the leftmost visible field.
- 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_Alarmfor S7-1500). - WinCC Comfort or Advanced for TP700 Comfort / TP1200 Comfort / TP2200 Comfort panels.
7.2 PLC-Side Configuration
- Create a global DB
AlarmIDswith 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
- In each FB containing alarms, instantiate
Program_Alarmas a multi-instance and wireSD_1to 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);
- 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.
-
Alarm text: Use placeholder
- Compile the PLC program (Build → Compile → Software (rebuild all)).
7.3 HMI-Side Configuration
- Open the HMI configuration in the same TIA Portal project.
- 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).
- Open the screen containing the alarm view (e.g., screen
Alarms_screen). - Select the alarm view object. Configure columns as per Section 6.1: hide "Alarm number", show "Associated value 1" (which displays the
SD_1user ID). - Optionally, reorder columns so the user ID is leftmost.
- Configure the alarm filter if needed (Section 6.3).
- 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
- Note the displayed user IDs in the HMI alarm view for all configured alarms.
- In TIA Portal, make a trivial edit (add a comment, add an unused tag) and recompile.
- Download to PLC and HMI.
- Trigger each alarm (set the
SIGinput true). - Confirm each alarm displays the same user ID as before.
8.2 Structural Change Stability Test
- Add a new
Program_Alarmcall near the top of the affected FB. - Recompile and download.
- Trigger all existing alarms. Their user IDs (via
SD_1) must remain unchanged.
8.3 Project Migration Stability Test
- Save a backup of the project.
- Migrate the project to the next TIA Portal version (e.g., V16 → V17).
- Compile and download.
- 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:
1xxxfor utility alarms,2xxxfor process alarms,9xxxfor 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_1assignment 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.