1. Overview: Why Edge Detection Matters in S7-1200 / S7-1500 Programming
Edge detection is the mechanism that turns a continuous Boolean signal into a one-shot pulse, sampled on every PLC scan. A positive edge (rising edge) is the OFF→ON transition of a bit; a negative edge (falling edge) is the ON→OFF transition. Edge instructions are required whenever a downstream action must execute exactly once per press of a button, per arrival of a new process value, or per completion of a sequencer step.
In the SIMATIC S7 family, edge detection has historically been handled by two operators in STEP 7 Classic (Simatic Manager):
-
P— Positive RLO Edge Detection (FP in STL, scans the result of logic operation) -
POS— Address Positive Edge Detection (FP on a named operand)
Starting with TIA Portal V11, the bit-logic editor exposes three positive edge operators, and the introduction of the S7-1200/S7-1500 (with their optimised data blocks and stricter memory model) made the choice between them non-trivial. The three operators in TIA Portal V13 SP1 Update 5 and later are:
-
--|P|--— Scan operand for positive signal edge (contact-style) -
--(P)--— Set operand on positive signal edge (coil-style) -
P_TRIG— Scan RLO for positive signal edge (FB-style box)
Each of these maps to one of the two Classic operators with subtle differences in where the edge memory bit must be declared, which signal is actually being edge-tested, and how the result is delivered to the rest of the program. The remainder of this article resolves the equivalences, identifies the operator that mimics the Classic P instruction, and builds a latched start/stop circuit on a CPU 1214 DC/DC/DC.
2. Operator Inventory and Cross-Tool Mapping
| TIA Portal V13+ Symbol | Name (TIA Help) | Classic Equivalent (STL) | Classic Equivalent (LAD/FBD) | Memory Bit Owner |
|---|---|---|---|---|
--|P|-- |
Scan operand for positive signal edge | FP <operand> |
Contact with edge attribute on operand (POS in FBD) | Hidden, system-allocated in instance / global DB |
--(P)-- |
Set operand on positive signal edge |
FP <edge_bit> ; = <result> (single network) |
Coil that pulses a flag | Hidden, system-allocated in instance / global DB |
P_TRIG |
Scan RLO for positive signal edge |
FP <edge_bit> on RLO |
Box (FB) placed anywhere on the network | Edge bit in INOUT (must be user-supplied, non-TEMP, non-optimised-DB-slice) |
When migrating STEP 7 Classic code into TIA Portal V13, the most common equivalence is:
-
Classic
Pon RLO → TIA PortalP_TRIG -
Classic
POSon a flag / input → TIA Portal--|P|-- -
Classic
Pon a flag used as a one-shot → TIA Portal--(P)--
--|P|-- and --(P)-- operators hide the edge memory bit inside a system-managed area of the instance / global DB. The user no longer has to allocate an M bit manually, but the optimisation view in TIA Portal will still show the auxiliary bit as a structure member of the calling FB or of the system data block. Do not delete or rename it.3. Operator Behaviour in Detail
3.1 --|P|-- — Scan operand for positive signal edge
This is a normally-open contact with an edge attribute. The operand is sampled each scan; the contact closes (passes power flow / evaluates to TRUE) for exactly one PLC cycle on the OFF→ON transition. It is the direct successor of the Classic POS instruction and is the operator most engineers reach for first.
Typical placement: in a ladder rung where the rising edge of an input or flag must trigger a downstream action within the same network.
Network 1 (LAD)
| %I0.0 %M0.0
|--|P|-------( S )---------|
"Button_Start" "Start_latched"
(--|P|-- on input ; (S) latches the run bit
3.2 --(P)-- — Set operand on positive signal edge
This is a coil that produces a one-cycle TRUE pulse on its assigned operand whenever the RLO entering the coil transitions from FALSE to TRUE. The result is written to the operand on the right-hand side of the coil. It is functionally identical to --|P|-- in effect, but the polarity of who is being edge-tested is reversed: --(P)-- tests the RLO of the network; --|P|-- tests the operand of the contact.
Typical placement: when the edge should be derived from a combination of conditions (e.g. "run mode active AND input just turned on") and the resulting pulse must be saved to a flag for use in a different network.
Network 1 (LAD)
| %I0.0 %M10.0 %M0.1
|------| |--------(P)------|
| "Button_Start" "Start_pulse"
| "Mode_Auto" (--(P)-- coil)
3.3 P_TRIG — Scan RLO for positive signal edge (FB box)
P_TRIG is the only one of the three that is implemented as a function block instance (system FBs FB_TRIG_P in the program resources). It exposes an CLK input (the RLO it is connected to) and an INOUT pin M_BIT that must be supplied by the user. The Q output is TRUE for one cycle on the rising edge of CLK.
Where --|P|-- and --(P)-- are the preferred forms on S7-1200/S7-1500, P_TRIG remains useful when:
- The edge must be tested on a calculated Boolean expression that cannot be expressed as a single operand.
- The same edge bit must be inspected by multiple networks in the same FB (SCL-style structuring).
- The code is being back-ported to an S7-300/S7-400 (where contact/coil edge attributes are not always available in LAD).
// SCL representation of P_TRIG
a_P_TRIG(
CLK := bStartPressed,
Q => bStartPulse);
// M_BIT handled internally as INOUT static
4. Selecting the Right Operator for a Start/Stop Latch
The user's requirement is the canonical "motor starter" circuit:
- Pressing
#button_Startsets output#Start. - The set state is retained after the button is released.
- Pressing
#button_Stopresets#Start. - After releasing the stop button, a new press of
#button_Startis required to restart.
Because the Start button is pressed momentarily and the output must be latched across the release of the button, the start logic must be edge-detected. A direct | | (OR) of the button onto the output would self-hold the moment the contact closes — but on a real panel button the contact bounces and the user may want to ignore the bounce. The edge instruction guarantees a one-shot.
The stop side does not need edge detection: a level-triggered reset is desired so the operator can hold the Stop button down and walk away. The choice is therefore --|P|-- on the start button (it is the operand that is being edge-tested) combined with --(S)-- and --(R)-- coils. The P_TRIG instruction is unnecessary overhead here because only one operand is being edge-tested and the result is consumed in the same network.
5. Implementation on a CPU 1214 DC/DC/DC
5.1 Symbol and Tag Declaration (PLC Tags / FB Interface)
| Symbol | Address / Scope | Type | Initial Value | Comment |
|---|---|---|---|---|
button_Start |
%I0.0 (input, NC/NO configurable) | Bool | FALSE | Start pushbutton, NO contact |
button_Stop |
%I0.1 (input) | Bool | TRUE | Stop pushbutton, NC contact → TRUE = released |
Start |
FB static / global tag | Bool | FALSE | Latched run bit |
Old_Start |
Not required with --|P|--
|
— | — | System allocates the edge bit |
K0_Motor |
%Q0.0 (output) | Bool | FALSE | Contactor / motor output |
button_Stop_NC := NOT %I0.1) to retain the same fail-safe behaviour.5.2 Ladder Implementation (Network 1 — Set Latch)
Network 1: Latch the run bit on rising edge of Start
| %I0.0 "Start"
|--|P|----------------------( S )------|
"button_Start" (BOOL tag)
| | |
| +---( )---+ (optional seal-in shown in §5.3)
The single contact --|P|-- on button_Start closes for one scan, the (S) coil sets "Start" to TRUE, and the bit remains set because nothing in this network can clear it.
5.3 Ladder Implementation (Network 2 — Reset Latch and Drive Output)
Network 2: Reset on Stop, drive contactor, optional seal-in for diagnostics
| %I0.1 "Start" %Q0.0
|------|/|------------------( R )----( )----|
| "button_Stop" (BOOL tag) "K0_Motor"
| | |
| "Start" | |
|------| |-----------------------+ (seal-in, optional)
Stop is wired NC, so its contact is shown as |/| (normally-closed). The (R) coil clears "Start" as long as Stop is pressed. The contactor %Q0.0 follows "Start" directly; the seal-in contact | | (OR) is shown only for diagnostic visibility (it can be removed if "Start" is already wired to the output).
5.4 STL Equivalent (For Reference)
Network 1
A "button_Start" // operand-style edge (--|P|--)
FP // Classic equivalent would require a hidden
// system edge bit; in TIA Portal the editor
// inserts it automatically.
S "Start"
Network 2
AN "button_Stop" // NC, so test for FALSE = pressed
R "Start"
A "Start"
= "K0_Motor"
5.5 SCL Implementation (Inside an FB, Cyclic OB1)
IF "button_Start" AND NOT "edge_button_Start" THEN
"Start" := TRUE; // rising edge of Start
END_IF;
"edge_button_Start" := "button_Start"; // remember the previous state
IF NOT "button_Stop" THEN // Stop is NC, so NOT = pressed
"Start" := FALSE;
END_IF;
"K0_Motor" := "Start";
The SCL form makes the edge memory bit explicit: edge_button_Start is a static FB tag of type BOOL, never a TEMP, because TEMP memory is not retained across scans and the edge will never be detected.
6. Edge Memory Bit — Rules That Prevent "It Doesn't Latch" Bugs
When the start logic refuses to latch on TIA Portal V13 and the engineer has cycled through all three operators without success, the failure is almost always one of these three:
-
Edge bit declared in TEMP. TEMP memory in S7-1200/S7-1500 FB interface is re-initialised on every call, so the previous scan value is lost and the edge comparator never sees a stable FALSE→TRUE transition. The
P_TRIGM_BIT must be in STATIC, in a global DB, or in a non-optimised M-bit area. Siemens' basic-instructions manual flags this explicitly under the Positive and negative edge instructions section. -
Edge bit aliased inside an optimised DB slice. S7-1500 (and S7-1200 firmware ≥ 4.2 with optimised block access) stores BOOLs as individual bits, not as a packed WORD. Pointing
P_TRIG.M_BITat aWORDtag and then bit-slicing it (%MW10→%M10.5) works in Classic, but TIA Portal will warn that the slice is not a valid INOUT for an FB. The fix is to declare a dedicatedBOOLstatic tag. - Stop button wired NO instead of NC, and the logic tested the raw input. The latching works correctly, but the output drops the moment Start is released because Stop is interpreted as "released." Inverting the input symbol resolves the issue without touching the edge logic.
Siemens documents these constraints in the S7-1200 manual collection, specifically the Basic instructions > Bit logic operations > Positive and negative edge instructions page, which states: "The Q output power flow or logic state is TRUE when a positive transition (OFF-to-ON) is detected at the CLK input." The transition is sampled on the OB1 cycle; any variable that cannot guarantee retention between two consecutive calls is not eligible as the M_BIT.
7. Why the Original Code Failed in TIA Portal V13
A frequent migration error is to copy a Classic FBD branch containing the explicit edge bit --|P|-- (M1.0) --(P)-- and rely on TIA Portal to translate. The translator maps the contact to --|P|-- on the input operand and the coil to --(P)-- on a flag — but if the M1.0 in Classic was previously shared with another network, the TIA Portal system edge bit is not the same address and the second network loses its edge. The visible symptom is "the output latches once, then never again," because the second network reads a flag that the system has already overwritten with a different value.
The fix is to make the edge local to a single FB instance (the system does this automatically when the operator is dropped inside an FB) or, when working in OB1, to declare a dedicated global edge_StartPulse : BOOL tag and write to it from a single --(P)-- coil.
8. Verifying the Circuit on the CPU 1214
- Compile the project (Ctrl+B) and check that no "Edge bit not unique" warnings appear in the Information pane.
- Download to the CPU 1214 DC/DC/DC (TIA Portal > Online > Download to device). The firmware must be ≥ 4.2 for the full V13 SP1 U5 instruction set; older firmware rejects some 1500-style operators.
- Open the watch table, force
%I0.0and%I0.1to TRUE. Verify"Start"remains FALSE while Stop is held FALSE. - Pulse
%I0.0from FALSE to TRUE. Within one OB1 cycle (typically 1–10 ms depending on cycle time),"Start"should go TRUE and stay TRUE. - Pulse
%I0.1from TRUE to FALSE (Stop pressed)."Start"should drop on the very next scan; while%I0.1is held FALSE the latch cannot be re-set. - Release
%I0.1(back to TRUE) and re-pulse%I0.0. Latch should re-engage.
Use the online > Monitor > Monitor all modifier to step the OB1 cycle if your development environment supports it; the edge memory bit must toggle FALSE→TRUE exactly once per press.
9. Troubleshooting Matrix
| Symptom | Likely Operator | Root Cause | Corrective Action |
|---|---|---|---|
| Latch engages but never releases | --(R)-- |
Stop wired NO and tested as | |
|
Change to |/| or invert the input tag |
| Latch never engages on first press, engages on second | Any | Edge bit in TEMP | Move M_BIT to STATIC or global DB |
| Engages on first press, then latches on every subsequent scan | Plain contact (no edge) | Operator inserted as | | instead of |P|
|
Right-click the contact > "Edge evaluation" > Positive |
| Compiler warns "instance DB for P_TRIG missing" | P_TRIG |
FB not instantiated | Drag the box into the network — TIA auto-creates the instance |
| Works in simulation, fails on hardware | Any | Watch-dog / scan time too short relative to M_BIT in I/O image | Check OB1 cycle time and the process image update time |
10. Performance and Cycle-Time Considerations
The three edge operators have nearly identical execution cost in compiled SCL. On the CPU 1214 DC/DC/DC, each --|P|-- or --(P)-- compiles to a single bit-test, an XOR against the previous scan, and a copy — on the order of 10–30 ns per invocation. P_TRIG adds the FB call overhead (~150 ns), which becomes measurable only when the instruction is placed inside a tight loop above 10 kHz. For a one-shot on a pushbutton, all three are well below the noise floor of OB1 jitter.
The deciding factor is therefore architectural, not performance: prefer --|P|-- when the edge is on a single operand and the result is consumed in the same network; prefer --(P)-- when the edge is the RLO of a multi-operand expression and the pulse must be saved to a flag; prefer P_TRIG when the edge bit must be shared between networks or the code must compile on both S7-300/400 and S7-1200/1500.
11. Standards and Documentation References
- Siemens SIMATIC S7-1200 Manual Collection — Basic Instructions > Bit Logic Operations > Positive and Negative Edge Instructions (official, primary reference for the operator semantics quoted throughout this article).
- IEC 61131-3:2013, Section 6.5.2 (standard Boolean function blocks and edge detection semantics) — referenced as a normative document, not as a guarantee of a specific overload class.
Which TIA Portal V13 operator is equivalent to Simatic Manager's P (Positive RLO Edge Detection)?
The direct equivalent is P_TRIG, the function-block-style box. It tests the RLO at its CLK input and pulses Q TRUE for one cycle on the OFF→ON transition. The edge memory bit must be supplied at the M_BIT INOUT pin, declared as a STATIC FB tag or a global BOOL, never as TEMP.
What is the difference between --|P|-- and --(P)-- in TIA Portal V13?
--|P|-- is a contact that edge-tests the operand of the contact itself. --(P)-- is a coil that edge-tests the RLO entering the coil and writes the resulting one-shot pulse to the operand of the coil. They produce the same shape of pulse; the choice is about which side of the equation owns the edge.
Why does my start/stop latch engage on the first press but never on the second?
The edge memory bit is in TEMP memory. Move it to a STATIC FB tag, a global DB tag, or a non-optimised M-bit. TEMP is re-initialised every scan, so the comparator never sees a stable FALSE→TRUE transition after the first execution.
Do I need to upgrade the CPU 1214 firmware for these edge operators?
TIA Portal V13 SP1 Update 5 supports CPU 1214 firmware from V4.0 onwards. Operators --|P|-- and --(P)-- are available on all firmware versions; P_TRIG with a system-allocated edge bit is fully supported on firmware V4.2 and later. Run an online > Diagnostics to confirm the firmware before download.
Should the Stop button be wired normally-open or normally-closed for this circuit?
Wire Stop normally-closed (NC) so the input idles TRUE. The rung uses a |/| contact, which evaluates TRUE when the input is HIGH (button released) and FALSE when pressed. A broken wire then drops the input to FALSE and trips the motor — fail-safe behaviour. NO wiring requires an explicit input inversion in software to match.