Positive Edge Detection in TIA Portal: S7-1200 LAD/SCL Guide

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

Positive Edge Detection in TIA Portal for S7-1200 PLCs

Engineers transitioning from LOGO! Soft Comfort to TIA Portal often find that the familiar single-click "positive edge" switch is replaced by a two-operand contact in ladder logic. The instruction is functionally identical, but the wiring convention and memory-bit requirement catch many first-time TIA Portal users. This reference documents the correct way to evaluate a positive (rising) edge on a Boolean tag, the available instructions in the Basic Instructions bit-logic library, the memory-bit rules that govern reliable operation, and the verification steps that confirm the edge fires exactly once per OFF-to-ON transition.

1. Overview of Edge Detection on S7-1200

Edge detection is the process of converting a level-based Boolean signal into a pulse that lasts one PLC scan. The PLC's cyclic OB1 execution reads all inputs once at the start of the cycle, so a static TRUE input cannot by itself signal "the moment the input turned on." The S7-1200 CPU family, including the CPU 1214C DC/DC/DC referenced in the field discussion, retains the prior cycle state of the input in a hidden image table and compares it with the current state on every scan. A positive edge (also called rising edge, positive flank, or P-edge) is detected when the current state is TRUE and the previous state was FALSE.

According to the official SIMATIC S7-1200 manual collection, positive- and negative-edge instructions fall under the Basic Instructions / Bit Logic Operations group. The state of a positive-edge contact is TRUE only for the scan in which the OFF-to-ON transition of the assigned IN bit is detected. The instruction produces no TRUE output on subsequent scans as long as the input remains TRUE — a property that makes it ideal for counters, one-shot events, alarm latches, and conditional writes.

Positive and negative edge instructions — SIMATIC S7-1200 Manual Collection

2. Prerequisites

Before configuring an edge instruction, confirm the following items are available in the project:

  • SIMATIC STEP 7 Basic or Professional V15 or later (V16+ recommended for current firmware families). Earlier versions of TIA Portal V13/V14 still expose the same instructions, but the project tree and online diagnostics views differ.
  • Target CPU: S7-1200 family. The edge instructions described here are supported on all S7-1200 firmware versions; CPU 1214C DC/DC/DC with order number 6ES7214-1AG40-0XB0 is a typical deployment.
  • Firmware compatibility: S7-1200 CPUs at firmware V4.0 or later expose the full set of P/N edge contacts and P_TRIG / N_TRIG function blocks. Firmware V4.2 adds optimized block access, which is recommended for the memory-bit operand used by the edge.
  • Defined PLC tags: at minimum a Boolean input tag (e.g., i0.0 or a symbolic name such as "Start_Button") and a Boolean memory tag for the edge operand (e.g., "Start_Button_Edge" or "M10.0").
  • A programming environment: LAD (ladder) or FBD for graphical contact use; SCL for the equivalent P_TRIG call.

3. Edge Detection Theory and Scan Semantics

The S7-1200 OB1 execution model reads process inputs into the process image input (PII) at the start of the cycle, executes the program using only the image-table values, and writes outputs to the process image output (PIO) at the end of the cycle. Edge instructions in TIA Portal compare the current value of the IN bit with the value stored in a hidden "previous-state" operand. That operand is the memory bit you wire beneath the edge contact. Because the comparison must persist across scans, the operand must be located in a retentive or non-retentive memory area that survives between OB1 calls.

The two operands on a positive-edge contact --(P)-- in LAD are:

  1. Above the contact: the Boolean input or tag to monitor (e.g., "Start_Button" or %I0.0). This is the value being compared.
  2. Below the contact: a Boolean memory tag (e.g., "Start_Button_Edge" or %M10.0) used to store the previous scan's state. The instruction writes the current state of the input into this tag on every scan and reads it back the next scan to detect the transition.
Critical rule: The operand below the edge contact is internally written by the instruction. It must not be a TEMP tag (local stack of the OB/FC/FB), because TEMP values are uninitialized at the start of each scan and the comparison would be meaningless. The Siemens manual explicitly requires that the memory bit be a global tag (M, DB, or a static FB tag) that retains its value between scans.

4. Available Positive-Edge Instructions in TIA Portal

TIA Portal exposes three primary positive-edge primitives. The table below summarizes them with their typical use case and the location of the memory operand.

Instruction Type Operands Typical Use
--|P|-- contact (P-edge contact) LAD / FBD contact Input above (bit to monitor); memory bit below Inline rising-edge evaluation inside a rung; preferred for Ladder logic
--(P)-- coil (P-edge coil) LAD / FBD coil Boolean input to the coil; memory bit operand on the box Set a tag TRUE for one scan on the rising edge of the driving logic
P_TRIG (Positive RLO edge detector, FB) SCL / STL / FBD box CLK (Boolean), Q (Boolean pulse), ET (Edge bit) Structured text, re-use inside an FB, edge bit accessible for diagnostics
N_TRIG / --|N|-- / --(N)-- Negative-edge counterparts Mirror wiring of the P variants OFF-to-TRUE-to-FALSE (falling) transitions; not covered here but follow identical rules

The SIMATIC S7-1200 manual explicitly states that the contact form --|P|-- and the coil form --(P)-- differ only in where the result is read: the contact form gates the rung's RLO, while the coil form writes a one-shot pulse to its assigned tag.

5. Ladder Logic (LAD) Implementation

5.1 Using the --(P)-- Coil

The most direct way to obtain a one-scan pulse on a long-running input is the P-edge coil. Drop a normally-open contact of the input on the left of the rung, then place the --(P)-- coil on the right. The coil box has two fields: the upper one accepts the tag to pulse (for example "Start_Pulse" BOOL) and the lower one accepts the memory bit that tracks the previous state (for example "Start_Pulse_Edge" BOOL, declared in the default tag table or in a global DB).

|      Start_Button      Start_Pulse    |
|----------| |----------( P )-----------|
|                         Start_Pulse_Edge |

On the scan in which Start_Button transitions from FALSE to TRUE, Start_Pulse is set TRUE and remains TRUE for the remainder of that OB1 cycle. On every subsequent cycle — including cycles where Start_Button is still TRUE — the edge instruction writes the current value of Start_Button into Start_Pulse_Edge and the comparison fails, so Start_Pulse is reset to FALSE.

5.2 Using the --|P|-- Contact

When the desired result is to gate a downstream rung, the P-edge contact is preferable. The contact form embeds the edge in the rung's left rail logic so any coils or boxes to the right see the pulse.

|  Start_Button    |    Start_Pulse  |    Counter_CV    |
|-------| |-------|P|---(            )---(   ADD   )---|
|                    |                |    1             |
|                    Start_Button_Edge|

This rung adds 1 to Counter_CV exactly once per button press, regardless of how long the operator holds the input. The contact |P| is TRUE for a single scan; Start_Button_Edge holds the previous value of Start_Button between scans.

5.3 Where to Declare the Memory Bit

There are three acceptable locations for the edge memory bit, in order of preference:

  1. Instance DB of the enclosing FB: declare Start_Button_Edge : BOOL; in the FB's Static section. This is the cleanest approach for re-usable blocks because the operand travels with the FB instance and cannot collide with other instances.
  2. Global DB (user-defined): declare the bit in a project-wide DB, for example "EdgeBits".Start_Button_Edge. This is the conventional choice for OB1-global edges.
  3. Merker / M area: the legacy %M10.0 or symbolic equivalent. Valid for S7-1200 but not recommended for new code; the default tag table in TIA Portal V15+ discourages M-bit use and routes you toward symbolic DB tags.
Do not use TEMP variables, local constants, or uninitialized FB parameters. The compiler will not always flag this, but the edge will misbehave at the first cycle boundary.

6. SCL Implementation with P_TRIG

In SCL the equivalent of the P-edge coil is the P_TRIG function block. The block has three formal parameters: CLK (the bit to monitor), Q (one-scan pulse output), and a hidden multi-instance / DB tag holding the edge bit. The standard SCL pattern looks like this:

// FB declaration
VAR
  Start_Button : BOOL;   // input from process
  Start_Pulse  : BOOL;   // one-scan pulse
END_VAR
VAR
  Start_Trig : P_TRIG;   // P_TRIG instance with edge bit inside
END_VAR

// Body
Start_Trig(CLK := Start_Button);
Start_Pulse := Start_Trig.Q;

When P_TRIG is instantiated inside an FB, TIA Portal stores the edge bit in the FB's instance DB automatically; you do not need to pass a memory bit explicitly. If you instantiate P_TRIG in a global DB (single instance), the compiler creates a P_TRIG_DB data block that holds the edge bit for you.

For OB1-global logic, the equivalent in a global SCL block is to declare a static helper and call P_TRIG against it:

VAR_GLOBAL
  Start_Button    : BOOL;
  Start_Pulse     : BOOL;
  Start_Trig_Inst : P_TRIG;   // edge bit lives in the instance DB
END_VAR

Start_Trig_Inst(CLK := Start_Button);
Start_Pulse := Start_Trig_Inst.Q;

7. Step-by-Step: Implementing a Positive Edge in LAD on a CPU 1214C

7.1 Declare the Tags

  1. Open the project in TIA Portal and expand PLC_1 > PLC tags > Default tag table.
  2. Add a Boolean input tag Start_Button with address %I0.0.
  3. Add a Boolean memory tag Start_Pulse with address %M0.0 (or omit the address to let TIA Portal assign a free one).
  4. Add a Boolean memory tag Start_Button_Edge with address %M0.1.

7.2 Insert the Rung

  1. Open Main [OB1] in the LAD editor.
  2. Insert a new network (Network 2 if a default network 1 exists).
  3. Drag a normally-open contact from the right-hand instructions palette. Assign operand "Start_Button".
  4. Drag a --(P)-- coil onto the right of the contact. The box has two fields: top = "Start_Pulse", bottom = "Start_Button_Edge".
  5. Compile the project. The compiler will warn if Start_Button_Edge is in TEMP storage; the warning text reads "Operand below an edge instruction must be located in a static/global area."

7.3 Download and Go Online

  1. Connect the engineering station to the CPU 1214C via PROFINET or the configured subnet.
  2. Select Online > Download to device. Confirm the firmware block version and select "Download to device."
  3. Click Go online. The LAD editor will display the live state of the contact and coil in green when TRUE.

8. Verification and Commissioning Checks

The following checks confirm that a positive-edge instruction is wired and configured correctly. Run them in order and stop at the first failed check.

  1. Static input test: force Start_Button to TRUE. Confirm that Start_Pulse is TRUE for only the first scan after the transition, then FALSE on every subsequent scan. Monitor with a watch table or the online LAD overlay.
  2. Toggle test: with a watch table, toggle Start_Button FALSE→TRUE→FALSE→TRUE in four successive scans. Confirm that Start_Pulse is TRUE on the first and third scan transitions only.
  3. Memory-bit inspection: in the same watch table, enable monitoring on Start_Button_Edge. Confirm that this tag mirrors the previous scan's value of Start_Button exactly. If the operand shows the current value, the contact is wired upside-down.
  4. Counter sanity: connect the P-edge pulse to a CTU counter. Press the button five times. Confirm that the counter value advances by exactly 5, regardless of how long the button was held.
  5. Restart test: perform a STOP→RUN transition on the CPU while the input is TRUE. Confirm that no edge fires on the first cycle (because the memory bit is initialized equal to the input on cold start; the S7-1200 process image is refreshed on STOP→RUN).
Safety caveat: Edge detection must not be relied upon for safety-critical inputs such as E-Stop pushbuttons or light curtains. Use a fail-safe CPU (e.g., CPU 1214FC) and the F-library's built-in discrepancy monitoring for safety signals.

9. Common Pitfalls and Corrections

Symptom Likely Cause Corrective Action
Coil never fires Memory bit is a TEMP tag, uninitialized every scan Move the operand to a global DB or FB Static section
Coil fires on every scan while input is TRUE Same memory bit used by more than one edge instruction Allocate a unique edge bit per instruction
Coil fires on the first scan after CPU restart Input was TRUE while CPU was in STOP; process image differs from edge bit Initialize the edge bit in startup OB100, or accept the documented behavior
Compiler warning "Edge operand must be a writable tag" Memory bit is bound to a read-only input Use a DB or M tag; never an %I address
Compiler error in SCL: "P_TRIG requires an instance" Calling P_TRIG as a function (FC) without an instance Instantiate P_TRIG in VAR or VAR_GLOBAL; the multi-instance holds the edge bit
Pulse width seems too short / too long Confusion between contact form and coil form; using both at once Use exactly one of --|P|-- or --(P)--; both produce identical pulse width of 1 OB1 cycle

10. Notes on Optimized Block Access

S7-1200 firmware V4.2 and later enables "Optimized block access" by default for newly created DBs. Optimized blocks store tags symbolically without fixed addresses, but edge instructions continue to work because the operand below --|P|-- is identified symbolically. The two practical implications are:

  • An edge memory bit declared in an optimized DB cannot be addressed by an absolute address from outside the DB; use the symbolic name "MyDB".Start_Button_Edge.
  • Watch tables in TIA Portal V15+ display the symbolic name and current value of optimized edge bits in the same column; no special configuration is required.

11. Edge Detection Compared with the LOGO! Soft Comfort Switch

Engineers moving from LOGO! to S7-1200 frequently compare the two environments. The single-click "positive edge" switch in LOGO! Soft Comfort is a graphic block that hides the memory-bit requirement. In TIA Portal the same primitive is exposed as a two-operand contact because the underlying IEC 61131-3 standard requires the edge bit to be a named, writable tag. The behavior is identical: one TRUE output for the first scan in which the input transitions from FALSE to TRUE. The S7-1200 version is also more flexible because the same memory bit can be reused in FB instances, while the LOGO! switch is local to the FBD block.

12. Frequently Asked Questions

What does the lower operand on the --(P)-- coil mean?

It is a Boolean memory tag (NOT a TEMP) that stores the input's previous-scan state. The edge instruction writes the current input value into this tag on every scan and compares it to the new value to detect a FALSE-to-TRUE transition. Declare it in a global DB, the enclosing FB's Static section, or a Merker address.

Can I use a TEMP variable as the edge memory bit?

No. TEMP variables are uninitialized at the start of each scan, so the previous-state comparison is meaningless. TIA Portal's compiler may or may not flag this; always use a global, static, or instance-DB tag.

Why does the edge coil fire only once even though the input is still TRUE?

The edge instruction outputs TRUE for exactly one OB1 scan on a FALSE-to-TRUE transition. On the next scan, the input is still TRUE, but the previous-state bit also equals TRUE, so no transition is detected. The pulse is therefore one scan wide, regardless of how long the input remains TRUE.

What is the difference between --(P)-- and P_TRIG?

--(P)-- is the LAD/FBD coil form; P_TRIG is the function-block form used in SCL/STL. Both produce a one-scan TRUE pulse on a FALSE-to-TRUE transition. P_TRIG is preferred in SCL because the edge bit is encapsulated in the multi-instance, avoiding the need to declare a separate global memory bit.

Does the edge fire on the first scan after a CPU STOP-to-RUN transition?

No, provided the input is FALSE at the moment of restart. The S7-1200 refreshes the process image and resets the edge bit on STOP-to-RUN, so no transition is detected on the first cycle. If the input is TRUE at restart, the edge bit and the input initialize to the same value and no edge fires — this is documented behavior for firmware V4.0 and later.

Back to blog