Configuring S7-400H ET 200M Module Diagnostics via SFC51
An S7-400H redundant controller paired with ET 200M distributed I/O over PROFIBUS DP delivers high-availability process control, but extracting deterministic module-level diagnostics from the IM 153-2 redundant header requires specific system software partial lists, OB82 interrupt handling, and a structured approach to mapping the data into tags that can be forwarded to a DCS. This reference consolidates the field-proven paths: SFC51 with SSL-ID W#16#0C91 / W#16#0D91, SFC59 for extended module diagnostic records, and the HW Config "Report System Error" (RSE) generator.
1. System Architecture Overview
The relevant topology for this article is a Siemens SIMATIC S7-400H fault-tolerant PLC with two H-CPUs (e.g., CPU 417-4H) communicating over the integrated PROFIBUS DP interface to one or more ET 200M stations. Each ET 200M station uses a redundant pair of IM 153-2 interface modules (6ES7153-2BA10-0XB0 or 6ES7153-2BA70-0XB0 for the high-feature variant) on the active backplane. PROFIBUS DP node 1, node 2, etc. in the HW Config view represents each physical ET 200M head station.
Diagnostic data is generated at three layers:
- Module status: module faulty / OK / channel fault / parameter assignment error / external auxiliary voltage missing.
- Channel status: per-channel short-circuit, wire break, overflow, underflow, and reference channel errors for analog modules.
- PROFIBUS DP slave diagnostics: station failure, redundancy loss, DP slave not reachable, diagnostic buffer overflow at the head module.
For DCS comms, only the first two layers are normally required - i.e. a single WORD/BOOL tag per module that indicates a "module fault" state, and ideally an error code identifying the failure type.
2. Diagnostic Methods Comparison
| Method | Data Granularity | Engineering Effort | Maintenance Overhead | Best Use Case |
|---|---|---|---|---|
| SFC51 SSL_ID W#16#0C91 (Module status info) | Module OK / faulty per slot | Low | Low | Boolean module fault tags for DCS |
| SFC51 SSL_ID W#16#0D91 (Module channel diagnostics) | Per-channel errors | Medium | Medium | Analog channel-level wire break / overflow |
| SFC51 SSL_ID W#16#00B1 / 00B2 / 00B3 / 00B4 (Diagnostic buffer) | Time-stamped events | Medium | Low | Troubleshooting history export |
| Report System Error (RSE) generator | Pre-built DB with all error states | Lowest (automated) | Low | Wide variety of modules, fewer code cycles |
| SFC59 (RD_REC) on PROFINET/PROFIBUS | Raw record set per slot | High | High | Vendor-specific diagnostic records |
| OB82 + SFC59 | Event-driven channel diagnostic | Medium | Medium | Reactive handling of a single fault event |
3. SFC51 SSL-ID W#16#0C91 - Module Status Information
The partial list extract with SSL-ID W#16#0C91 is the canonical answer for "which module is faulty" across an S7-400 rack. The System Software for S7-300/400 System and Standard Functions manual defines the structure of this partial list as follows:
- SZL_ID W#16#0C91, partial list extract:
- S7-400: bits 0 to 14: logical base address of the module. Bit 15: 0 = input, 1 = output.
- S7-300: bits 0 to 14: any logical base address of the module. Bit 15: 0 = input, 1 = output.
- Multiple data records (DR) of 16 bits each; index = slot number of the module (1 to 18 for ET 200M backplanes).
Call parameters for SFC 51 "RDSYSST":
CALL SFC 51
REQ := TRUE // start request
SZL_ID := W#16#0C91 // module status info
INDEX := W#16#0001 // slot 1 .. 18 (rack slot)
RET_VAL := MW100 // return value
BUSY := M101 // processing flag
SZL_HEADER := DW#16#00000000 // optional: W#16#0000 = first/next record
SZL_PTR := P#M 200.0 BYTE 100 // destination area, 100 bytes minimum
The destination area must be at least 4 bytes for the SZL header plus 2 bytes per data record. For 18 slots in an ET 200M, allocate 100 bytes to be safe. SZL_HEADER.WORD[0] returns the length of the data record in bytes, SZL_HEADER.WORD[1] returns the number of records returned.
4. SFC51 SSL-ID W#16#0D91 - Module Channel Diagnostics
When the question is "which channel of an SM 331 analog module has wire break", use SSL-ID W#16#0D91. This partial list provides the channel-level diagnostic data record for the addressed module. The structure of each record is identical to the standardized PROFIBUS DP diagnostic data record 1 - DS1:
- Byte 0: channel error present (bit 0) / module error (bit 1) / external fault (bit 2)
- Byte 1..2: channel number / channel type
- Byte 3..5: error type (e.g., 0x06 short circuit, 0x07 wire break, 0x08 overflow, 0x09 underflow)
This partial list is built up only when a diagnostic interrupt (OB82) has occurred or the module is polled after a fault. It is the right answer when a single DI module in the central rack is suspected of having no diagnostic interrupt support but the question is on an ET 200M station (the IM 153-2 forwards DS1 transparently).
5. OB82 Diagnostic Interrupt Handling
OB82 is the diagnostic-interrupt OB. It is called by the CPU when an I/O module signals "diagnostic event incoming" (event entering) or "diagnostic event outgoing". Local data of OB82 contains the standard header:
OB82_FLT_ID BYTE // 0x39 = incoming, 0x38/+0x39 = outgoing coding
OB82_IO_FLAG BOOL // 0 = input, 1 = output
OB82_MDL_ADDR INT // logical base address of the faulty module
OB82_MDL_DEFECT BOOL // module defective
OB82_1V_CHG_ERR BOOL // 1V change error (rack fault)
OB82_INT_FAULT BOOL // internal module fault
OB82_EXT_FAULT BOOL // external fault
OB82_PNT_INFO BOOL // channel fault present
OB82_EXT_VOLTAGE BOOL // external auxiliary voltage missing
OB82_FLD_CONNCTR BOOL // front connector not plugged in
OB82_WTCH_DOG_F BOOL // watchdog timeout
OB82_CHAN_FAULT BOOL // channel fault present (per-channel diagnosis available)
OB82_MDL_TYPE BYTE // module type identifier
OB82_RACK_NUM WORD // DP station number / rack number
Inside OB82, call SFC59 "RD_REC" to read the diagnostic record set directly from the module, or call SFC51 to query the current status. The combination of OB82 + SFC59 is the lowest-latency path for DCS notification because the OB is only triggered on actual fault events:
// In OB82 (STL):
L #OB82_MDL_ADDR // load logical base address of faulty module
T MW 300 // store for DB tagging
L #OB82_MDL_DEFECT
T MB 302
L #OB82_CHAN_FAULT
T MB 303
// Trigger SFC59 read of DS0/DS1 for full detail
CALL SFC 59
REQ := TRUE
IOID := B#16#54 // 0x54 = input header ID, 0x55 = output
LADDR := W#16#0080 // example: 0x80 = I/O start addr 128
RECNUM := B#16#00 // DS0
RET_VAL := MW 310
BUSY := M 311
RECORD := P#M 320.0 BYTE 16
6. SFC59 (RD_REC) - Raw Module Record Access
SFC 59 "RD_REC" reads a data record from the addressed module. For ET 200M modules, the most useful records are:
| Record # | Content | Length | Module Type |
|---|---|---|---|
| 0 (DS0) | Standard diagnostic - 6 bytes header + module-specific | Up to 244 | All digital/analog |
| 1 (DS1) | Channel-related diagnostic (per-channel errors) | Up to 244 | Modules with channel diagnostics |
| 128 (DS128) | Module parameters (read back) | Variable | All |
| 131 (DS131) | DI/DO specific - per-channel value status | Variable | SM 32x, SM 42x |
| 140 (DS140) | AI/AO diagnostic - last error per channel | Variable | SM 331, SM 332, SM 334 |
SFC59 is heavier than SFC51 SSL pulls and should be reserved for OB82-triggered reads or for ad-hoc diagnostics from the diagnostic buffer. SFC51 reads from a CPU-internal mirror that the OS updates automatically.
7. Report System Error (RSE) Generator
For projects where the goal is a single DB containing all module fault states with their symbolic names, enable the Report System Error function in HW Config:
- Open HW Config, select the S7-400H station.
- Menu Options > Report System Error.
- Configure: enable "Support of PROFINET devices" or "PROFIBUS DP" as required; choose S7-300/S7-400 OB82 support, S7-300/S7-400 OB83 support (plug), OB84 (rack), OB85, OB86 (slave failure), OB122.
- Assign a "User block" call (FB/DB pair) in the "User block" tab. RSE will then call the assigned FB on every diagnostic event with the standard error information record.
- Assign descriptive names to every module in the HW Config (right-click module > Properties > Name). These become the symbolic names in the generated DB.
- Click "Generate". The generator creates a DB containing one BOOL tag per error state and per module plus an error-number WORD.
The error-number WORD can be exported in CSV from the "General" tab and used to map each integer to a textual description for the DCS. The error number list in the dialog shows the complete enumeration - use it to build the lookup table on the DCS side. The generated DB is named per your settings, e.g., DB_RSE_ERROR, and is regenerated on each "Generate" run.
8. Mapping to DCS Tags
Once you have a single source of truth - either a hand-coded DB built from SFC51 calls, or the RSE-generated DB - copy the required bits into the DB segment you use for the S7-400H-to-DCS interface (e.g., a designated DB written by the user program and read by the comms FB, such as BSEND/BRCV via ISO-on-TCP, or via a PROFIBUS DP slave interface to the DCS). The minimal structure is:
DATA_BLOCK DB_DCS_DIAG
STRUCT
ModuleFault : ARRAY[1..18] OF BOOL; // one bit per slot, ET 200M
ChannelFault : ARRAY[1..18] OF BOOL; // bit per slot, has channel diag
AuxVoltMissing : ARRAY[1..18] OF BOOL;
ErrorCode : ARRAY[1..18] OF WORD; // 0 = OK, otherwise SZL code
ScanTimestamp : DWORD; // last successful SFC51 poll
END_STRUCT
END_DATA_BLOCK
Update this DB from a cyclic OB1 segment that calls SFC51 once per slot per scan, or call it from OB82 on demand. OB1-only polling is simpler; OB82-only is more responsive; a hybrid approach (OB1 background poll every 500 ms, OB82 event-driven update) is field-proven for S7-400H plants.
9. Step-by-Step Implementation (Recommended Path)
- Open the S7-400H station in HW Config, navigate to each IM 153-2 head, confirm both modules are configured with identical slot order. Open object properties of the DP slave and check the "Diagnostic" checkbox is enabled.
- Open the report system error dialog (Options > Report System Error). Configure OBs 82, 83, 84, 85, 86, 122. Set the "Diagnosis bits and error types" to "All fault categories" if you want full coverage. Assign module names.
- Generate the RSE blocks. The generator outputs one FB, one FC, and one (or more) DBs containing the status data.
- Insert the generated FB into OB1. The FB pre-wires the diagnostic calls and writes the status DB automatically.
- Create
DB_DCS_DIAGin your project. Add a copy block in OB1 that mirrors the relevant RSE tags intoDB_DCS_DIAGfor downstream comms. - Export the RSE error list to CSV. Build the same lookup table on the DCS side (e.g., OPC tag of type STRING indexed by the error code).
- If more granular per-channel data is required, add a user-defined OB82 implementation that calls SFC59 to read DS1 for the specific module from
OB82_MDL_ADDR, parse the result, and updateDB_DCS_DIAG.ErrorCode. - Download HW Config + software to both H-CPUs of the S7-400H. Run RUN-REDU on the standby CPU so the redundant partner has matching diagnostics.
10. Verification Procedure
- Monitor
DB_DCS_DIAG.ModuleFault[i]in online view. All bits should be FALSE on a healthy plant. - Pull a single DI module from slot 4 of the ET 200M head. Confirm OB82 fires, the bit goes TRUE, and the timestamp updates.
- Re-insert the module. Confirm the bit returns to FALSE within one SFC51 cycle (typically < 200 ms) and the diagnostic buffer contains the "module OK" entry.
- For an analog module, disconnect a 4-wire current loop. Confirm ChannelFault and ErrorCode match the expected wire-break code per DS1 byte 5 (typically 0x07 for SM 331 AI8x12-bit).
- Perform a redundancy switchover (H-CPU failover). Verify that the standby CPU assumes ownership and the diagnostic state is preserved - SFC51 partial lists are CPU-internal, so the new active CPU must rebuild them on next OB1 scan. The RSE DB is in load memory and replicated; verify its content remains consistent.
- Validate that the DCS receives the data with the expected update rate. Use the timestamp WORD to detect dropped updates.
11. Troubleshooting Matrix
| Symptom | Likely Root Cause | Corrective Action |
|---|---|---|
| SFC51 RET_VAL = W#16#8085 (power flow error, type fault) | SSL_ID not supported on this CPU firmware | Upgrade CPU firmware to a version that supports W#16#0C91; or use SFC59 directly |
| SFC51 RET_VAL = W#16#8090 (no data record) | INDEX (slot) is empty or module does not exist | Check the module layout in HW Config against the actual slots; verify logical address vs. slot mapping |
| SZL_HEADER = 0 after call | Module is a passive backplane slot, or DP slave is not in data exchange | Check DP diagnostic; verify IM 153-2 in RUN; check bus terminator and PROFIBUS address |
| OB82 does not fire on a real fault | Module diagnostic is disabled in module properties | Open module properties, enable "Group diagnostics" and "Diagnostic interrupt" |
| OB82 fires but OB82_MDL_ADDR is 0 | Fault originates from the CPU backplane, not ET 200M | Use SFC51 with W#16#00B2 to read the diagnostic buffer and identify the source |
| RSE-generated DB shows wrong slot numbers | RSE was generated against a stale HW Config | Re-run Options > Report System Error > Generate after any module change |
| Diagnostic data lost on H-CPU failover | User program reads SFC51 only on the active CPU; new active has no cached data | Force OB1 to re-poll all slots on standby-standby-to-active transition; or use RSE DB which is replicated |
| SFC59 RET_VAL = W#16#80A2 / 0x80A3 | Record number not supported by module / record too short | Use RECORD length >= 244; check the manual for that module's supported records |
| ChannelFault bit set but ErrorCode = 0 | Module reported group fault only (no DS1) | Check the module catalog number; non-diagnostic modules do not publish DS1 |
12. Notes on S7-400H-Specific Behavior
S7-400H runs an event-synchronized redundant OS, so SFC51 internal state is mirrored to the standby CPU in a consistent manner. However, partial list snapshots are constructed on the active CPU at runtime. After a switchover (link-down between H-CPUs, master CPU stop, etc.), the new active CPU rebuilds the partial list on the next OB1 cycle. Plan a single warm-up scan of all slots on OB100 startup to populate the DB before downstream comms are enabled.
For an ET 200M head with redundant IM 153-2 modules, both headers are polled independently. The DP slave ID is the same; the active header is the one that holds the PROFIBUS token. SFC51 cannot tell you which physical header is active; that requires OB83 (plug) and OB70 (redundancy loss) handling plus the IM 153-2-specific status byte in the slave diagnostic. Add OB70 and OB72 in HW Config to capture redundancy-related events on the H station side.
13. Cross-References and Standards
- IM 153-2 / ET 200M Operating Instructions (PDF) - channel-related diagnosis, H status, diagnostic records.
- System Software for S7-300/400 System and Standard Functions - SFC51 partial list catalog and SZL_ID definitions.
- PROFIBUS Profile for Process Automation (PA) and PROFIBUS DP standard EN 50170 / IEC 61158 - DS0/DS1 record format.
14. FAQ
Which SSL-ID gives module OK / faulty status for an ET 200M on an S7-400H?
Use SFC 51 with SZL_ID W#16#0C91 and index the slot number (1 to 18). Each data record returned in the SZL_PTR area contains a 16-bit word per slot where bit 0 = module faulty, bit 1 = channel fault, bit 2 = parameter assignment error, and so on, per the System Software manual.
Can I get channel-level diagnostic data for a DI module in an ET 200M station?
Yes, but only if the DI module supports diagnostic interrupts (e.g., 6ES7321-7BH01-0AB0). For non-diagnostic modules, only group diagnostics are reported, accessed via SSL W#16#0C91. For per-channel data, use SSL W#16#0D91 or call SFC59 to read DS1 from the affected module inside OB82.
How is Report System Error (RSE) different from SFC51 polling?
RSE auto-generates an FB and DB that continuously monitor all configured modules and write a structured status DB. SFC51 polling requires the user to call SFC51 manually for each slot, parse the SZL_HEADER, and write to a custom DB. RSE is faster to deploy; SFC51 is leaner and gives you more control over update rate and CPU load.
Does the S7-400H lose diagnostics on a CPU failover?
SFC51 partial lists are rebuilt on the newly active CPU, so there can be one OB1 scan with stale data. Use OB100 to pre-fill the diagnostic DB, or rely on the RSE-generated DB which is replicated in load memory and is consistent across the H pair immediately after switchover.
What SFC reads the diagnostic buffer of the S7-400H CPU?
Use SFC 51 with SZL_ID W#16#00B2 (single entry) or W#16#00B3 / W#16#00B4 (last N entries) to read the diagnostic buffer in a chronological order. The buffer is a ring of 49 entries on most S7-400 CPUs. For 7-400H, the entries from both H-CPUs can be merged using a combination of SZL_ID W#16#00B1 (own CPU) and W#16#00B1 with appropriate rack index for the partner.
How do I forward module faults to a DCS via comms?
Build a dedicated DB (e.g., DB_DCS_DIAG) that contains one BOOL per slot plus an error code WORD. The comms FB (BSEND/BRCV over ISO-on-TCP, or a PROFIBUS DP slave interface to the DCS) reads from this DB. Mirror the data from the RSE-generated DB or from your SFC51 caller into DB_DCS_DIAG every OB1 cycle.