1. Problem Overview
An S7-300 station with a 6ES7314, 6ES7315, 6ES7316, or 6ES7317 CPU monitors 120 digital inputs wired to one or more SM 321 digital input modules (for example, 6ES7321-1BL00-0AA0 with 32 DI, 24 V DC). During an installation stop event, a single field contact chatters for a few milliseconds, the PLC recognizes the falling edge, and the controlled process then propagates the fault - dozens of dependent signals transition to their safe/fault state within the same scan. The maintenance engineer is left with a screen full of "fallen" signals but no way to know which contact actually opened first. This is the classic First-Out problem: identify, with the highest resolution the CPU can provide, the first input whose state changed from 1 to 0 and freeze the record so it can be displayed on the HMI or read by service personnel.
The achievable resolution depends on the detection mechanism used:
- Hardware interrupt (OB40-OB47): 1 ms timestamp via SFC64 TIME_TCK or the OB40_POINT_ADDR / OB40_TIMESTAMP fields, independent of OB1 scan time.
- Cyclic OB1 evaluation: limited to OB1 cycle time (typical 5-50 ms for this I/O count); fast enough to find the first fallen input but unable to sequence two events inside the same cycle.
- Diagnostic interrupt (OB82) + diagnostic buffer (SFC52 WR_USMSG): records the moment a module detects a wire break, channel fault, or short circuit and is the mechanism for hardware-detected faults - not for ordinary 24 V input changes.
2. Root Cause Analysis - Why the First Signal Disappears
Three mechanisms cause the "lost first signal" symptom in S7-300 installations:
- Bounce / chatter on a real contact: mechanical limit switches, relay contacts, or proximity switches produce a 1->0->1->0 sequence inside a 1-5 ms window. The PLC sees the falling edge in cycle N, but by cycle N+1 the signal has recovered; meanwhile, the interlock logic has already latched the process stop and dozens of derived signals are now false.
- CPU scan time is larger than the pulse: with a 10 ms OB1 cycle and a 2 ms pulse, the falling edge can be missed entirely if the input is not captured at the hardware interrupt stage. STEP 7 only samples the process-image input (PII) at the start of OB1, so any pulse shorter than the cycle that does not align with the PII refresh is invisible to cyclic logic.
- Single-cause cascade: a single sensor open-circuits and, by the program logic, brings down a row of dependent outputs. The HMI shows the cascade, not the origin. The maintenance technician must restart the line, but on restart all signals return to TRUE, so the original cause is invisible.
The remedy is to latch the first falling input into a non-volatile bit that survives the restart, tag it with a timestamp, and surface it on the HMI in a dedicated "First-Out" faceplate.
3. Architecture - Three Detection Strategies
| Strategy | Mechanism | Resolution | CPU load | Hardware required | Best use |
|---|---|---|---|---|---|
| OB1 cyclic First-Out latch | Compare current PII to previous PII each cycle; first bit that was 1 and is now 0 wins. | OB1 cycle time (5-50 ms typical) | Low; one FB, one scan of 120 bits | None | Process inputs where ms resolution is unnecessary; sequence of events within one cycle not required. |
| Hardware interrupt (OB40) | SM 321 raises OB40 on configured falling edge; OB40 captures timestamp via SFC64. | 1 ms (SFC64) or hardware stamp (OB40_TIMESTAMP) | Negligible per event; 120 IS inputs = 120 event sources | SM 321 with hardware interrupt capability (e.g., 6ES7321-7BH00-0AB0, 6ES7321-7TH00-0AB0) | Critical interlocks, safety-relevant First-Out, signals shorter than OB1. |
| Diagnostic buffer (SFC52 WR_USMSG) | User program writes a structured event into the diagnostic buffer with date/time stamp. | 100 ms (diagnostic buffer time stamp) | One SFC call per event | None | Post-mortem logging; correlate with STEP 7 diagnostic buffer viewer. |
For most installations the OB1 First-Out latch is the workhorse because it works on any SM 321, costs nothing in hardware, and runs at the scan time the user already accepts. Hardware interrupts are added for the 5-10 inputs that genuinely need ms resolution. The diagnostic buffer is the third leg: an insurance policy that survives power-cycle and shows up in STEP 7 even if the HMI is down.
4. Strategy 1 - Cyclic First-Out Latch in OB1
4.1 Data Blocks
Create two global DBs. DB100 is the runtime buffer; DB101 is the HMI mirror.
DATA_BLOCK DB100
TITLE = FirstOut_Runtime
VERSION : 0.1
STRUCT
Prev_PII : ARRAY[0..14] OF BOOL; // 15 bytes = 120 bits, last cycle
FirstEdgeFound : BOOL; // 1 = first falling edge locked in
FirstEdgeBit : INT; // 0..119 absolute bit index
FirstEdgeByte : INT; // 0..14 PII byte number
FirstEdgeTime : DATE_AND_TIME; // SFC1 read time at the moment of capture
Reset : BOOL; // HMI reset pushbutton
END_STRUCT
END_DATA_BLOCK
4.2 Latch Function (ST)
The function reads the process-image input partition assigned to the user, compares it bit-by-bit against the previous scan stored in DB100.Prev_PII, and on the first detected 1->0 transition records the absolute bit index, the PII byte, and the current system time. The latch is one-shot: only the very first transition per "run" is captured; further transitions are ignored until Reset is pressed.
FUNCTION_BLOCK FB100 "FB_FirstOut_Latch"
VAR_INPUT
i_Reset : BOOL;
END_VAR
VAR_TEMP
i : INT;
j : INT;
byte_idx : INT;
bit_idx : INT;
cur_word : WORD;
prev_word: WORD;
mask : WORD;
changed : BOOL;
t_now : DATE_AND_TIME;
END_VAR
BEGIN
// 1) Reset handling
IF i_Reset OR DB100.Reset THEN
DB100.FirstEdgeFound := FALSE;
DB100.FirstEdgeBit := -1;
DB100.FirstEdgeByte := -1;
DB100.FirstEdgeTime := DT#1990-01-01-00:00:00;
DB100.Reset := FALSE;
END_IF;
// 2) Scan 15 bytes of PII (PII 0..14 corresponds to IB0..IB14)
IF DB100.FirstEdgeFound THEN
// Latch already armed - just refresh the previous image and exit
FOR i := 0 TO 14 DO
DB100.Prev_PII[i] := PI[i/8].%X(i MOD 8); // symbolic, see note below
END_FOR;
RETURN;
END_IF;
changed := FALSE;
FOR byte_idx := 0 TO 14 DO
cur_word := PIW[byte_idx/2] AND 16#00FF SHL ((byte_idx MOD 2) * 8);
prev_word := WORD_TO_INT(DB100.Prev_PII[byte_idx])
AND 16#00FF SHL ((byte_idx MOD 2) * 8);
// Detect any 1->0 transition in this byte
IF (prev_word AND NOT cur_word) <> 0 THEN
// Find the lowest-numbered bit that flipped
FOR bit_idx := 0 TO 7 DO
mask := 16#01 SHL bit_idx;
IF (prev_word AND mask) <> 0 AND (cur_word AND mask) = 0 THEN
DB100.FirstEdgeByte := byte_idx;
DB100.FirstEdgeBit := byte_idx * 8 + bit_idx;
t_now := READ_CLK(TRUE); // SFC1, returns DT
DB100.FirstEdgeTime := t_now;
DB100.FirstEdgeFound := TRUE;
changed := TRUE;
EXIT; // first one wins
END_IF;
END_FOR;
END_IF;
IF changed THEN EXIT; END_IF;
END_FOR;
// 3) Update previous image for the next cycle
FOR i := 0 TO 14 DO
DB100.Prev_PII[i] := PI[i/8].%X(i MOD 8);
END_FOR;
END_FUNCTION_BLOCK
PI[i/8].%X(i MOD 8) is SCL-style and assumes STEP 7 V5.5 with the optional SCL package. In pure LAD/FBD, replace the loop with 120 contacts and 120 memory bits (one per input) and feed them into a priority encoder. The bit-by-bit ST form shown above is also valid if you declare PI as an ARRAY[0..14] OF BYTE via an AT overlay to PIB 0 and use direct byte access: PIB[byte_idx].4.3 Call in OB1
CALL FB100 , DB100
i_Reset := "HMI".Cmd_FirstOut_Reset
Call the FB unconditionally at the very start of OB1, before any sequence logic, so the latch captures the first falling edge of the cycle. The FB takes well under 1 ms even at 120 bits on a 6ES7314 CPU.
5. Strategy 2 - Hardware Interrupt OB40 with Timestamp
For inputs that can pulse in the sub-millisecond range, configure a hardware interrupt on the SM 321 module and handle the event in OB40. On the 6ES7321-7BH00-0AB0 (16 DI, 24 V DC, interrupt-capable) and the 6ES7321-7TH00-0AB0 (16 DI, NAMUR) you enable hardware interrupts per channel in the HW Config "Inputs" tab. Each channel can be set to raise OB40 on a rising edge, falling edge, or both. The CPU passes to OB40:
-
OB40_POINT_ADDR- point address of the channel that triggered the interrupt (e.g.,0for IB0.0,7for IB0.7). -
OB40_TIMESTAMP- 16-bit value of the 1 ms counter at the moment of the event (only on modules that support timestamping; check the module manual - 6ES7321-7TH00 supports it, older -7BH00-0AA0 revisions do not).
5.1 OB40 skeleton
ORGANIZATION_BLOCK OB40
TITLE = "Hardware Interrupt - First Out Capture"
VERSION : 1.0
VAR_TEMP
info : WORD; // OB40_POINT_ADDR alias
ts_ms : WORD; // OB40_TIMESTAMP value
abs_bit : INT;
sys_time : DATE_AND_TIME;
END_VAR
BEGIN
// Capture the channel that fired
info := OB40_POINT_ADDR; // relative to module base address
ts_ms := OB40_TIMESTAMP; // 1 ms counter (rolls over at 65535)
// Convert OB40_POINT_ADDR to absolute bit index 0..119
// Assumes first hardware-interrupt module at PII byte 8 (IB8..IB15)
abs_bit := 8*8 + info; // 8 bytes of regular DI + channel offset
// One-shot latch, identical to FB100 but event-driven
IF NOT DB100.FirstEdgeFound THEN
DB100.FirstEdgeByte := 8 + (info / 8);
DB100.FirstEdgeBit := abs_bit;
DB100.FirstEdgeTime := READ_CLK(TRUE); // wall-clock time
DB100.FirstEdgeFound := TRUE;
// Optional: also store the 1 ms hardware counter for sub-cycle resolution
DB100.FirstEdgeTime_ms := ts_ms; // add this WORD to DB100
END_IF;
END_ORGANIZATION_BLOCK
Because OB40 runs to completion before OB1 resumes, two events firing in the same OB1 cycle are still serialized - OB40 instances do not preempt each other. Within a single OB40 invocation, if multiple channels triggered simultaneously (group interrupt), use the OB40_POINT_ADDR value and the channel mask in OB40_FLT_ID = 16#0A to enumerate them; the first one in the module's priority order wins the First-Out.
6. Strategy 3 - Diagnostic Buffer Entries with SFC52
SFC52 WR_USMSG writes a user-defined diagnostic event into the CPU diagnostic buffer, complete with date and time, that survives power cycle and is visible from STEP 7 > PLC > Module Information > Diagnostic Buffer. Use it as a black-box recorder for the First-Out event.
CALL SFC 52 // WR_USMSG
EV_ID := W#16#0 // not used for user messages
SIG := W#16#0
DT1 := DB100.FirstEdgeTime
DT2 := DT#1990-01-01-00:00:00
OB_NUMBER := 1
OB_PRIORITY:= 1
OB_EV_NUM := 1
COMP_ID := 'FBOUT' // 4 ASCII chars, free choice
EVENT_CLASS:= W#16#0B // 11 = user diagnostic, free text below
INFO1 := INT_TO_WORD(DB100.FirstEdgeByte)
INFO2 := INT_TO_WORD(DB100.FirstEdgeBit)
INFO3 := W#16#0
INFO4 := W#16#0
RET_VAL := MW 200
On the next service call, the technician opens STEP 7, reads the diagnostic buffer, sorts by time, and sees FBOUT / B=12 / B=99 - byte 12, bit 99 - with the exact time it was written. Pair SFC52 with the cyclic First-Out FB: SFC52 fires only on the rising edge of DB100.FirstEdgeFound to avoid flooding the buffer.
7. HMI Integration
On WinCC Flexible 2008 SP5, TIA Portal WinCC Comfort/Advanced, or a ProTool/Pro panel, expose four tags to the HMI:
-
DB100.FirstEdgeFound- bool - shows the red "First-Out active" lamp. -
DB100.FirstEdgeByte- int - PII byte. -
DB100.FirstEdgeBit- int - absolute bit index 0..119. -
DB100.FirstEdgeTime- Date_And_Time - displayed in field as DD.MM.YYYY HH:MM:SS.mmm.
Map FirstEdgeBit through a text list to show the engineer-friendly tag name. Maintain a separate DB101 with 120 strings, index = bit number:
DB101.Text[0] := 'E0.0 Start permissive';
DB101.Text[1] := 'E0.1 Guard door 1 closed';
DB101.Text[2] := 'E0.2 Guard door 2 closed';
...
DB101.Text[119] := 'E14.7 Lubrication OK';
The HMI faceplate is then a single rectangle with four fields - state, tag name, byte/bit, and timestamp - and one reset button wired to DB100.Reset. Use a momentary pushbutton, not a toggle: the reset must be re-armed to catch the next event.
8. Verification and Commissioning Procedure
- Build the program offline and download to the CPU. Verify OB1, OB40, OB82, and OB100 are present in the active project. STEP 7 > PLC > Module Information > Diagnostic Buffer should now show the download entries.
- Force DB100.FirstEdgeFound = FALSE and clear the previous-image array. The HMI should display "No First-Out" / grey lamp.
- Manually trigger one input (e.g., disconnect E0.3) for 50 ms. Check HMI: red lamp, tag = "E0.3 ...", time = current time to the second.
- Press reset on HMI. The lamp goes off and FirstEdgeBit returns to -1.
- Repeat the test but with a 5 ms pulse (function generator on a 24 V input). On a system running OB1 only, the event should still be captured because OB1 cycle < 5 ms; on OB40-configured inputs, the event must be captured even at 1 ms.
- Trigger a second input 200 ms after the first. Confirm the latch still shows the first one; the second is ignored.
- Press the reset, cycle power to the CPU, then re-trigger. With retentive DB bits the value persists. With non-retentive (default for DB100 in STEP 7) it clears. Decide per project: usually make FirstEdgeFound, FirstEdgeByte, FirstEdgeBit, and FirstEdgeTime retentive so a power-cycle during the event does not lose forensic data.
9. Performance and Scan Time Considerations
On a 6ES7314-6CG03-0AB0 (CPU 314C-2 PN/DP) at default OB1 priority, the FB100 loop over 120 bits takes approximately 0.3-0.6 ms in the SCL-compiled form. On a 6ES7312 (CPU 312) the same loop can exceed 2 ms because of the smaller instruction throughput. If the project already runs OB1 near its time-out, switch the loop to a direct byte compare with two WORD operations per PII byte and a FIND_FIRST_LO instruction on the XOR result to locate the first set bit in a single CPU instruction:
// Pure LAD/FBD: 15 byte pairs
A IB 0
L DB100.Prev_PII[0] // from previous cycle
XOR // bits set in XOR = edges
T MW 200 // EDGE_WORD
// Then priority-encode EDGE_WORD to find the lowest set bit
// (LAD: cascade of AN/= instructions, or call FC_PRIORITY_ENCODE)
For a 6ES7317-2EK14-0AB0 (CPU 317-2 PN/DP) the cost is negligible and the FB can be called at OB1 priority class 1 without measurable impact. The hardware interrupt path adds no OB1 cost at all - OB40 only runs when an event occurs.
10. Edge Cases and Field-Proven Caveats
-
First-scan cold start: on the very first OB1 after power-up,
DB100.Prev_PIIcontains zeros. If the process starts with all 120 inputs TRUE, no edge is detected on cycle 1 (1 AND NOT 1 = 0) - this is correct. If the process starts with some inputs FALSE, those will be reported as First-Out on the first cycle. To avoid this, condition the FB with aFirstScanDoneflag that the OB100 (warm restart) sets after the first valid sample, or initializePrev_PIIfrom the PII itself on the first scan. -
Module replacement: OB83 (insert/remove module interrupt) fires if an SM 321 is pulled or re-seated. After the module comes back, the PII is re-read on the next cycle but the previous-image array is stale. Force a re-initialize of
Prev_PIIin OB83, or your First-Out will fire on the first cycle after a module swap. - Wire break on interrupt-capable DI: modules like 6ES7321-7TH00-0AB0 raise a diagnostic interrupt (OB82) on wire break. This is independent of the First-Out latch. Add a wire-break monitor in OB82 and present it on the HMI as a separate alarm - it is the same physical fault viewed from two perspectives.
- Group interrupt (multiple channels at once): if a single field event short-circuits two wires simultaneously, OB40 reports a group event. Iterate over the channel mask in OB40_POINT_ADDR and latch the lowest-numbered bit - the "first" in the sense of lowest address.
- Retentivity: STEP 7 DBs are not retentive by default. In HW Config > CPU > Properties > Retentive Memory, declare the byte range covering FirstEdgeFound, FirstEdgeByte, FirstEdgeBit, and FirstEdgeTime as retentive (a single byte covers the bool; for the DT you need 8 bytes of retentive area).
- Time skew on S7-300: the built-in clock of the CPU is not synchronized. If you have multiple S7-300 stations on one line, install a CP 343-1 (e.g., 6GK7343-1EX30-0XE0) and run the time-of-day synchronization via NTP to a single master so timestamps across stations are comparable.
-
SFC1 vs SFC64: SFC1 READ_CLK returns a wall-clock
DATE_AND_TIMEin BCD; SFC64 TIME_TCK returns a 1 ms system tick as DWORD since last restart. Use SFC1 for human-readable timestamps on the HMI; use SFC64 in OB40 to compute intervals between events down to 1 ms.
11. S7-300 Module and Catalog Reference
| Module | Order number | DI count | Hardware interrupt | Wire-break diagnostic | Used for |
|---|---|---|---|---|---|
| SM 321 DI 16x24 V DC | 6ES7321-1BH02-0AA0 | 16 | No | No | Standard process DI for the bulk of the 120 signals. |
| SM 321 DI 32x24 V DC | 6ES7321-1BL00-0AA0 | 32 | No | No | Density-optimized DI; covers 96 of 120 with three modules. |
| SM 321 DI 16x24 V DC, interrupt | 6ES7321-7BH00-0AB0 | 16 | Yes | No | Inputs that need OB40 with sub-cycle resolution. |
| SM 321 DI 16xNAMUR | 6ES7321-7TH00-0AB0 | 16 | Yes | Yes | Safety-related or wire-break-monitored inputs; full OB40 + OB82 support. |
| CPU 314C-2 PN/DP | 6ES7314-6EH04-0AB0 | 24 onboard DI | Yes (onboard) | No | Compact machine controller; onboard DIs can be used for critical First-Out inputs. |
| CPU 317-2 PN/DP | 6ES7317-2EK14-0AB0 | 0 onboard | n/a | n/a | Larger installations where 120 DI on racks is common. |
12. S7-300 / STEP 7 System Functions Used
| SFC / SFB | Name | Purpose in this design |
|---|---|---|
| SFC 1 | READ_CLK | Read CPU wall-clock time at the moment a First-Out event is captured. |
| SFC 6 | RD_SINFO | Read OB start information in OB82 / OB83 to identify the module that triggered the diagnostic. |
| SFC 13 | DPNRM_DG | Read PROFIBUS DP slave diagnostic on a remote SM 321 behind an IM 153. |
| SFC 52 | WR_USMSG | Write a user diagnostic message into the CPU diagnostic buffer. |
| SFC 64 | TIME_TCK | Read 1 ms system tick - sub-cycle resolution timestamp in OB40. |
| OB 40 | Hardware interrupt | Event-driven capture of falling edges on interrupt-capable DIs. |
| OB 82 | Diagnostic interrupt | Wire break / channel fault on diagnostic-capable SM 321. |
| OB 83 | Insert/remove module | Reset Previous_PII after a hot-swap to avoid spurious First-Out. |
FAQ
How do I find the first falling input on a Siemens S7-300 with 120 digital inputs?
Run a cyclic First-Out latch in OB1 that compares the current process-image input to the previous cycle. On the first detected 1->0 transition, write the bit index (0-119) and the SFC1 wall-clock time into a DB and freeze the latch until an HMI reset. The detection resolution equals the OB1 cycle time, typically 5-50 ms. For sub-millisecond resolution, configure a hardware interrupt on a 6ES7321-7BH00-0AB0 or 6ES7321-7TH00-0AB0 and handle the event in OB40.
Does OB82 help me find the first fallen digital input?
No, not by itself. OB82 only fires on diagnostic events from the module - wire break, channel fault, short circuit, or PROFIBUS slave diagnostic on an ET 200S - not on ordinary 24 V transitions of a normal process input. Use OB82 in parallel to the First-Out latch to record wire-break faults on diagnostic-capable SM 321 modules such as the 6ES7321-7TH00-0AB0.
What resolution do I get with a hardware interrupt on the S7-300?
On modules that support it, OB40 provides a 1 ms timestamp via the SFC64 TIME_TCK system tick or via the OB40_TIMESTAMP field. Two falling edges in the same OB1 cycle are still serialized because OB40 instances do not preempt each other, but they can be ordered to within 1 ms of each other.
How do I make the First-Out record survive a power cycle?
Declare the DB100 memory area that holds FirstEdgeFound, FirstEdgeByte, FirstEdgeBit, and FirstEdgeTime as retentive in HW Config > CPU > Properties > Retentive Memory. The minimum retentive area is one byte for the bool plus eight bytes for the DATE_AND_TIME; round up to 16 bytes for headroom.
Can I see the First-Out event in STEP 7 if the HMI is down?
Yes. Call SFC52 WR_USMSG in OB1 on the rising edge of FirstEdgeFound. The message appears in STEP 7 > PLC > Module Information > Diagnostic Buffer with full timestamp and user-defined INFO1/INFO2 fields that carry the byte and bit index. This gives you a black-box recorder independent of any HMI or SCADA.