Overview
The application described here is a per-channel alarm annunciator on a SIMATIC S7-1200 CPU programmed in TIA Portal V17 or later. Each process alarm input drives one panel LED; a shared horn relay sounds whenever any alarm is unacknowledged. A single Acknowledge button silences the horn and converts any subsequently re-triggered LED into a blinking pattern; a Reset button extinguishes every LED and re-arms the annunciator. The blink source is the CPU clock-memory byte - a hardware-implemented square-wave generator that requires no program scan time and continues to cycle even when OB1 is paused.
The original implementation ran on a LOGO! 8 using set/reset relays and a software pulse generator. This article ports the same functional behaviour to STEP 7 Basic in TIA Portal using LAD with a few M-bit flags and eight identical ladder sub-chains. The pattern scales linearly with the number of alarm channels and the same code structure applies to the S7-1500 and ET 200SP CPUs.
Prerequisites
- STEP 7 Basic V17 (V18 or V19 acceptable) inside TIA Portal. Clock-memory configuration in the device view is identical from V14 SP1 onward.
- SIMATIC S7-1200 CPU 1212C DC/DC/DC or 1214C DC/DC/DC, firmware V4.2 or later. The instructions used (S/R, FP, AND, OR) exist in all S7-1200 firmware revisions.
- Onboard DI for up to 14 alarms. Add an SM 1221 (6ES7221-1BF32-0XB0) for additional channels; up to 1024 DI can be addressed on a single CPU through module stacking.
- Two 22.5 mm operator pushbuttons, NO contact (Ack, Reset). Configure the input filter on the CPU properties to 5 ms (default) or 10 ms for mechanical debounce.
- One 24 V horn relay (Phoenix Contact PLC-OSC-24DC/24DC/2 or Finder 55.34) on a digital output.
- One 24 V panel LED per alarm (Siemens Sirius 3SB3 holder with 3SB34 01-1B or Banner K50 Pro). Sourcing outputs on the S7-1200 deliver 0.5 A max per channel on relay DQ, 0.1 A on transistor DQ. Choose output type accordingly.
- Reference: SIMATIC S7-1200 Programmable Controller System Manual (entry ID 109751350).
- Reference: STEP 7 Basic in TIA Portal - Programming and Operating Manual (entry ID 109744827).
- Reference: SIMATIC S7-1200 Easy Book (entry ID 109772942).
I/O and Tag Allocation
The example below uses eight alarm channels. Scale the table upward by extending the per-channel M-bit blocks; the program structure is channel-independent.
| Symbol | Address | Type | Function |
|---|---|---|---|
| Alarm_01 ... Alarm_08 | I0.0 ... I0.7 | Bool | Process alarm inputs, 24 V DC, active high |
| Ack_Button | I1.0 | Bool | Acknowledge pushbutton, NO, 24 V DC |
| Reset_Button | I1.1 | Bool | Master reset pushbutton, NO, 24 V DC |
| LED_01 ... LED_08 | Q0.0 ... Q0.7 | Bool | Alarm LED drivers, sourcing 24 V |
| Horn_Output | Q1.0 | Bool | Horn relay driver, sourcing 24 V |
| Clk_2Hz | M100.3 | Bool | Clock-memory bit, 2 Hz, period 500 ms |
| Clk_1Hz | M100.5 | Bool | Clock-memory bit, 1 Hz, period 1000 ms |
| Horn_Latch | M101.0 | Bool | Common horn latch, non-retentive |
| Ack_Edge_Memory | M101.1 | Bool | Edge bit for FP instruction on Ack_Button |
| Reset_Edge_Memory | M101.2 | Bool | Edge bit for FP instruction on Reset_Button |
| Ack_State | M101.3 | Bool | Latched flag: any alarm has been acknowledged |
| Alarm_Latch[1..8] | M102.0 ... M102.7 | Bool[8] | Per-channel latched alarms |
| Alarm_Blink[1..8] | M103.0 ... M103.7 | Bool[8] | Per-channel blink-enable flags |
Keep all M bits above the process-image range and outside the default MB0..MB15 used by Siemens for system status. M100 onward is conventional user space. If you also enable clock memory at MB100 as documented below, the same MB100 serves both the clock bit and the user flags - bits M100.6 and M100.7 are still free for additional 1.6 s and 2 s pulses.
Enabling Clock Memory (Pulse Generator)
The clock-memory byte is the S7-1200 equivalent of the LOGO! pulse generator block. The byte is driven by a hardware timer inside the CPU. Each of the eight bits in the byte toggles at a fixed, frequency-locked rate. The byte address is configurable; the frequency of each bit is not.
- In the project tree, open Devices & Networks and double-click the CPU icon.
- Select Properties > System and Clock Memory.
- Tick Enable Clock Memory.
- Enter the byte address (default MB100). The byte must not overlap with process I/O, retained M bits, or any DB you reference symbolically.
- Click OK and download the hardware configuration to the CPU.
| Bit (MB100 = base) | Frequency | Period | Duty Cycle | Recommended Use |
|---|---|---|---|---|
| M100.0 | 10 Hz | 100 ms | 50 % | Strobe / beacon |
| M100.1 | 5 Hz | 200 ms | 50 % | HMI heartbeat |
| M100.2 | 2.5 Hz | 400 ms | 50 % | Cycle pulse |
| M100.3 | 2 Hz | 500 ms | 50 % | Alarm LED blink (ISA 18.1 fast flash) |
| M100.4 | 1.25 Hz | 800 ms | 50 % | Slow indicator |
| M100.5 | 1 Hz | 1000 ms | 50 % | 1-second heartbeat / slow alarm blink |
| M100.6 | 0.625 Hz | 1600 ms | 50 % | Long-pulse call light |
| M100.7 | 0.5 Hz | 2000 ms | 50 % | Marine / aviation wink |
Choose M100.3 (2 Hz, period 500 ms) for an annunciator flash rate that meets the ISA 18.1 nominal flash range of 1.5 to 2.5 flashes per second. Choose M100.5 (1 Hz) for a calmer, slower panel pulse more typical of European continuous-process plants. The frequency is firmware-fixed; to change blink speed at runtime, swap the bit reference inside the LED driver network (Section 6).
Annunciator State Machine
Each alarm channel has four logical states. Transitions are driven by the Ack_Pulse and Reset_Pulse one-shots and by the rising edge of the alarm input itself.
- Idle - Alarm_Latch = 0, LED off, Horn off.
- Active-Unacknowledged - Alarm_Latch = 1, Ack_State = 0, LED solid, Horn on.
- Active-Acknowledged - Alarm_Latch = 1, Ack_State = 1, alarm input low, LED off, Horn off.
- Re-Triggered - Alarm_Latch = 1, Ack_State = 1, alarm input high again, Alarm_Blink = 1, LED blinking at Clk_2Hz, Horn on.
State machine - per alarm channel. All four states collapse to Idle on Reset_Pulse.
OB1 Ladder Logic - Network by Network
OB1 contains nine networks for eight alarm channels. The first two networks generate edge one-shots from the operator buttons; networks 3-5 manage the common horn latch; networks 6-9 manage per-channel logic. The LED driver network repeats for each channel; only the index changes.
Network 1 - Acknowledge Edge One-Shot
The FP (rising edge detect) instruction compares the current state of Ack_Button with the bit stored in Ack_Edge_Memory. When the current state is TRUE and the stored state is FALSE, FP outputs TRUE for one scan. This guarantees the Ack button is acted upon exactly once per press regardless of operator hold time.
A "Ack_Button"
FP "Ack_Edge_Memory"
= "Ack_Pulse"
Network 2 - Reset Edge One-Shot
A "Reset_Button"
FP "Reset_Edge_Memory"
= "Reset_Pulse"
Network 3 - Set Common Horn Latch on Any Active Alarm
An OR across all eight alarm inputs sets Horn_Latch. Because S is a retentive coil in STEP 7, the latch stays set even when the alarm input returns low.
A "Alarm_01"
O "Alarm_02"
O "Alarm_03"
O "Alarm_04"
O "Alarm_05"
O "Alarm_06"
O "Alarm_07"
O "Alarm_08"
S "Horn_Latch"
Network 4 - Reset Horn Latch on Acknowledge Pulse
A "Ack_Pulse"
R "Horn_Latch"
Network 5 - Drive Horn Output
The horn sounds while Horn_Latch is set and the panel has not yet been acknowledged. The condition AN Ack_State prevents the horn from re-sounding when an alarm clears naturally after acknowledgement.
A "Horn_Latch"
AN "Ack_State"
= "Horn_Output"
Network 6 - Latch Ack_State on First Acknowledge
A "Ack_Pulse"
S "Ack_State"
Network 7 - Reset Ack_State on Reset Pulse
A "Reset_Pulse"
R "Ack_State"
Network 8 - Per-Channel Alarm Latch (channel 1 shown)
A "Alarm_01"
S "Alarm_Latch_01"
A "Reset_Pulse"
R "Alarm_Latch_01"
Network 9 - LED Driver (channel 1 shown)
The LED driver combines two OR branches: the solid branch is TRUE while the alarm is currently active and the panel has not yet been acknowledged; the blink branch is TRUE when the channel has been acknowledged and the alarm input has returned. The blink branch is ANDed with the 2 Hz clock bit Clk_2Hz, producing the pulse-train output to the LED.
// Branch A: solid while alarm is currently active and not yet acknowledged
A "Alarm_01"
AN "Ack_State"
S "LED_01_latch"
// Branch B: blink enable flag, set on rising edge after acknowledgement
A "Alarm_Latch_01"
A "Ack_State"
A "Alarm_01"
S "Alarm_Blink_01"
A "Reset_Pulse"
R "Alarm_Blink_01"
// Drive LED_01 output
O( A "LED_01_latch" )
O( A "Alarm_Blink_01" A "Clk_2Hz" )
= "LED_01"
Alarm_01, Alarm_Latch_01, Alarm_Blink_01 with Alarm_02, Alarm_Latch_02, Alarm_Blink_02, etc., and copy Network 8 and Network 9 eight times to cover all alarm channels. The horn latch (Networks 3-7) does not need duplication.STL Reference Listing
For teams that prefer text-based STL or want to copy-paste into an SCL source file, the same logic in STL is below. The order of evaluation is identical to LAD.
// --- Network 1: Acknowledge edge
A "Ack_Button"
FP "Ack_Edge_Memory"
= "Ack_Pulse"
// --- Network 2: Reset edge
A "Reset_Button"
FP "Reset_Edge_Memory"
= "Reset_Pulse"
// --- Network 3: Horn latch set
A "Alarm_01"
O "Alarm_02"
O "Alarm_03"
O "Alarm_04"
O "Alarm_05"
O "Alarm_06"
O "Alarm_07"
O "Alarm_08"
S "Horn_Latch"
// --- Network 4: Horn latch reset
A "Ack_Pulse"
R "Horn_Latch"
// --- Network 5: Horn output
A "Horn_Latch"
AN "Ack_State"
= "Horn_Output"
// --- Network 6: Latch Ack_State
A "Ack_Pulse"
S "Ack_State"
// --- Network 7: Reset Ack_State
A "Reset_Pulse"
R "Ack_State"
// --- Networks 8 and 9: per-channel (channel 1)
A "Alarm_01"
S "Alarm_Latch_01"
A "Reset_Pulse"
R "Alarm_Latch_01"
A "Alarm_01"
AN "Ack_State"
S "LED_01_latch"
A "Alarm_Latch_01"
A "Ack_State"
A "Alarm_01"
S "Alarm_Blink_01"
A "Reset_Pulse"
R "Alarm_Blink_01"
O "LED_01_latch"
O "Alarm_Blink_01"
A "Clk_2Hz"
= "LED_01"
Alternative: Cyclic Interrupt OB for Custom Pulse Rates
If the operator wants a non-standard blink rate that the fixed clock byte does not offer - for example 0.8 Hz or a Morse-code S.O.S. pattern - generate the pulse inside a cyclic interrupt OB. The S7-1200 supports OB30-OB38 cyclic interrupts with configurable intervals from 1 ms to 60000 ms.
- Add a new OB: Add new object > Organization Block > Cyclic interrupt.
- Set the cycle time to 500 ms for a 1 Hz pulse (250 ms for 2 Hz, 100 ms for 5 Hz).
- In the OB body, write a single network that inverts a free M bit:
// Inside OB30 (Cyclic interrupt, 500 ms period)
AN "Custom_Blink"
= "Custom_Blink"
Wire Custom_Blink (M104.0) into the LED driver network in place of Clk_2Hz. The pulse rate is now a function of the OB period rather than the clock-memory byte. Beware: cyclic interrupts still consume scan-time budget and CPU resource; the clock-memory byte is essentially free.
HMI and Web Server Integration
If a TP700 Comfort or a KTP400 Basic is in the same project, expose the alarm tags as a status display. The HMI shows the blinking animation when Alarm_Blink is true, complementing the physical LED.
- Drag the Alarm_Blink array into an HMI tag list.
- Place a circle graphic on the screen; bind its colour to Alarm_Blink[i] via an animation.
- For more sophisticated annunciator pages, configure an alarm view from the PLC alarm buffer (PROFINET I-Device alarm routing).
The S7-1200 also exposes a built-in web server (default URL http://<cpu-ip>) under Standard web pages > Variable status. Tick Activate web server on this component in the device configuration, then browse to /VariableStatus for a no-HMI diagnostic view of every alarm and horn tag. Read/write protection is configured via user administration.
Commissioning Procedure
- Wire all alarm inputs, the Ack button, the Reset button, the horn relay, and the LEDs. Verify the input common (1M on the CPU) is tied to 24 V for sinking sensors or to 0 V for sourcing sensors.
- Compile the project (Shift+F5) and download to the CPU in RUN mode.
- Open the Monitor & Force Tables tool and force Ack_Edge_Memory and Reset_Edge_Memory to FALSE before first start; this prevents spurious edges from the initial CPU stop-to-run transition.
- Force one alarm input (e.g., Alarm_01) HIGH. Observe: the horn turns on, LED_01 illuminates solid.
- Click the Ack pushbutton. Observe: horn silences, LED_01 remains solid while the alarm input is still forced HIGH.
- Force the alarm input LOW. Observe: LED_01 turns off, horn stays off.
- Force the alarm input HIGH again. Observe: LED_01 blinks at 2 Hz, horn returns.
- Click Reset. Observe: LED_01 turns off, horn silences, Alarm_Latch and Alarm_Blink cleared.
- Repeat for channels 2 through 8.
- Disconnect the forcing. Power-cycle the CPU. Verify that all latches come up cleared and no alarm LED is stuck on.
Troubleshooting Matrix
| Symptom | Probable Cause | Diagnostic Step | Fix |
|---|---|---|---|
| No LED ever lights even with alarm input forced HIGH | Clock memory not enabled, or LED driver network inverted | Watch table: monitor Clk_2Hz and LED_01
|
Enable clock memory in CPU properties; verify Network 9 polarity |
| Horn does not sound | Horn_Output wired to a sourcing output but load is grounded, or Ack_State latched from previous cycle | Monitor Horn_Output bit; check Q1.0 voltage with multimeter |
Verify wiring (sourcing loads need 24 V common return); clear Ack_State with Reset |
| LED blinks immediately on first alarm without prior acknowledge | Ack_State latched from previous session due to retentive M bit | Online > Watch table - inspect Ack_State on STOP-to-RUN | Clear retentive bit in CPU properties, or remove from Retain area |
| Ack button works only when held | FP instruction missing on Ack_Button | Check Network 1 for FP coil | Insert FP on Ack_Edge_Memory |
| Reset does not clear LEDs | Reset_Edge_Memory shares an address with another flag, or Reset_Pulse is wired to a NOR instead of R | Cross-reference M101.2 in the project | Move Reset_Edge_Memory to a unique address |
| LEDs blink at half the expected rate | Wrong clock bit selected (e.g., M100.5 used instead of M100.3) | Watch M100.3 with 1 s scan | Change Network 9 to M100.5 for slower blink |
| Multiple alarms with one Ack only silence horn, all LEDs stay on | Network 4 missing Reset Pulse or Ack_Pulse not generated | Monitor Ack_Pulse on Watch table | Verify Network 1 FP and Network 4 R coil |
| LED latches ON permanently even with input LOW | Alarm input wiring reversed (active low) or sensor sourcing 0 V on alarm | Check input polarity with voltmeter | Swap sensor polarity or invert input in PLC tag table |
| Horn stays on after Reset pressed | Reset_Pulse did not propagate to Ack_State reset because of scan order | Reorder Network 7 ahead of Network 4 | Move Reset Ack_State above the Ack horn reset |
Field Notes and Edge Cases
Retentive behaviour. Horn_Latch, Ack_State, Alarm_Latch[i], and Alarm_Blink[i] are declared as non-retentive Bool by default. If a power cycle must preserve acknowledged alarms (e.g., a refinery DCS that wants to retain first-out indication across battery backup), tick Retain on each of these tags inside the PLC tag table. Mark only what you need - retaining all M bits doubles the byte count in the retain memory area and increases restart time.
First-out indication. In ISA 18.1 annunciators, the first alarm in a sequence is held distinct from subsequent alarms. To add first-out logic, declare a First_Out tag that is set on the rising edge of any alarm before Ack and is cleared on Reset. Drive the first-out LED from Alarm_Latch[i] AND First_Out_Captured = i. The structure of OB1 networks 3-9 above does not need to change; only the additional first-out capture network is added.
Pushbutton bounce. Mechanical pushbuttons generate contact chatter for 1-10 ms. The CPU input filter at 5 ms default already masks most bounce. If Ack misfires under heavy vibration, raise the filter on I1.0/I1.1 to 10 ms in CPU properties > Digital Inputs.
24 V supply sizing. Each LED draws approximately 20 mA. Eight LEDs plus horn relay plus CPU plus I/O modules draws: I = 8 * 0.020 + 0.050 (horn) + 0.500 (CPU 1214C) + 0.080 (DQ) = 0.79 A. With 30 % design margin, select a 24 V, 1.5 A power supply such as the Siemens 6EP1332-1SH43 (LOGO! Power) or Phoenix Contact QUINT4-PS/1AC/24DC/1.5.
Converting from LOGO! to TIA. The LOGO! set/reset relay becomes a STEP 7 S (set) and R (reset) coil pair. The LOGO! pulse generator becomes the clock-memory byte described in Section 4. The LOGO! AND/NOT gates map directly to LAD's A/AN/O/ON branches. The LOGO! "text message" output maps to either an HMI text field or a structured text snippet in OB1.
EMC and cable routing. Keep alarm wiring in a separate conduit at least 100 mm from VFD motor cables. The S7-1200 onboard DI already meets IEC 61131-2 Type 1 / Type 3 input immunity; no external filtering is required for industrial installations. Use shielded cable for runs longer than 10 m and bond the shield at the cabinet entry only.
Comparison to LOGO! 8. The S7-1200 implementation described here is larger (9 networks vs ~6 LOGO! blocks) but adds features the LOGO! cannot match natively: web server diagnostic, retentive first-out capture, and easy migration to S7-1500 by copying the OB1 into a V18 TIA Portal project with only minor retag edits.
Fault F1 / F2 CPU errors. A persistent 24 V short on an LED output trips the CPU's DQ diagnostics (CPU 1214C DC/DC/DC supports diagnostic interrupt on overload). If LED_03 turns off and SF (red) LED illuminates, check the field wiring first; the CPU diagnostics log entry SF0001 indicates channel Q0.2 short to M.
How do I change the LED blink speed on the S7-1200?
Change the clock-memory bit referenced in the LED driver network (Network 9). Pick M100.0 (10 Hz) for fast strobe, M100.3 (2 Hz) for ISA 18.1-compliant alarm flash, M100.5 (1 Hz) for slow heartbeat. The bit frequency is firmware-fixed; if you need a non-standard rate, generate a custom pulse inside a cyclic interrupt OB (OB30-OB38) at the period you want.
Can I use a TP (pulse timer) instead of the clock-memory byte?
Yes. An IEC TP block (e.g., TP time := T#500ms) with its output wired to a free M bit produces the same blink pattern. The clock-memory byte is preferred because it consumes no scan time and is updated by the CPU operating system independent of OB1. TP timers add 4-8 microseconds per LED per scan, which adds up when you have 32 or 64 channels.
How do I add a fourth state - latched solid even after acknowledgement - without losing the blink-on-retrigger feature?
Add a separate LED_Solid_Latch[i] tag driven by Alarm_Latch and Ack_State. OR three branches into the LED output: solid-while-active, blink-on-retrigger (current logic), and steady-on-after-ack (new branch). See Section 6 for the OR structure that combines multiple LED branches.
Will this logic work on the S7-1500 and ET 200SP CPUs?
Yes. The same instructions (S, R, FP, A, AN, O, ON, =) are part of the IEC 61131-3 instruction set used across all S7-1200, S7-1500, and ET 200SP CPUs. The clock-memory byte is enabled through the device configuration of every S7-1500 CPU. The frequency table is identical: 10 Hz, 5 Hz, 2.5 Hz, 2 Hz, 1.25 Hz, 1 Hz, 0.625 Hz, 0.5 Hz.
Why does the horn not silence immediately when I press Ack?
The horn output is gated by both Horn_Latch and NOT Ack_State. Ack_Pulse resets Horn_Latch and sets Ack_State, but the network that drives Horn_Output reads both bits at the start of the next scan. One PLC scan at 10 ms typical execution time yields up to 10 ms of horn latency. If lower latency is required, swap the order: reset Horn_Latch and set Ack_State inside a hardware interrupt OB or use an immediate-write instruction.