S7-1200 OB82 PROFINET Diagnostics: Detecting Cable and IO Faults

David Krause17 min read
S7-1200SiemensTroubleshooting
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

S7-1200 OB82 PROFINET Diagnostics: Detecting Cable and IO Device Faults

Diagnostic interrupt OB82 is the standard mechanism for a SIMATIC S7-1200 to react to PROFINET IO device faults: a yanked cable, a failed station, a removed module, or a channel-level diagnostic event. The OB82 handler is also one of the most common sources of confusion for engineers who are trying to detect a HMI disconnect on a SIMATIC panel such as the KTP400 Basic PN. The panel is not a PROFINET IO device in the sense OB82 understands, so OB82 will not fire when the HMI cable is broken, and the diagnostic DB will appear to do "strange things" because no event source matches the slot the HMI occupies.

This reference explains what OB82 actually monitors on a CPU 1215C DC/DC/DC, why it does not detect a KTP400 HMI disconnect, how to wire the correct OB82 handler in TIA Portal V12 (or later), how to interpret the start information, and what to use instead of OB82 to track the HMI online state with area pointers and a coordination life bit.

Hardware/firmware precondition: OB82 (and OB86) are supported on the S7-1200 starting from firmware V4.0. CPUs shipped before V4.0 will silently ignore diagnostic events and your handler block will never be called. Verify with Online & Diagnostics → Diagnostics → CPU Information or by reading the order number (6ES7 215-1AG40-0XB0 and later).

1. Problem Summary

Symptom reported in the field:

  • Topology: CPU 1215C DC/DC/DC (PROFINET port X1, FW ≥ V4.0) connected directly to a KTP400 Basic PN over PROFINET copper.
  • User goal: detect a physical cable break, wire damage, or panel power-down and display an alarm in the HMI; also drive the PLC error LED.
  • Implementation: OB82 created in TIA Portal, diagnostic data mirrored into a global DB, no alarms raised in the HMI, values in the DB look nonsensical.
  • Root cause: OB82 is the wrong OB for an HMI station. The KTP400 Basic PN is configured as an HMI panel, not as a PROFINET IO device, so it does not generate channel diagnostics, and it does not appear in the slot table that OB82 walks.

OB82 in the S7-1200 world covers three real cases:

  1. A PROFINET IO device (e.g., ET 200SP, SINAMICS, third-party IO) reports a diagnostic alarm.
  2. A module on a PROFINET IO device is inserted or removed (also OB83 is involved).
  3. The CPU itself detects loss of an IO device or IO submodule (also handled through OB86 for station failure).

It does not cover a SIMATIC HMI panel losing its HMI/PLC connection, because the HMI connection is a TSAP-based S7 channel, not a PROFINET IO relationship.

2. Why OB82 Cannot See the KTP400

The KTP400 Basic PN is added to the project under HMI devices, not under Distributed IO. In the device configuration you can still see the panel in the network view and assign it to the same PROFINET subnet as the CPU, but the relationship is:

Element PROFINET IO device HMI panel (KTP400 Basic PN)
Configured as IO device, slot-mapped HMI station with HMI/PLC connection
Generates channel diagnostics Yes, per channel No
Fires OB82 on event Yes No
Fires OB86 on loss Yes No
Monitored via OB82, OB86, RDREC, device status Coordination area pointer, life bit, HMI system events

When you read "strange" values in your diagnostic DB, the typical causes are:

  • The HMI does not transmit a diagnostic record, so OB82 never enters with a real event. Any preset values in your DB are stale defaults from the last program download.
  • You are reading slots that are not assigned. Unassigned slots on a real PROFINET IO device return the configured default, which looks like a fault to the user.
  • The CPU is logging the event in the diagnostic buffer, but the buffer entries show "PROFINET IO: Station failure" or "PROFINET IO: Diagnostics" for the panel only if you mis-configured the KTP400 as an IO device (do not do this — it removes the HMI runtime).

3. OB82 Technical Background

OB82 is the diagnostic interrupt organization block. It is called by the operating system of the CPU when a PROFINET/PROFIBUS DP slave or an IO module reports a diagnostic event, and again when the event goes away. See the Siemens reference page Diagnostic interrupt OB (OB 82) — S7-300, S7-400 for the canonical definition. The S7-1200 implements the same start information with the same names, plus a small set of S7-1200-specific extensions.

3.1 OB82 Start Information (Temp Variables)

Local variable Type Description
OB82_EV_CLASS BYTE Event class: 16#39 = incoming, 16#38 = outgoing
OB82_FLT_ID BYTE Fault ID: 16#06 = diagnostic interrupt, 16#07 = module removed, 16#0B = channel fault
OB82_IO_FLAG BYTE 0 = input module, 1 = output module
OB82_MDL_ADDR INT Logical base address of the module that raised the alarm
OB82_RACK_NUMBER WORD Rack / station number
OB82_MODULE_TYPE WORD Module type identifier from the device GSD
OB82_CHANNEL DWORD Channel number with channel direction bit
OB82_WS_RACK_NO WORD Subslot / slot number
OB82_INT_STAT WORD Interrupt status (bit 0 set = incoming)
OB82_IO_DIAG DWORD IO diagnostic flag field (bit 0 = module good, bit 1 = invalid, bit 3 = channel fault, bit 5 = external fault, bit 7 = parametrization fault)
OB82_DATE_TIME DATE_AND_TIME Timestamp of the event (CPU local time)

3.2 Behaviour on an S7-1200

  • If OB82 is not loaded in the CPU, the operating system handles the diagnostic event internally and writes it to the diagnostic buffer. The CPU goes to STOP only if the IO device is configured as a required (not optional) partner and the failure is unrecoverable.
  • If OB82 is loaded, the user program is responsible for acknowledging the event; the operating system will not call OB82 again for the same event until the cause is cleared and a new diagnostic is raised.
  • For each diagnostic event the operating system calls OB82 once coming in and once going out, distinguished by OB82_EV_CLASS and the bit pattern in OB82_INT_STAT.
Time budget: OB82 must complete within the cycle of the OB priority it inherits (priority 26 in S7-1200). Keep the handler short: copy the start info into a global DB, set a flag, and exit. Long operations belong in OB1 or in a cyclic task.

4. Prerequisites

  1. CPU 1215C DC/DC/DC with firmware V4.0 or later. Read firmware with Online → Accessible Devices in TIA Portal.
  2. TIA Portal V12 SP1 or later (the user is on V12; V12 SP1 is recommended for full PROFINET diagnostics support).
  3. At least one real PROFINET IO device assigned to the CPU so OB82 has a source of diagnostic events. The KTP400 alone will not generate OB82 events.
  4. The IO device must have Diagnostics enabled in its device configuration (Device view → Properties → Diagnostics). Most ET 200 stations have this enabled by default; some compact IO blocks need it enabled per channel.
  5. Optional: a KTP400 Basic PN for the HMI side, configured as an HMI station with an HMI/PLC connection and an enabled Coordination area pointer.

5. Configuring OB82 in TIA Portal

  1. Open the S7-1200 project and expand Program blocks in the project tree.
  2. Double-click Add new block and choose Organization block → Diagnostic interrupt. TIA inserts OB82 with default name "Diagnostic_interrupt".
  3. Open the new OB, right-click the interface header, and confirm that the start info table is visible (View → Show/Hide → Interface). All variables above must be present.
  4. Add a global DB called DB_Diag with the structure shown in section 6.
  5. Write the handler code (SCL example in section 6.1) and compile. TIA will warn if the S7-1200 firmware does not support OB82 — upgrade firmware first.
  6. Download the project to the CPU. Confirm the block list contains OB82.

6. OB82 Handler: DB and SCL

6.1 Diagnostic data block

Create DB_Diag with the following UDT-derived structure so that OB82 can copy data without allocating temporary DBs in the cyclic program:

Name Type Initial value Comment
EventClass BYTE 16#00 16#38 outgoing / 16#39 incoming
FaultId BYTE 16#00 OB82_FLT_ID
IoFlag BYTE 0 0 = input, 1 = output
ModuleAddr INT 0 Logical base address
RackNumber WORD 16#0000 Rack / station
Channel DWORD 16#0000_0000 Channel number
IoDiag DWORD 16#0000_0000 Bit-mapped diagnostic flags
EventTimestamp DATE_AND_TIME DT#1990-01-01-00:00:00 Event time stamp
IncomingFlag BOOL FALSE Sticky incoming flag for OB1 to read
OutgoingFlag BOOL FALSE Sticky outgoing flag for OB1 to read
CableLost BOOL FALSE TRUE while a module is in diagnostic state

6.2 SCL body of OB82

// Diagnostic interrupt OB — copy start info into DB_Diag and latch flags
// Target CPU: S7-1200 FW V4.0+ in TIA Portal V12 SP1+

// 1) Capture raw event
"DB_Diag".EventClass    := #OB82_EV_CLASS;
"DB_Diag".FaultId       := #OB82_FLT_ID;
"DB_Diag".IoFlag        := #OB82_IO_FLAG;
"DB_Diag".ModuleAddr    := #OB82_MDL_ADDR;
"DB_Diag".RackNumber    := #OB82_RACK_NUMBER;
"DB_Diag".Channel       := #OB82_CHANNEL;
"DB_Diag".IoDiag        := #OB82_IO_DIAG;
"DB_Diag".EventTimestamp := #OB82_DATE_TIME;

// 2) Classify event direction. Bit 0 of OB82_INT_STAT is set on incoming events.
IF (#OB82_EV_CLASS = 16#39) OR ((#OB82_INT_STAT AND 16#0001) <> 0) THEN
    "DB_Diag".IncomingFlag := TRUE;
    "DB_Diag".OutgoingFlag := FALSE;
ELSE
    "DB_Diag".IncomingFlag := FALSE;
    "DB_Diag".OutgoingFlag := TRUE;
END_IF;

// 3) Latch cable-lost flag while ANY module is in diagnostic state.
//    Bit 1 of OB82_IO_DIAG = "module invalid"; bit 3 = channel fault.
IF (#OB82_IO_DIAG AND 16#0000_000A) <> 0 THEN
    "DB_Diag".CableLost := TRUE;
ELSE
    "DB_Diag".CableLost := FALSE;
END_IF;

Add the Standard block to the OB82 priority level if you have multiple S7-1200 CPUs and need to interlock the handler. Most projects leave OB82 at default priority.

6.3 OB86 handler (companion to OB82)

OB82 fires per diagnostic; OB86 fires when a complete station (PROFINET IO device) disappears. For a cable break both fire — OB86 first, then OB82 for each affected slot. The S7-1200 supports OB86 from FW V4.0 onward. SCL body:

// Rack/station failure OB — latch a "station gone" flag for the HMI
IF #OB86_FLT_ID = 16#13 THEN            // station failure
    "DB_Diag".StationFailed := TRUE;
    "DB_Diag".FailedStation := #OB86_MDL_ADDR;
    "DB_Diag".FailedIoFlag  := #OB86_IO_FLAG;
ELSIF #OB86_FLT_ID = 16#14 THEN         // station return
    "DB_Diag".StationFailed := FALSE;
END_IF;

7. Detecting a PROFINET Cable Disconnect

Pulling the patch cable from the CPU or the IO device on a healthy PROFINET network produces a predictable sequence of events:

  1. The link LED at the affected port goes off (link-down is the first physical signal).
  2. After a configurable link-down timeout (default 200 ms on the CPU), the device reports a station failure. OB86 enters with FLT_ID = 16#13.
  3. The CPU's BF (bus fault) LED turns on solid red; MAINT may blink yellow.
  4. If the IO device was an active diagnostics source, OB82 enters with FLT_ID = 16#06 or 16#07 and IO_DIAG with the module-invalid bits set.
  5. The diagnostic buffer records "PROFINET IO: Station failure" followed by per-module diagnostic entries.

Use the diagnostic buffer to confirm that OB82 was actually called. In TIA Portal: Online & Diagnostics → Diagnostics → Diagnostic buffer. The most recent entry should show the source PROFINET interface and the affected station number.

7.1 LED mapping

LED State on PROFINET station loss
LINK (port LED, green) Off immediately on link-down
RX/TX (port LED, yellow) Off when no traffic
BF (bus fault, red) Solid on after link-down timeout
MAINT (yellow) Blinks if a maintenance-required diagnostic was reported
ERROR (red) On only if a configured required IO device fails to come back

To drive an additional external LED or a HMI alarm from the PLC logic, latch DB_Diag.StationFailed and DB_Diag.CableLost and tie them to a HMI tag.

8. HMI Connection Monitoring (Replaces OB82 for the KTP400)

For the KTP400 Basic PN, use one of three techniques. They do not depend on OB82.

8.1 Coordination area pointer with life bit

This is the standard Siemens recipe and is the one to use for "is the HMI online?" alarms.

  1. In the project tree, double-click the KTP400 to open device configuration.
  2. Select Connections → HMI_Connection_1 and open Properties → Area pointers.
  3. Enable Coordination. The default DB starts at DB 1, byte 0; rename or move to fit your project. A typical setup uses DB_HMI_Coord with one byte at offset 0.
  4. On the PLC side, the Coordination area is a single byte that the HMI writes and the PLC reads. The HMI toggles bit 0 every second (the life bit). Other bits indicate the acquisition state.
  5. In OB1 or a cyclic interrupt, detect the life bit transition and call it "HMI online". When the life bit stops toggling for more than ~3 seconds, the HMI is offline or the cable is broken.
// HMI online check — run in OB1, 100 ms cyclic
// "DB_HMI_Coord".CoordByte is the Coordination area pointer byte
// Set DB_HMI_Coord in TIA Portal: HMI Connections → Area pointers → Coordination

IF "DB_HMI_Coord".CoordByte.%X0 = TRUE THEN
    IF "DB_HMI_Coord".LastLifeBit = FALSE THEN
        "DB_HMI_Coord".LifeBeatCount := "DB_HMI_Coord".LifeBeatCount + 1;
    END_IF;
    "DB_HMI_Coord".HmiOnline := TRUE;
ELSE
    IF "DB_HMI_Coord".LastLifeBit = TRUE THEN
        "DB_HMI_Coord".HmiOfflineEvent := TRUE; // sticky event for the alarm log
    END_IF;
    "DB_HMI_Coord".HmiOnline := FALSE;
END_IF;
"DB_HMI_Coord".LastLifeBit := "DB_HMI_Coord".CoordByte.%X0;

// Timeout detector: if no transition for > 3 s, declare HMI offline
IF ("DB_HMI_Coord".HeartbeatTimer < SHRT_MAX) THEN
    "DB_HMI_Coord".HeartbeatTimer := "DB_HMI_Coord".HeartbeatTimer + 1;
END_IF;
IF "DB_HMI_Coord".HeartbeatTimer > 30 THEN  // 30 * 100 ms = 3 s
    "DB_HMI_Coord".HmiOnline := FALSE;
END_IF;
IF "DB_HMI_Coord".CoordByte.%X0 = TRUE THEN
    "DB_HMI_Coord".HeartbeatTimer := 0;
END_IF;

8.2 Project ID area pointer

The Project ID is a fixed 16-bit identifier. If the HMI is in the wrong project, the values will not match. Use it as a sanity check, not a connection monitor.

8.3 Tag-based polling

Define a boolean tag HMI_Heartbeat in the PLC, increment it every cycle, mirror it on the HMI, and read it back through another tag. If the read value stops tracking the write value within the HMI update cycle (default 1 s), the connection is broken. This is the most reliable method when the Coordination area pointer is unavailable, but it consumes a tag and a tag update window.

9. Combining PROFINET IO Diagnostics and HMI Status

For a complete alarm picture on the S7-1200, combine OB82/OB86 (PROFINET IO) with the Coordination life bit (HMI). A small status word can be assembled in the cyclic program:

// Master alarm word — assemble a 16-bit status for the HMI alarm view
// Bit 0 = PROFINET station lost, Bit 1 = PROFINET module diagnostic active
// Bit 2 = HMI cable broken (Coordination timeout), Bit 3 = CPU in STOP
// Bit 4 = OB82 executed at least once, Bit 5 = OB86 executed at least once

"DB_Alarm".StatusWord.%X0 := "DB_Diag".StationFailed;
"DB_Alarm".StatusWord.%X1 := "DB_Diag".CableLost;
"DB_Alarm".StatusWord.%X2 := NOT "DB_HMI_Coord".HmiOnline;
"DB_Alarm".StatusWord.%X3 := (WORD_TO_INT("DB_Alarm".StatusWord) AND 0) = 0 AND (NOT "DB_Diag".CpuRun);  // example
"DB_Alarm".StatusWord.%X4 := "DB_Diag".Ob82Fired;
"DB_Alarm".StatusWord.%X5 := "DB_Diag".Ob86Fired;

Expose DB_Alarm.StatusWord as an HMI tag and use a multi-state indicator to show the operator the current alarm state.

10. Verification Procedure

  1. With the project compiled and downloaded, go online with the CPU.
  2. Open Online & Diagnostics → Diagnostics → Diagnostic buffer. Confirm it shows clean PROFINET state.
  3. In the project tree, open Watch table_OB82 with the DB_Diag tags CableLost, StationFailed, EventClass, FaultId.
  4. Physically unplug the PROFINET cable on the CPU side of an active IO device.
  5. Within ~3 seconds the diagnostic buffer must show a station-failure entry, the BF LED on the CPU must light, and DB_Diag.StationFailed must go TRUE.
  6. Replug the cable. Confirm that StationFailed returns to FALSE and that the diagnostic buffer records a station-return event.
  7. For the KTP400: open the HMI runtime, navigate to the screen that shows the alarm word, unplug the HMI patch cable, and confirm the life-bit timeout drives DB_HMI_Coord.HmiOnline to FALSE within ~3 seconds.

11. Troubleshooting Matrix

Symptom Likely cause Fix
OB82 never fires CPU firmware < V4.0 Update CPU firmware; OB82 needs V4.0+
OB82 never fires No PROFINET IO device assigned (HMI is the only partner) Add a real IO device or use a second CPU on PROFINET for IO tests
OB82 never fires Diagnostics disabled in IO device configuration Device view → Properties → Diagnostics → enable per channel
DB_Diag values look wrong Reading uninitialized DB after download First OB1 cycle initializes DB; or set initial values in DB editor
DB_Diag values look wrong Reading wrong DB number after renumbering Confirm the symbolic name in the project tree
BF LED off but OB82 fires Channel-level diagnostic, not link loss Read OB82_IO_DIAG bit 3 (channel fault)
HMI offline not detected Coordination area pointer not enabled HMI device config → Connections → Area pointers → Coordination → Enable
HMI offline detected too late Life-bit check only on edge, not timeout Add a watchdog timer (section 8.1)
CPU goes to STOP on cable pull IO device configured as required (not optional) Device properties → Operation mode → "Optional" if the process tolerates the loss
OB82 enters with FLT_ID = 16#07 Module removed/inserted Use OB83 alongside OB82 for hot-swap IO

12. Edge Cases and Field-Proven Caveats

  • Multiple IO devices on one subnet: OB82 fires per affected device. The OB82_MDL_ADDR discriminates them; store the full event in a ring buffer (e.g., 16 entries) so you do not overwrite older alarms.
  • CPU 1200 firmware V4.0 to V4.2 limitation: a small number of diagnostic event codes from GSD V2.3 devices are not fully decoded; the OB82_IO_DIAG bits are still set, but extended channel diagnostics (bytes 4–n of the record) are not surfaced in start info. Use RDREC (SFB52) with index 16#8000 if you need the full record.
  • Time zone and timestamp: the timestamp in OB82_DATE_TIME is the CPU's local time and is not adjusted for DST. If you are logging alarms in UTC, shift by the current UTC offset before writing to the alarm DB.
  • Priority inversion: if OB1 spends more than the OB82 watch time (priority 26) inside a single call, OB82 will queue. The default OB1 cycle of an S7-1215C is typically 5–10 ms and is shorter than the OB82 queue limit, so this is rare but possible in projects with very large cyclic programs.
  • HMI redundancy: if you operate two KTP400 panels on the same PLC, the Coordination area pointer exists per HMI connection. Configure one Coordination byte per panel, and use two separate DBs (or one DB with two bytes) to monitor each independently.
  • Watchdog re-trigger: a flapping cable can cause OB82 to oscillate. Debounce in OB1 by requiring the flag to stay TRUE for at least 500 ms before generating the operator alarm.
  • Same CPU used as IO controller and as an IO device: the S7-1200 cannot be configured as a PROFINET IO device; if you need that, switch to an S7-1500 or use an ET 200SP CPU. This avoids the temptation to misuse OB82 across CPU pairs.

13. Migrating from TIA Portal V12 to V16/V17/V18

The same OB82, OB86, and Coordination area pointer logic applies to newer TIA Portal versions. Differences worth noting:

  • From TIA V14, the project tree shows an explicit Diagnostics tab in the device view; this is where you enable per-channel diagnostics that feed OB82.
  • From TIA V15.1, the S7-1200 firmware is V4.4, which exposes the new GET_DIAG instruction (S7-1500 style). GET_DIAG is not available on S7-1200; continue with OB82/OB86 and RDREC if you need more detail.
  • From TIA V16, the KTP400 Basic PN is superseded by the KTP400 Basic 2nd Generation (6AV2 123-2DB03-0AX0). Both use the same area-pointer model, so the code above works unchanged.
  • From TIA V18, the S7-1200 firmware is V4.6, which extends diagnostic coverage. You can keep the same handler code; only the firmware must be updated.

14. Frequently Asked Questions

Does OB82 on the S7-1200 fire when the PROFINET cable to a KTP400 is unplugged?

No. The KTP400 Basic PN is an HMI station, not a PROFINET IO device, and it does not generate channel diagnostics. Use the Coordination area pointer with a life bit and a watchdog timer (default 3 s) to detect HMI cable loss. See section 8.1 for the SCL implementation.

What firmware version do I need for OB82 on the CPU 1215C?

OB82 (and OB86) are supported from firmware V4.0 onward. The order number 6ES7 215-1AG40-0XB0 and later carry V4.x. Confirm the version under Online & Diagnostics → Diagnostics → CPU Information in TIA Portal.

Why does my diagnostic DB show "strange" values after the OB82 handler runs?

Typical causes: the HMI is not an IO device and never produces an event; the slot is not assigned so the handler reads uninitialized memory; the DB was renumbered but the symbolic reference still points to the old DB. Initialize the DB on first scan, confirm the DB number, and read only the variables that the OB82 start info actually populates.

Which OB do I use to detect a complete PROFINET station disappearing?

OB86 fires on station failure and station return with FLT_ID 16#13 (failure) and 16#14 (return). Use it together with OB82 so that you get a station-level event and per-module channel events. Both are required for a complete alarm picture.

Can I make the CPU go to STOP on a cable break?

Yes — if the affected PROFINET IO device is configured as "required" (the default) and the CPU cannot recover, it will go to STOP. In most operator interfaces this is undesirable; set the IO device to "optional" in the device properties, and let OB82/OB86 plus your HMI alarm display do the notification work without halting the line.

Back to blog