Configuring S7-400H ET 200M Module Diagnostics via SFC51

David Krause14 min read
S7-400SiemensTechnical Reference
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

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:

  1. Module status: module faulty / OK / channel fault / parameter assignment error / external auxiliary voltage missing.
  2. Channel status: per-channel short-circuit, wire break, overflow, underflow, and reference channel errors for analog modules.
  3. 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:

  1. Open HW Config, select the S7-400H station.
  2. Menu Options > Report System Error.
  3. 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.
  4. 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.
  5. Assign descriptive names to every module in the HW Config (right-click module > Properties > Name). These become the symbolic names in the generated DB.
  6. 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)

  1. 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.
  2. 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.
  3. Generate the RSE blocks. The generator outputs one FB, one FC, and one (or more) DBs containing the status data.
  4. Insert the generated FB into OB1. The FB pre-wires the diagnostic calls and writes the status DB automatically.
  5. Create DB_DCS_DIAG in your project. Add a copy block in OB1 that mirrors the relevant RSE tags into DB_DCS_DIAG for downstream comms.
  6. 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).
  7. 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 update DB_DCS_DIAG.ErrorCode.
  8. 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

  1. Monitor DB_DCS_DIAG.ModuleFault[i] in online view. All bits should be FALSE on a healthy plant.
  2. Pull a single DI module from slot 4 of the ET 200M head. Confirm OB82 fires, the bit goes TRUE, and the timestamp updates.
  3. 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.
  4. 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).
  5. 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.
  6. 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.

Safety notice: Always test diagnostic changes on a non-production H station first. New OB82 / OB86 code paths can mask existing fault handling. Confirm with the plant's Functional Safety team before activating any OB changes on a SIL-rated loop.

13. Cross-References and Standards

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.

Back to blog