Siemens STEP 7 --(P)-- and --(N)-- Edge Contacts: Migration from S7-200 MicroWIN to STEP 7 and TIA Portal
1. Overview
The --|P|-- (positive edge) and --|N|-- (negative edge) contacts familiar to engineers using the SIMATIC S7-200 MicroWIN programming software do not exist as named, parameterless instructions in classic STEP 7 (SIMATIC Manager) or in TIA Portal. Their functional equivalent is the --(P)-- and --(N)-- coil-style instruction found in the Bit Logic folder of both editors, and the P_TRIG / N_TRIG function blocks (or the legacy POS / NEG / FP / FN instructions) used in FBD and SCL/ST.
The single most important difference between MicroWIN and STEP 7 / TIA Portal edge detection is the requirement for an explicit edge memory bit. In S7-200 MicroWIN, the |P| and |N| instructions automatically use a hidden internal flag. STEP 7 and TIA Portal force the programmer to allocate a unique boolean tag (M, DB, I, Q, or instance) to each edge instruction, and the editor refuses to compile the block until that assignment is made.
This reference covers the LAD, FBD, and SCL/ST forms of the instruction, the edge memory bit rules, the migration procedure from S7-200 to S7-300/400/1200/1500, and the most common pitfalls (shared tags, scan-order dependencies, retained vs non-retained memory).
2. Edge Detection Fundamentals
An edge is a state transition of a boolean signal during one PLC scan. Two transitions are meaningful in discrete control:
-
Positive edge (rising edge): signal changes from
0(FALSE) to1(TRUE). Often abbreviated as P or RE. -
Negative edge (falling edge): signal changes from
1(TRUE) to0(FALSE). Often abbreviated as N or FE.
The output of an edge instruction is TRUE for exactly one OB1 scan cycle when the transition is detected, and FALSE in all subsequent scans until the input transitions again. This one-shot behavior is the foundation of event counters, latching logic, debounce-free transition recognition, and pulse generation.
Mathematically, a positive edge on input IN with edge memory M is computed as:
Q = IN AND NOT M_prevM_prev := IN
The edge memory bit therefore stores the previous state of the input. Two independent edge instructions must never share the same edge memory bit, because each write would corrupt the other's stored previous state and suppress or duplicate edges.
--(P)-- and --(N)-- instructions are evaluated once per call of the parent code block. If the block is called multiple times in the same scan (for example, from a multi-instance or an alarm OB), each call increments the internal edge counter. Always place edge instructions in code that is executed exactly once per cycle, typically OB1 or a cyclic interrupt OB.3. P and N Contacts in S7-200 MicroWIN (Legacy Reference)
On the S7-200 platform, the MicroWIN instruction set exposes two contacts in the Bit Logic toolbar:
-
--|P|--— positive (rising) edge contact. Closed for one scan when the upstream logic transitions from FALSE to TRUE. -
--|N|--— negative (falling) edge contact. Closed for one scan when the upstream logic transitions from TRUE to FALSE.
A typical MicroWIN network evaluates a rising edge on the boolean M10.1 and, on detection, sets output Q0.0:
M10.1 Q0.0
----| |-------|P|--------( )---
MicroWIN automatically allocated an internal edge memory bit in the system area (V memory region) and managed the previous-state storage internally. The programmer was not required to specify or even know which bit was used. This convenience is the single biggest source of confusion when the same logic is re-implemented on S7-300/400 or S7-1200/1500.
The S7-200 product line reached end of life in 2017. New applications should be implemented on S7-1200/1500 with TIA Portal, and existing S7-200 logic should be migrated using the conversion paths described in section 9.
4. --(P)-- and --(N)-- in Classic STEP 7 (SIMATIC Manager, S7-300/400)
Classic STEP 7 (versions V5.x) and the SIMATIC Manager provide the following edge instructions in the Bit Logic folder of the program editor:
| Editor view | Instruction | Function | Edge memory argument |
|---|---|---|---|
| LAD | --(P)-- |
Positive edge contact / coil |
M, DB, or instance bit — required |
| LAD | --(N)-- |
Negative edge contact / coil |
M, DB, or instance bit — required |
| FBD | POS |
Positive edge flag |
CLK, Q, M_BIT
|
| FBD | NEG |
Negative edge flag |
CLK, Q, M_BIT
|
| STL | FP |
Positive edge on accumulator 1 | <bit> |
| STL | FN |
Negative edge on accumulator 1 | <bit> |
The LAD --(P)-- and --(N)-- appear as coil-type elements at the right end of a rung, although they are functionally contacts in the sense that they make a one-shot TRUE pulse available to downstream logic. The symbol matches the --( )-- assignment coil, with a P or N letter inside the parentheses.
To reproduce the MicroWIN example above, the engineer must:
- Allocate a free boolean tag for the edge memory, e.g.
M10.2. - Insert the
--(P)--instruction from the Bit Logic folder and assignM10.2above the coil symbol. - Wire the upstream RLO (the result of the
M10.1contact) into the--(P)--input. - Use the
--(P)--output as the energizing input to the assignment coil that drivesQ0.0.
The equivalent classic STEP 7 network looks like this:
M10.2
M10.1 Q0.0
----| |-----------(P)----------( )----
The M10.2 tag above the --(P)-- coil is the edge memory bit. It is the parameter that MicroWIN hides from the user; in classic STEP 7 it must be made explicit. The same tag is reserved exclusively for this one edge instruction.
--(P)-- or --(N)-- instruction in the program must be assigned a unique edge memory bit. Reusing M10.2 for two different edges will cause one of the edges to be silently suppressed, depending on which rung is scanned first. The compiler does not detect this misuse; it must be enforced by the programmer through naming conventions (for example, Edge_M10_1_Pos, Edge_Start_Neg).5. --(P)-- and --(N)-- in TIA Portal (S7-1200 / S7-1500)
TIA Portal exposes the same instructions with the same naming convention as classic STEP 7, with the addition of a dedicated Edge Memory Bit (M_BIT) input parameter that is more clearly surfaced in the tooltip and F1 help. The official TIA Portal help for the S7-1200 instruction set describes the positive edge contact as follows:
"Scan operand for positive signal edge. LAD: The state of this contact is TRUE when a positive transition (OFF-to-ON) is detected on the assigned IN bit, otherwise it is FALSE. The edge memory bit stores the previous state of the IN bit."
The TIA Portal implementation, however, is more forgiving: the editor can auto-generate an edge memory bit from the project symbol table when one is not explicitly assigned, marking it with the prefix <Edge>. This convenience feature is enabled by default in TIA Portal V15.1 and later, and it stores the bit in an automatically-managed instance DB or in the PLC tags area. Auto-generated edge bits can be identified in the cross-reference by the editor-assigned name.
For a fully explicit and self-documenting implementation, the engineer should still create a dedicated edge memory tag in the PLC tags table and assign it manually:
// PLC tags
Tag Type Address
Edge_M10_1 Bool M10.2 // edge memory for M10.1 rising edge
The TIA Portal LAD network for the migrated logic is identical in appearance to the classic STEP 7 version:
Edge_M10_1
M10.1 Q0.0
----| |--------------(P)--------( )----
For S7-1500, the same --(P)-- instruction is implemented in optimized block access, meaning the edge memory bit must be located in a tag that the compiler can resolve to a single bit of a byte/word/dword. TIA Portal V18 and later automatically marks edge memory tags as non-optimized-compatible; if the block uses optimized access, the tag must be a standalone Bool.
6. Edge Memory Bit Assignment Rules and Best Practices
Whether the project uses classic STEP 7 or TIA Portal, the following rules apply to the edge memory bit (M_BIT):
-
Uniqueness. No two
--(P)--or--(N)--instructions may share the same M_BIT. Sharing causes one edge to overwrite the other's stored previous state. -
Single-bit width. M_BIT must resolve to a single boolean. Assigning a byte (e.g.
MB10) is not allowed; the tag must be of typeBoolat a bit address (e.g.M10.2). - Non-retained or retained? Use a non-retained bit (default for M area) so that a power-cycle resets the edge history. Retained bits carry the last state across restarts, which can produce a spurious edge on the first scan after a warm restart if the input is already TRUE.
- No re-use of the same bit as a normal flag. The same tag must not be SET, RESET, or assigned in another network. The compiler does not enforce this, but doing so corrupts the stored previous state and causes missed or duplicate edges.
- Single scan-cycle exposure. The pulse is true for exactly one OB1 cycle. Any downstream logic that requires the pulse for longer than one cycle must latch it explicitly.
-
Order of evaluation. In LAD/FBD, the
--(P)--must be reached in the same scan in which the input transitions. Re-ordering rungs can change which edge is detected first when two edges share a common trigger network.
A common naming convention used in industrial code reviews is to name the edge memory bit with a _EM_ suffix or to bind it inside a dedicated edge data block (DB). For multi-instance patterns, an instance DB of a function block containing the edge instruction is preferred to ensure uniqueness through the compiler-generated DB number.
FP on the negative transition of an OB1_FirstScan flag.7. LAD, FBD, and SCL/ST Equivalents
The following table shows the three representations of a rising edge on a boolean input bStart that sets a latch bLamp. The edge memory bit is bEdgeStart. All three forms compile to identical machine code on S7-1200/1500.
| View | Code |
|---|---|
| LAD | |
| FBD | |
| SCL | |
For S7-300/400 STL, the rising edge of bStart with edge memory bEdgeStart is written as:
// STL (S7-300/400)
A bStart // AND input
FP bEdgeStart // positive edge on M_BIT
S bLamp // set latch if edge detected
For the falling edge, the LAD contact --(N)-- is the mirror image. In STL the equivalent is FN:
// STL (S7-300/400) - falling edge
A bStop
FN bEdgeStop
R bLamp // reset latch on falling edge of bStop
8. P_TRIG and N_TRIG Function Block Alternative
In TIA Portal V13 and later, the P_TRIG and N_TRIG blocks (and their older aliases R_TRIG and F_TRIG) are available in the Bit Logic → Edge Detection folder. They are functionally identical to --(P)-- / --(N)-- but expose a multi-instance interface, which is the recommended pattern in S7-1500 programs that follow the PLC Open style:
-
P_TRIG (positive / rising edge detector): inputs
CLKandM_BIT; outputQ. -
N_TRIG (negative / falling edge detector): inputs
CLKandM_BIT; outputQ.
When the block is called from a function block (FB) using multi-instance capability, the edge memory bit is stored in the instance DB, guaranteeing uniqueness by construction. This is the preferred pattern for engineers migrating S7-200 code that contained dozens of |P| and |N| instructions, because the instance DB approach eliminates the bookkeeping required to allocate unique M bits.
A minimal SCL example of a multi-instance P_TRIG inside an FB:
FUNCTION_BLOCK FB_Conveyor
VAR
iRun : BOOL; // run input
iRunEdge : P_TRIG; // multi-instance edge detector
bRunLatch : BOOL; // latched run bit
END_VAR
IF iRunEdge.CLK := iRun; iRunEdge() THEN
bRunLatch := TRUE;
END_IF;
Note that when the multi-instance P_TRIG is used, the M_BIT parameter is stored in the instance DB and is therefore allocated by the compiler, eliminating the unique-tag bookkeeping error class entirely.
9. Step-by-Step Migration Procedure from S7-200 to STEP 7 / TIA Portal
The following procedure applies to engineers porting S7-200 MicroWIN programs (using |P| / |N|) to a modern controller. The procedure is the same whether the target is an S7-300/400 with classic STEP 7 or an S7-1200/1500 with TIA Portal.
9.1 Prerequisites
- The S7-200 source program in MicroWIN (.mwp or .mwt format) or exported as a STEP 7 source file.
- A target controller firmware version that supports the required instructions: S7-300/400 firmware ≥ V2.0 for STL
FP/FN(universal), S7-1200 firmware ≥ V4.0 for full TIA Portal edge support, S7-1500 firmware ≥ V1.0 (all instructions available out of the box). - A TIA Portal installation matching the target controller family, version ≥ V16 SP1 for S7-1200/1500 (V18 or later is recommended for current projects).
- An empty edge memory data block (DB) or a reserved M area, e.g.
MB100..MB199, dedicated exclusively to edge bits.
9.2 Migration Procedure
-
Inventory the edge instructions. Open the S7-200 program and count every
|P|and|N|contact. Record the upstream RLO tag and the downstream consumer tag for each. The micro-grained inventory is the input to the next step. -
Allocate unique edge memory bits. For each edge, assign a unique boolean tag in the reserved M or DB area. Use a naming convention such as
Edge_<source>_P/Edge_<source>_N. -
Insert the new instructions. In the target editor, locate Bit Logic → --(P)-- and --(N)--. Drag the instruction into the rung, or in LAD double-click the rung terminus and type
--|P|--(TIA Portal auto-completes to--(P)--). -
Assign the edge memory bit. Click the
M_BITplaceholder above the coil symbol and type the allocated tag, or pick it from the PLC tag table dropdown. -
Wire the network. Connect the upstream contact (the original
| |instruction that was left of|P|) to the input of the--(P)--and connect the output to the original downstream consumer (typically a coil, set, or reset). -
Reserve an instance DB pattern where practical. For S7-1500, encapsulate each edge in a multi-instance
P_TRIGorN_TRIGinside an FB. The compiler will then allocate edge memory automatically and uniqueness is enforced by the data block structure. - Re-validate the network. Use the Compile command. STEP 7 and TIA Portal both raise a compile error if the edge memory bit is missing or assigned to a non-boolean tag.
9.3 Verification on the Target Controller
- Download the project to the target PLC and put it in RUN.
- Force the upstream contact to
0using the watch table / monitor and modify window. - Toggle the contact to
1and observe the edge bit and the downstream output. The edge bit should remain0for at least one full scan after the rising edge is processed. - Use a trace recording in TIA Portal (S7-1500 only) or the VAT (variable status table) to confirm that the
--(P)--output is TRUE for exactly one OB1 cycle. - Repeat the test for a falling edge: confirm that
--(N)--output is TRUE for one cycle on the 1→0 transition only.
10. Common Pitfalls and Diagnostics
The following matrix lists the most frequent defects introduced by migration from S7-200 MicroWIN, the symptom, and the corrective action.
| Defect | Symptom | Root cause | Correction |
|---|---|---|---|
Edge memory bit shared between two --(P)-- instructions |
One of the two edges is missed on roughly half the transitions | Both instructions write to the same M_BIT; the second write overwrites the first |
Allocate a unique tag per instruction; refactor with P_TRIG multi-instances |
| Edge memory bit in the retained area | First edge after a warm restart is missed | The retained bit holds the last previous state, so the input is already "high" in the edge memory | Move the bit to the non-retained area, or initialize it in OB100 |
| Edge instruction used in an FB called from multiple alarm OBs | Edge fires multiple times per OB1 scan | The instruction is evaluated once per call, not once per scan | Move edge evaluation to a single call site in OB1, or use P_TRIG with a static instance |
| Edge memory bit missing in FBD | Compile error: "Parameter M_BIT is missing" | The M_BIT input is not wired |
Wire a unique boolean tag to the M_BIT input |
Edge bit type is Byte instead of Bool
|
Compile error: "Type mismatch" | STEP 7 and TIA Portal require a single-bit boolean | Change the tag declaration to Bool at the bit-level address |
| Edge instruction inside a non-OB1 cyclic block (e.g. OB35) with edge memory in M area | Behavior inconsistent with S7-200 expectations | The M bit is overwritten in OB35, but read in OB1, causing interleave artifacts | Place the edge instruction in the same block that reads it, or move the edge memory to a DB local to the block |
| Auto-generated edge bit renamed by the user | Cross-reference shows the tag is used by an instruction that does not visually contain it | TIA Portal's auto-allocation creates a hidden tag; renaming the tag invalidates the linkage | Use the right-click → Rename edge bit command, or allocate the bit manually from the start |
11. Advanced Use Cases
11.1 Generating a Fixed-Width Pulse
The single-cycle pulse of --(P)-- is too short for some HMI or fieldbus handshake sequences. To generate a fixed-width pulse, the standard pattern is to combine --(P)-- with a self-resetting timer:
// LAD pattern (TIA Portal)
bEdge_M TON "PulseTimer"
--| |---------------(P)----(IN)----
PT = T#200ms
When --|P|-- fires, it sets the IN of the on-delay timer for one cycle. The timer then runs to its preset (200 ms in this example) and resets, producing a clean 200 ms pulse regardless of the input transition.
11.2 Debounced Edge from a Mechanical Input
Mechanical contacts produce contact bounce that can register as multiple edges within a few milliseconds. The --(P)-- instruction alone will fire multiple times during the bounce window. The recommended mitigation is to pass the input through an IEC timer configured for the bounce time (typically 5–20 ms) before feeding it to the edge instruction:
// Debounce with on-delay timer
iRawSwitch -> TON bDebounced, PT = T#10ms
bDebounced -> --(P)-- with bEdgeDebounce memory bit
11.3 Counting Events
The standard pattern for counting events uses the CTU IEC counter and the --(P)-- instruction as the count trigger:
// Counter increment on rising edge of bPartDetected
bPartDetected ----(P)---- CTU iCounter, PV := 1000
12. References and Official Documentation
- TIA Portal Help: Positive and Negative Edge Instructions (S7-1200)
- SIMATIC S7-1200 Programmable Controller System Manual
- SIMATIC TIA Portal V18 Programming and Operating Manual
- SIMATIC S7-300 CPU 31xC and CPU 31x: Installation and Operating Manual
- SIMATIC S7-1200 Programmable Controller: System Manual (current edition)
- SIMATIC S7-1500 Automation System: Function Manual
What is the STEP 7 equivalent of the S7-200 --|P|-- contact?
The LAD instruction is --(P)-- (positive edge coil/contact), found in the Bit Logic folder of both classic STEP 7 (SIMATIC Manager) and TIA Portal. Unlike the S7-200 |P| contact, the --(P)-- requires an explicit edge memory bit (M_BIT) of type Bool, for example M10.2, which must be unique to that one instruction.
Why does the compiler reject my --(P)-- instruction with a type-mismatch error?
The edge memory bit (M_BIT) must resolve to a single-bit boolean tag. Tags declared as Byte, Word, or DWord are rejected. Declare the tag as Bool at a specific bit address (e.g. M10.2) or as a single-bit DB element, and the compile error will clear.
Can two --(P)-- instructions share the same edge memory bit if they detect the same input?
No. Each --(P)-- or --(N)-- instruction must be assigned a unique edge memory bit. Sharing the bit causes one of the instructions to overwrite the previous-state storage of the other, producing missed or duplicated edges depending on rung scan order. Use a unique tag per instruction, or switch to multi-instance P_TRIG / N_TRIG blocks where the compiler allocates the bit in the instance DB.
How long is the output of a --(P)-- instruction TRUE?
Exactly one OB1 scan cycle. The pulse is high in the scan in which the input transitioned from FALSE to TRUE, and low in every subsequent scan until the next rising transition. Use a self-resetting timer to extend the pulse to a fixed width for HMI or handshake sequences.
My rising edge fires correctly during normal operation but is missed on the first scan after a warm restart. What is wrong?
The edge memory bit is in a retained area (retained M bits or retained DB), so it stores the last previous state across the restart. If the input is already TRUE on the first scan after restart, the edge comparator sees input == previous state and does not fire. Move the edge memory bit to the non-retained area, or initialize it in OB100 with := FALSE at the start of the warm restart routine.
Is the P_TRIG function block identical to the --(P)-- instruction?
Functionally yes, both detect a rising edge and produce a one-scan TRUE pulse. The difference is interface: P_TRIG exposes explicit CLK, M_BIT, and Q parameters and can be instantiated as a multi-instance inside an FB, with the edge memory stored in the instance DB. The --(P)-- instruction is more compact for one-off edges in OB1 but requires the programmer to allocate a unique M_BIT tag by hand.
Why does the same input trigger two edges in rapid succession on an S7-1200/1500 but only one edge on an S7-200?
Mechanical contact bounce. The S7-200 program in MicroWIN often includes implicit analog filtering of the digital input; the S7-1200/1500 digital inputs are unfiltered by default and pass the bounce through to the edge instruction. Configure the input filter (in the device configuration of the CPU) to 5–20 ms, or debounce the signal in software with an on-delay timer before the edge instruction.