Dynamic Program_Alarm Text in TIA Portal: SD_i & Lock Settings

David Krause13 min read
SiemensTIA PortalTutorial / How-to
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

Dynamic Program_Alarm Text in TIA Portal: SD_i Parameters and Lock-Settings Workaround

The Program_Alarm instruction (S7-1200/S7-1500) raises a program-defined alarm when its SIG input transitions. By default, the alarm text is defined once on the FB-static level and appears as a greyed-out field in the instance DB; the field engineer can see the text but cannot change it. This reference documents two field-proven methods to obtain runtime-modifiable alarm text: (1) unlocking the lock icon in the TIA Portal PLC alarms editor so the static text becomes editable at the instance DB, and (2) using the SD_1...SD_10 associated-value parameters with @1%s@-style placeholders so the text is built dynamically in the application code. Both methods are validated against TIA Portal V15.1 through V17 Update 4 and align with the official Siemens Diagnostics function manual.

Scope. This article covers the standard Program_Alarm instruction (sometimes labelled Generate program alarm with associated values). The Program_Alarm_S and Alarm_S instructions share a similar model but use SIG/ACK semantics; the lock-icon and SD_i approach described here applies to all three with minor variations noted in Section 11.

1. Program_Alarm Default Behavior and the Locked-Text Problem

The Program_Alarm block is declared as a multi-instance (static variable) inside an FB, or as a stand-alone instance in a global DB. Each invocation requires a unique EV_ID (DWORD) that ties the call to a row in the PLC supervisions & alarms > Program alarms editor. The default project setting Enable lock function for new alarms ties the alarm text to the FB type definition: any new instance DB inherits a copy of that text but cannot modify it. The intent is consistency: every instance of an FB should emit the same human-readable message unless the engineer explicitly opts out.

The relevant inputs and outputs of Program_Alarm are summarized in the table below. The interface is documented in the TIA Portal help under Extended Instructions > Alarms S7-1200/S7-1500 > Program_Alarm: Generate program alarm with associated values (S7-1500) - TIA Portal V20.

Input / output Type Description
SIG BOOL Trigger signal; alarm is raised on the rising edge and cleared on the falling edge
SD_1...SD_10 VARIANT Up to 10 associated values; any elementary type (BOOL, INT, REAL, STRING, WSTRING, DTL, etc.)
EV_ID DWORD Unique event ID per alarm source; auto-assigned by the editor
CMP_ID WORD Optional component identifier used by the diagnostic buffer
SEVERITY WORD Alarm severity class (0..127); 0 = highest
ACK (output) BOOL Acknowledgment state output (Program_Alarm_S / Alarm_S only)
STAT (output) WORD Status word; 0 = OK, non-zero = error code

The official Siemens example illustrating the @1%s@ syntax with a real tag binding is provided in the SIMATIC ET 200clean manual collection - Example 2: Program alarm with associated value and is also mirrored in the support article Generate program alarm with associated values (S7-1500) - Support.

2. Method 1 - Unlock the Lock Icon for Editable Static Text

The first method allows the engineer to edit the static alarm text on a per-instance basis in the instance DB. The lock state is a project-wide setting stored with the alarm definition; unsetting it is reversible.

2.1 Procedure

  1. In TIA Portal, open the menu Options > Settings.
  2. Navigate the tree to PLC programming > PLC alarms.
  3. Uncheck Enable lock function for new alarms (German: Sperrfunktion für neue Alarme aktivieren). The related option Show lock icon (Sperrsymbol anzeigen) controls only whether the icon is rendered in the editor; clearing it does not remove the lock.
  4. Open PLC supervisions & alarms in the project tree and switch to the Program alarms tab.
  5. Right-click the target alarm and choose Unlock. The lock icon disappears and the alarm text becomes editable.
  6. Open the instance DB. The previously greyed Program_Alarm text field is now white, indicating editability.
  7. Type the new static text, then compile and download.
Behavior on recompile. Once the lock is removed for an alarm, every change to the alarm text in the instance DB persists in the project. If the FB is recompiled and the instance DB is re-initialized, the text is overwritten with the FB default. To prevent this, enable Reinitialize only if necessary or use the Snapshot of actual values option during download.

2.2 When Method 1 Is the Right Choice

  • Few instances, each with a unique static text (e.g. a one-off nameplate or serial number per motor).
  • No operator-facing dynamic content required (text is fully known at commissioning time).
  • The text genuinely differs from the FB default and is unlikely to be reverted.

3. Method 2 - Dynamic Alarm Text via SD_i Associated Values (Recommended)

The second method is the recommended production approach because the text is computed in the application and survives every recompile, every download, and every project re-open. The alarm text contains placeholders such as @1%s@ or @2%d@; the runtime values are provided through the SD_1...SD_10 inputs.

3.1 Placeholder Syntax

Placeholder Source input Typical type Format specifier
@1%s@ SD_1 STRING / WSTRING ANSI or Unicode text
@2%d@ SD_2 INT / DINT Signed decimal
@3%f@ SD_3 REAL / LREAL Floating point (default 6 digits)
@4%t@ SD_4 DTL Date/time stamp
@5%b@ SD_5 BOOL TRUE / FALSE string
@6%x@ SD_6 BYTE / WORD / DWORD Hexadecimal

3.2 SCL Example (S7-1500 / S7-1200, FW V4.0+)

// FB "MotorMonitor" - runtime alarm text via SD_i
VAR
  prch           : Struct
                     vstp    : BOOL;     // trip signal
                     vactCur : REAL;     // actual current [A]
                   END_STRUCT;
  textAlarm      : WSTRING;             // dynamic text buffer
  curText        : WSTRING;             // formatted numeric value
  myAlarm        : Program_Alarm;       // static alarm instance
END_VAR

BEGIN
  // 1. Build the dynamic text in application code
  #curText   := WSTRING#"I=" + REAL_TO_WSTRING(#prch.vactCur) + WSTRING#" A";
  #textAlarm := WSTRING#"Motor tripped, " + #curText;

  // 2. Forward to Program_Alarm via associated value SD_1
  #myAlarm(SIG  := #prch.vstp,
           SD_1 := #textAlarm);
END_FUNCTION_BLOCK

The alarm text in PLC supervisions & alarms > Properties > Alarm text is configured to:

Drive fault: @1%s@

At runtime, when prch.vstp rises, the alarm is published with the text "Drive fault: Motor tripped, I=12.3 A". The placeholder substitution is performed by the CPU's diagnostic dispatcher, not by the user program.

4. Configuring the Dynamic Tag in PLC Supervisions & Alarms (Editor Workflow)

To bind a tag to a placeholder, follow the steps below. The dynamic tag is required even when the value ultimately comes from SD_i, because the editor needs a symbol to know the data type of the placeholder.

  1. Open PLC supervisions & alarms > Alarms > Program alarms.
  2. Select the alarm and open Properties.
  3. In the Alarm text field, right-click and choose Insert dynamic parameter > Tag.
  4. Under Process, browse to the tag that is the target of an SD_i input. In multi-instance situations, TIA Portal filters candidates to the FB's static area and adjacent DBs.
  5. Under Format, pick the format that matches the source data type (e.g. String for WSTRING, Dec for DINT).
  6. Type the placeholder manually (e.g. @1%s@) if the editor did not auto-insert it.
  7. Compile the project. The placeholder is replaced at runtime by the value passed through the corresponding SD_i input.
Editor anomaly on TIA V17 Update 4. The dynamic-tag drop-down occasionally shows in-build function calls in addition to user tags. The selection still works, but treat the list as informational and pick your own symbol.

5. Multiple SD_i in a Single Alarm Text

Up to 10 associated values can be referenced from a single alarm. The example below combines a motor name, a current value, and a timestamp.

// FB "MotorMonitor" - multiple SD_i in one alarm
VAR
  name     : WSTRING;        // e.g. "M-201"
  cur      : REAL;           // 12.3 A
  tEv      : DTL;            // event time
  trip     : BOOL;
  myAlarm  : Program_Alarm;
END_VAR

BEGIN
  // Read values (omitted for brevity)
  #myAlarm(SIG  := #trip,
           SD_1 := #name,
           SD_2 := #cur,
           SD_3 := #tEv);
END_FUNCTION_BLOCK

Alarm text configuration:

Motor @1%s@ tripped at @3%t%t@, current = @2%f@ A

The order of placeholders in the text does not need to match the SD_i index; each placeholder is identified by its numeric prefix. The format specifier between % and the type letter controls width and precision (e.g. @2%.2f@ for two decimal places).

6. Working with Arrayed Program_Alarm Instances

When you instantiate Program_Alarm as an array element (e.g. arrAlarm : ARRAY[1..20] OF Program_Alarm), the editor only allows a tag to be bound to the dynamic parameter in the alarm text for the first array element. For subsequent elements, you must assign the tag through the SD_i inputs in code.

6.1 Workaround Pattern Using a FOR Loop

VAR_TEMP
  i : INT;
END_VAR

FOR #i := 1 TO 20 DO
  // Compute text per instance
  arrText[#i] := WSTRING#"Loop #" + INT_TO_WSTRING(#i);
  // Forward to alarm instance
  arrAlarm[#i](SIG  := arrSig[#i],
               SD_1 := arrText[#i]);
END_FOR;

This pattern is the only fully working method observed on TIA Portal V17 Update 4. Editor-driven dynamic parameters on indexed elements remain a known limitation; submit a Siemens Support Request (SR) with project fragments if the limitation blocks a deployment.

6.2 Generation Pattern for Bulk Alarms

For new projects, generate the array and the helper text buffer with a single source pattern. Use the Program blocks > Generate > Multiple instances wizard or a code template to keep the indices, EV_ID values, and text buffers in sync.

7. Multi-Language Alarm Text and HMI Display

For operator panels, alarm texts must be available in each project language. Configure languages via Project > Languages & Resources, then open the alarm's Properties > Texts tab. Each language has its own static text and its own dynamic parameter binding. Switching the runtime language on the HMI automatically selects the localized static prefix and forwards the same associated values from SD_i.

Language Static prefix Placeholder Runtime output (example)
English (US) Motor # @1%s@ tripped "Motor 4 tripped"
German (DE) Motor # @1%s@ ausgeloest "Motor 4 ausgeloest"
Spanish (ES) Motor # @1%s@ disparado "Motor 4 disparado"
French (FR) Moteur # @1%s@ declenche "Moteur 4 declenche"

If only the English text is shown at runtime, the project has not been edited in the other languages. Open Properties > Texts for the alarm and supply a translation in every active project language, then recompile and re-download.

8. Alarm Acknowledgment and Clearing Behavior

The standard Program_Alarm clears the alarm on the falling edge of SIG; the operator does not need to acknowledge. The Program_Alarm_S and Alarm_S variants add an ACK input: the alarm stays active until the rising edge of ACK. The acknowledgment state is reflected in the STAT output and in the HMI alarm view.

Instruction Trigger Clear condition Ack required?
Program_Alarm Rising edge of SIG Falling edge of SIG No
Program_Alarm_S Rising edge of SIG Rising edge of ACK Yes (operator)
Alarm_S Rising edge of SIG Rising edge of ACK Yes (operator)

For an alarm that re-fires every cycle, edge detection is the most common cause. Latch the trip signal with a Set/Reset FF; the alarm is raised once and cleared only after a manual reset.

9. Verification Procedure

  1. Compile. Build > Compile all. The alarm text must compile without warnings. A warning of the form Alarm text references undefined associated value indicates a missing or wrong SD_i.
  2. Download. Download the project to the CPU in STOP, then run.
  3. Force the trigger. Force the SIG input TRUE in the watch table or with a small test program. Alternatively, toggle the input from the HMI test screen.
  4. Inspect the alarm buffer. Open Online & diagnostics > Diagnostic buffer on the CPU. Confirm that the alarm appears with the substituted value and not the literal placeholder @1%s@.
  5. Inspect the HMI. Open the HMI alarm view (WinCC / Unified / TIA-portable panels). Confirm that the alarm text is displayed in the active project language.
  6. Clear. Force the SIG input FALSE and confirm the alarm clears (or send an ACK if using Program_Alarm_S).
  7. Stress test. Toggle SIG at 10 Hz for one minute and confirm that the diagnostic buffer does not overflow and that the HMI refresh rate is acceptable.

10. Troubleshooting Matrix

Symptom Likely cause Resolution
Alarm text grey in instance DB Lock function enabled in project settings Uncheck Enable lock function for new alarms in Options > Settings > PLC programming > PLC alarms
Placeholder shown literally (e.g. @1%s@) SD_i input not wired or wrong type Wire the SD_i input in code; ensure the data type matches the placeholder format specifier
Alarm not visible in HMI Alarm class not enabled in HMI alarm view Add the alarm class to the HMI's Alarms project node and enable the class filter in the alarm view
Editor refuses to bind tag to dynamic parameter on arrayed alarm Known TIA Portal limitation for array indices > 1 Use a FOR loop with code-driven SD_i binding as shown in Section 6
Multiple languages show English text only Translation not entered in Properties > Texts Open Properties > Texts for the alarm and provide the text in each project language
Alarm re-fired every cycle Edge detection re-triggers Latch the SIG input with a Set/Reset FF; ensure a falling edge precedes the next rising edge
Alarm buffer overflow during commissioning Too many SD_i values or too many active alarms Reduce the number of alarms in active state; refer to the per-CPU ceiling in the S7-1500 system manual
Alarm appears in TIA but not in WinCC HMI connection not configured for the alarm source Verify the HMI connection in Devices & Networks and ensure the alarm class is in the HMI's alarm configuration
Static text change in instance DB lost after recompile DB re-initialized during download Use Reinitialize only if necessary during download, or switch to the dynamic SD_i method

11. Cross-Platform Notes: S7-1200, S7-1500, ET 200SP / ET 200pro

The Program_Alarm instruction is available on S7-1500 (FW V1.0+), S7-1200 (FW V4.0+), and the IM 151 / IM 155 PROFINET interfaces of the ET 200SP and ET 200pro distributed I/O. The interface and placeholder syntax are identical. The per-CPU limits differ and are documented in the system manual of the specific CPU order number. The table below lists typical ceilings (always confirm against the latest system manual):

Platform Typical max program alarms Source
S7-1200 CPU 1214C (FW 4.4) 500 S7-1200 system manual
S7-1500 CPU 1511-1 PN 2000 S7-1500 system manual
S7-1500 CPU 1515-2 PN 4000 S7-1500 system manual
S7-1500 CPU 1518-4 PN/DP 8000 S7-1500 system manual
ET 200SP IM 155-6 PN Depends on head module ET 200SP system manual

For ET 200pro / ET 200clean applications, refer to the application example Example 2: Program alarm with associated value which is written for the same SD_i workflow described here.

12. Performance and Resource Considerations

Each Program_Alarm call consumes an event ID and an alarm slot in the CPU's diagnostic buffer. Passing long WSTRING values (over 254 characters) increases the per-alarm message length and CPU load during message formatting. Trim associated values to operator-actionable content (status code, current value, motor name) rather than dumping large records. On S7-1500 the per-cycle cost of an active alarm with five SD_i values is in the order of single-digit microseconds; the cost is paid only when the alarm is active.

Diagnostic messages flow over the integrated PROFINET interface to HMI panels and SCADA stations. Each active subscriber contributes to the publisher load on the interface; for very large alarm populations, partition the alarms across multiple HMI connections to balance the load.

FAQ

Can I edit the alarm text directly in the instance DB without unlocking?

No. By default, the alarm text is locked at the FB-static level. You must either uncheck Enable lock function for new alarms in Options > Settings > PLC programming > PLC alarms and unlock the alarm in the editor, or use the dynamic SD_i parameter approach with @1%s@-style placeholders.

What is the difference between SIG and SD_i?

SIG is the Boolean trigger input that raises or clears the alarm. SD_1...SD_10 are VARIANT inputs used to inject runtime values into placeholders (@1%s@, @2%d@, etc.) in the alarm text. The trigger and the data path are independent.

How many associated values can I pass to a single Program_Alarm?

Up to 10. The instruction provides SD_1 through SD_10; each accepts any elementary data type (BOOL, INT, REAL, STRING, WSTRING, DTL, etc.). The order of placeholders in the text does not need to match the SD_i index.

Why does the editor not allow tag binding on arrayed Program_Alarm instances?

Observed behavior in TIA Portal V17 Update 4: only the first array index offers editor-driven tag binding for the dynamic parameter. For additional indices, wire the SD_i inputs in code within a FOR loop; this is the only fully working method.

Does Program_Alarm work on S7-1200?

Yes, with firmware V4.0 and later. The instruction set is the same as on S7-1500, but the per-CPU ceiling on the number of active alarms is lower. Refer to the S7-1200 system manual for the limit on your specific CPU order number.

Back to blog