TIA Portal: Reading Single Device State Without DeviceStates

David Krause18 min read
SiemensTechnical ReferenceTIA Portal
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

Overview: The Per-Device Diagnostic Problem

On a SIMATIC S7-1500 controller running TIA Portal, the standard pattern for monitoring fieldbus health is to call the DeviceStates instruction. The instruction is convenient because it returns a packed array describing the operational state of every device configured in the IO system. For a small machine with two or three PROFINET devices this is fine. For a complex station with dozens of IO devices, distributed I/O on PROFINET IO controllers, and a soft-starter driver that only cares about one specific device, calling DeviceStates every cycle is wasteful: the function block reads and parses the complete diagnostic picture, the user code has to scan the result table for the slot of interest, and the system load scales linearly with the number of configured devices.

This reference shows four supported methods to query the communication state of a single PROFINET IO device or a single module inside a station, without scanning the whole IO system. The methods are ordered from most surgical (targeted to a single HW identifier) to most global (event-driven via diagnostic OBs):

  1. GET_DIAG instruction against the HW identifier of the target device.
  2. ModuleStates instruction scoped to a single station.
  3. Diagnostic organization blocks (OB82, OB83, OB86) for event-driven per-device state change.
  4. The IO device status word in the process image (qualified according to PROFINET).

All four are supported on the S7-1500 CPU family and the ET 200SP / ET 200MP distributed I/O stations, and are documented in the SIMATIC S7-1500 System Manual and the STEP 7 (TIA Portal) Programming and Operating Manual. The methods are not mutually exclusive; production-grade drivers often combine GET_DIAG for a watchdog check and OB86 for event-driven alarms.

Note on the LADDR parameter. All instructions in this document that take an LADDR (or hardware identifier) input expect the HW identifier of the IO device, not its IP address, PROFINET device name, or slot number. The HW identifier is assigned by TIA Portal and can be read from the device properties under "System constants" or "Constants". Treat it as a constant in the FB interface.

Why DeviceStates Is Not the Right Tool for a Single Device

DeviceStates reads the state of all IO devices in the configured IO system. The function fills a user-supplied array with a WORD per device; bit 0 set means the device is OK, bit 1 set means the device is faulty, bit 2 set means the device does not exist (slot disabled), and so on. The instruction does not expose a filter for a single LADDR. If you only want state for device #7 out of 30, you still pay for the scan of devices 0-29 and you have to index into the result array.

State bit Meaning Typical cause
Bit 0 Device OK / data valid PROFINET AR established, cyclic IO is running.
Bit 1 Device faulty Diagnostic, channel fault, or AR in error state.
Bit 2 Device does not exist / slot disabled Device configured but not reached, or deactivated in hardware config.
Bit 3 Device is being diagnosed Diagnosis in progress (rare in steady state).
Bit 4 Device needs maintenance Maintenance demanded, e.g. PROFINET port error counter threshold.
Bit 5 Device not accessible Name resolution failed, device not found on the network.
Bit 6 Device substituted / standby Used with S7 redundancy (H-systems).

Two design decisions follow from this. First, the instruction forces the user to know the slot index of the device of interest inside the result array, which is brittle when devices are added or re-numbered. Second, the function runs synchronously in the OB that calls it; on a busy 1500 CPU this can mean several hundred microseconds of additional scan time per call, which is non-trivial inside a fast (1 ms) OB.

Prerequisites

Before implementing any of the methods below, confirm the following:

  • CPU firmware V2.0 or higher for the S7-1500. GET_DIAG and ModuleStates are both available from firmware V1.8, but MODE 1 and MODE 2 of GET_DIAG require V2.0+. Check with Online & diagnostics > CPU > Information or with the order number suffix on the front of the CPU (e.g. 6ES7511-1AK02-0AB0 = V2.6).
  • STEP 7 Professional V15.1 or higher in TIA Portal. Earlier versions do not expose MODE = 1 on GET_DIAG and lack the system constants view for the HW identifier.
  • The PROFINET device must be configured under Devices & networks with a real PROFINET interface (not a simulated IO device or a CP slot without cyclic IO).
  • The CPU must have the "PROFINET IO Controller" or "PROFINET IO Device" option enabled in the device configuration (default for S7-1500 CPUs with a PROFINET port).
  • For diagnostic OBs, the OB must exist in the program blocks. If OB82, OB83, or OB86 are missing, the CPU enters STOP on the first event. Add empty OBs early in commissioning to prevent unexpected STOPs.

Method 1: GET_DIAG Instruction for Per-Device Diagnostics

GET_DIAG is the most direct method. The instruction reads the diagnostic record of a single module or device, identified by its hardware identifier. It does not touch any other device in the IO system. The function returns a RET_VAL indicating success or an explicit error code, and writes a structured DETAIL block containing channel-level faults, status, and the maintenance bit.

The relevant modes of GET_DIAG for this application are:

MODE Return data Use case
0 Complete diagnostic record (output structures: DIAG, STATUS, CHANNEL, VENDOR_SPECIFIC) Full fault analysis, error decoding, alarm routing.
1 Status of the module / device only (no channel data) Watchdog check, "is comms healthy?" Yes/No.
2 Channel diagnostics only Per-channel fault on an IO module; not relevant for a soft-starter head module.
3 Difference between last call and current state Event-driven polling with minimum CPU load.

For a soft-starter driver the recommended call is MODE = 1: it returns a packed DWORD describing the device status. The relevant bit in that DWORD is the bit "Module / device OK". A zero in that bit means the device is not communicating or is in a fault state.

SCL Example: GET_DIAG MODE 1 Watchdog

FUNCTION_BLOCK "FB_SoftStarter_Diag"
VAR
    : StructRetain
        hwIdSoftStarter : HW_DEVICE;       // linked to device PROFINET interface
        nLastRetVal     : INT;
        bCommsOk        : BOOL;
        bDiagPending    : BOOL;
        nState          : DWORD;
    endStruct
END_VAR
BEGIN
    // Read the diagnostic status of the single device only.
    #nLastRetVal := GET_DIAG(
        MODE    := 1,
        LADDR   := "Local~PROFINET_interface_1".DEVICE_HW_ID, //  or #hwIdSoftStarter
        CHANNEL := 0,
        DETAIL  := NULL,
        SET     := FALSE,
        SRC     := 0
    );

    IF #nLastRetVal = 0 THEN
        // Bit 0 of STATE = device OK / data valid
        #bCommsOk := (#GET_DIAG.STATE AND 16#0001) <> 0;
        // Bit 1 of STATE = device faulty
        #bDiagPending := (#GET_DIAG.STATE AND 16#0002) <> 0;
    ELSE
        // GET_DIAG itself returned an error. Treat comms as not-OK.
        #bCommsOk := FALSE;
        #bDiagPending := FALSE;
    END_IF;
END_FUNCTION_BLOCK

For deeper fault decoding use MODE = 0 and a non-NULL DETAIL structure. The structure DiagDetails is generated by the TIA Portal instruction wizard and provides fields for channel number, channel error type, channel error data, and the extended PROFINET diagnostic tag. This is the path to use if the driver needs to know why the soft-starter is not communicating, not just that the link is down.

Performance note. A GET_DIAG call with MODE = 0 can take 200 to 800 microseconds on an S7-1515-2 PN depending on the size of the returned diagnostic record. A MODE = 1 call is consistently below 100 microseconds. If the driver FB runs in a 1 ms OB, use MODE = 1 for the watchdog and call MODE = 0 only on the rising edge of a fault to keep cycle time predictable.

RET_VAL (Error) Codes for GET_DIAG

RET_VAL (INT, decimal) Meaning Action
0 No error Evaluate the STATE or DETAIL block.
8091 LADDR does not refer to a configured module / device Check the HW identifier; the device may have been deleted or renamed.
8092 The MODE parameter is not supported on this module / device Reduce MODE; some head modules reject MODE = 0.
80C3 The required resources (memory) are currently in use Retry in the next cycle, or call less frequently.
80C4 Internal error, transient Retry; persistent failures indicate firmware bug, see Siemens KB entry 109751826.
80B0 Instance DB error, internal Recompile, re-download the block.

Method 2: ModuleStates Instruction Scoped to a Station

ModuleStates is the sibling of DeviceStates but with a finer scope. Instead of "the entire IO system", it operates on a single station (one IO device or one IO controller with its slots). When called with a station LADDR, it fills the result array with one WORD per module inside that station. For a soft-starter on a PROFINET interface, "station" is the head module of the soft-starter; for an ET 200SP, "station" is the interface module.

The advantage of ModuleStates over DeviceStates is that the data is local to a small number of modules (often a single module), so the call is faster and the result parsing is trivial.

SCL Example: ModuleStates Scoped to a Single Station

VAR
    arrModuleState : ARRAY[0..15] OF WORD;
    nSlotOfInterest : INT := 0;
    bHeadOk         : BOOL;
END_VAR
BEGIN
    #arrModuleState[0] := ModuleStates(
        LADDR   := "SoftStarter_Head_HW_ID",
        MODE    := 1,            // 1 = state of head only, 2 = state of all slots
        RET_VAL := #nLastRetVal
    );

    IF #nLastRetVal = 0 THEN
        // Bit 0 = OK, Bit 1 = faulty, Bit 2 = does not exist
        #bHeadOk := (#arrModuleState[0] AND 16#0001) <> 0;
    END_IF;
END_FUNCTION_BLOCK

Note the difference: ModuleStates writes its result into the first element of the array, not into a structure. The instruction returns one WORD at index 0 for MODE = 1 (single module / head). For MODE = 2 the array is filled with one entry per slot of the station. Always pre-allocate the array to the maximum slot count of the station plus 1, otherwise the call will return error 8091.

ModuleStates vs. DeviceStates. If the user configures 30 PROFINET devices under one IO controller, DeviceStates returns 30 entries. ModuleStates on the same LADDR returns the 30 devices as modules. ModuleStates on a head module of an ET 200SP returns the modules inside the head. The naming is confusing; the parameter LADDR is what defines the scope.

Method 3: Diagnostic Organization Blocks (OB82, OB83, OB86)

Diagnostic OBs are event-driven and do not need to be polled. They fire only when something changes. For a driver FB this is the most efficient mechanism: the FB is notified of a state change without scanning, and the OB carries the LADDR of the affected device in its input interface.

OB Name Fires on Input interface carries
OB 82 Diagnostic interrupt Channel fault, maintenance event, or diagnostic status change of a module IOState (WORD), LADDR (HW_DEVICE)
OB 83 Insert / remove module Module pulled or inserted, hot-swap events on ET 200S/SP LADDR, event type
OB 86 Rack failure / station failure PROFINET IO device lost (cable pulled, device powered down, AR dropped) LADDR of the failed station, IOState
OB 122 I/O access error Direct I/O access to a slot that is currently not available Slot number, area (PI / PQ)

For PROFINET device presence, OB86 is the canonical event. The OB's temporary local data provides the LADDR of the failed station. The driver's alarm handler can compare this LADDR against the soft-starter's LADDR and set a boolean flag accordingly.

SCL Example: OB86 Station-Failure Handler

// In the program blocks of the S7-1500
ORGANIZATION_BLOCK "OB86"
TITLE   = "Rack / station failure"
VERSION : "1.0"
VAR_TEMP
    t_obEventClass  : BYTE;
    t_faultId       : BYTE;
    t_isAdding      : BOOL;
    t_isRemoving    : BOOL;
    t_obIOState     : WORD;
    t_obLADDR       : HW_DEVICE;
END_VAR
BEGIN
    // Standard header evaluation
    t_faultId    := OB86_FLT_ID;
    t_isAdding   := OB86_EV_CLASS = 16#39;   // coming
    t_isRemoving := OB86_EV_CLASS = 16#38;   // going
    t_obLADDR    := OB86_MDL_ADDR;            // hardware identifier of failed device
    t_obIOState  := OB86_IO_STATE;

    IF t_obLADDR = "SoftStarter_Head_HW_ID" THEN
        IF t_isRemoving THEN
            "DB_Driver".bCommsOk := FALSE;
            "DB_Driver".nLastEvent := 1;  // station lost
        ELSIF t_isAdding THEN
            "DB_Driver".bCommsOk := TRUE;
            "DB_Driver".nLastEvent := 2;  // station returned
        END_IF;
    END_IF;
END_ORGANIZATION_BLOCK

The driver FB no longer needs to poll at all. It reads DB_Driver.bCommsOk and reacts when the value changes. This pattern is recommended in the SIMATIC S7-1500 System Manual (function manual section 11.4, "Diagnostics with diagnostic OBs").

OB latency and priority. OB86 runs at priority class 26 by default on the S7-1500. OB82 runs at priority 25. These are higher than the priority of OB1 (priority 1) or OB35 (priority 12). When OB86 fires the cyclic program is interrupted. Keep OB86 code short — a few branches and one write to a global flag. Do not call GET_DIAG from inside OB86; the diagnostic record is not yet complete on a "going" event.

Method 4: IO Device Status Word in the Process Image

PROFINET IO devices expose a per-device status word in the input process image of the controller. The status word is part of the device's "device" input image and is updated every PROFINET update cycle. The bit "IO device OK" (bit 0) is set when the AR is established and the device is sending valid cyclic data. On a loss of AR the bit is cleared by the IO controller firmware before the input image is written to the input process image area.

This is the fastest possible check (single load instruction, no system call) and is the method used internally by the Siemens standard FB PNIO_Device_Status from the SIMATIC library "PROFINET". The disadvantage is that the status word is only available if the slot is configured to provide it; on some GSD-based devices the bit may be in a different location, and on PROFIBUS DP the equivalent status comes from DPV1 slave diagnostics.

SCL Example: Status Word Watchdog

// The status word address is shown in the device properties
// under "IO tags > Device status word". It is mapped to a tag
// by the TIA Portal compiler; the user does not need to know the
// absolute address.

IF "SoftStarter_DeviceStatus".%X0 THEN
    // Bit 0 = 1: device OK, AR established, data valid
    #bCommsOk := TRUE;
ELSE
    #bCommsOk := FALSE;
END_IF;

For a soft-starter from a third-party vendor (e.g. Eaton DS7, ABB PSE, Schneider ATS22) the device status word is exposed by the GSD file. The vendor GSD defines the slot layout. The status word is typically slot 0, sub-slot 1 of the device.

Step-by-Step: Building a Single-Device State FB

  1. Open the TIA Portal project. Navigate to Devices & networks and select the soft-starter IO device.
  2. Open the device properties. Switch to System constants. Note the HW identifier of the device. It is a value of type HW_DEVICE (e.g. 269).
  3. Create a new function block FB_SoftStarter_Diag. In the interface declare an input hwDevice : HW_DEVICE (the identifier from step 2) and outputs bCommsOk : BOOL, bFault : BOOL, wState : WORD.
  4. Implement the GET_DIAG MODE = 1 call as shown in the first SCL example.
  5. For event-driven update, add an OB86 if it does not exist. In OB86, copy the OB86_MDL_ADDR to a global DB and set a flag that the FB evaluates on its next cycle.
  6. Add the FB call to a cyclic OB (e.g. OB1, OB35, or OB30 to OB38 depending on the cycle time). For a 1 ms watchdog, call from OB30 set to 1 ms cycle time. For a 10 ms watchdog, call from OB35.
  7. Compile, download, and go online. Right-click the soft-starter in Online & diagnostics and force a diagnostic interrupt by disconnecting the PROFINET cable. The FB output bCommsOk should transition to FALSE within one watchdog cycle and OB86 should fire.

Verification and Testing

After implementation, verify the driver FB with the following test cases. Each case must be performed with the CPU in RUN and the FB being scanned by a watch table.

  1. Healthy state: PROFINET cable connected, soft-starter powered, AR established. Expected: bCommsOk = TRUE, bFault = FALSE, GET_DIAG RET_VAL = 0, GET_DIAG STATE bit 0 = 1.
  2. Cable disconnect: pull the PROFINET cable from the controller side, leave the soft-starter powered. Expected: bCommsOk = FALSE within the watchdog period (1 to 10 ms), OB86 fires with OB86_EV_CLASS = 16#38 (going), the device shows "IO device not accessible" in Online & diagnostics.
  3. Device power loss: power down the soft-starter. Expected: same as case 2; both OB82 and OB86 may fire (OB82 first if the device itself reports a diagnostic).
  4. Cable reconnect: reconnect the cable. Expected: OB86 fires with OB86_EV_CLASS = 16#39 (coming), bCommsOk returns to TRUE after the next GET_DIAG poll. The AR re-establishment typically takes 200 to 800 ms on a PROFINET IRT network; on RT the time is shorter (50 to 200 ms).
  5. Slot disabled: in the device configuration, disable the soft-starter's slot 0 and re-download. Expected: bCommsOk = FALSE immediately, GET_DIAG STATE bit 2 set (does not exist), no OB86 fires (the slot is configured out).

To capture the diagnostic event stream for later analysis, attach a trace to the relevant HW identifier. In TIA Portal: Project tree > Traces > New trace, add the STATE tag of GET_DIAG and the OB86_MDL_ADDR local. Record at 1 ms, 5 s duration. The trace file (TRC) can be exported and reviewed in the SIMATIC Automation Tool.

Method Comparison Matrix

Criterion GET_DIAG MODE 1 ModuleStates OB86 (event) Status word (PI)
Scope of scan Single device Single station Single event / single device Single device (1 WORD)
CPU load per call ~ 50 to 100 µs ~ 30 to 80 µs 0 µs steady state, burst on event 1 ns (single load)
Latency to detect loss One watchdog cycle (1 to 10 ms) One watchdog cycle Immediate (event-driven, < 1 ms) One PROFINET update cycle (250 µs to 1 ms)
Detail (why it failed) Yes, with MODE 0 No (just OK / faulty) Event class, fault ID, slot No (just OK / not OK)
Needs to be polled Yes Yes No (event-driven) No (process image is updated by firmware)
Effect of slot disabling Returns bit 2 Returns bit 2 OB86 does not fire (configured out) Bit stays 0
Available on S7-1500 firmware V1.x Yes (V1.8+) Yes (V1.8+) Yes (V1.0+) Yes (V1.0+)
Best use Watchdog + root cause Head module check on ET 200 Event-driven alarm, fast reaction Hot-path check in fast OB

Field-Proven Caveats and Edge Cases

The following caveats are based on real commissioning and have not been removed to keep the reference practical.

  • Multiple ARs on a single device. A PROFINET device with shared device (e.g. a soft-starter with a separate safety module) has two HW identifiers. GET_DIAG on the safety HW identifier returns the safety AR state, not the standard AR state. Always call GET_DIAG on the standard IO AR identifier for "is comms healthy".
  • PROFINET name resolution time. On a freshly powered device, name resolution can take 3 to 10 seconds. During this window GET_DIAG returns STATE bit 5 (not accessible) before it returns bit 0 (OK). Do not interpret the bit 5 state as a permanent fault; wait for two consecutive polls to confirm.
  • OB86 latency on a loaded network. On a PROFINET IRT network with high jitter, the OB86 may be delayed by the configured PROFINET update time. For deterministic reaction, supplement OB86 with a 5 ms GET_DIAG watchdog.
  • ModuleStates on shared IO. When the soft-starter is configured as a shared device with multiple IO controllers, ModuleStates on the head returns the state visible to this controller only. The other controller may have a different view. Confirm which controller's AR is being queried via the LADDR of the controller-side AR.
  • GSD file drift. Third-party GSD files sometimes remap the device status word. After a vendor GSD upgrade, re-verify the status word location in Device properties > IO tags.
  • S7-1500R / H redundancy. On a redundant S7-1500R/H system, GET_DIAG on the AR of the primary CPU and the AR of the backup CPU can return different values. The standard pattern is to OR the two states to get a combined "device reachable" flag.
  • Web API alternative. For S7-1500 with the OPC UA server enabled, the per-device diagnostic data is also exposed as OPC UA nodes under DeviceSet//Diagnostics. The OPC UA read is non-blocking from the PLC and is suitable for SCADA mirroring.

FAQ

Can I use GET_DIAG to detect a soft-starter that is reachable on PROFINET but whose internal firmware is in a fault state?

Yes. GET_DIAG MODE = 1 reports the PROFINET AR state (link up, data valid) and does not depend on the soft-starter's internal state. For the soft-starter's own fault (e.g. overload, phase loss), read the vendor-specific diagnostics from the device record via MODE = 0 or read the standard process image slot provided by the GSD file (typically slot 4 / sub-slot 1 for the diagnostic record).

What is the difference between DeviceStates, ModuleStates, and GET_DIAG on the S7-1500?

DeviceStates returns the state of all IO devices in the entire IO system in a single call. ModuleStates returns the state of all modules within a single station. GET_DIAG returns the diagnostic data of a single device or module identified by its HW identifier. For per-device status with minimum CPU load, prefer GET_DIAG with MODE = 1 over DeviceStates or ModuleStates.

Do I need to call GET_DIAG every cycle, or can I rely on OB82 / OB86 alone?

OB82 and OB86 are event-driven and fire only on a state change. On a stable healthy PROFINET network, no OBs fire. This is the most efficient mechanism, but it does not detect a "stuck" state (e.g. the diagnostic pending bit set, no follow-up event). The recommended pattern is OB86 for fast event-driven reaction plus GET_DIAG MODE = 1 in a 5 to 10 ms cyclic OB as a watchdog.

What HW identifier do I use for the GET_DIAG LADDR parameter when the soft-starter is a third-party GSD device?

Use the HW identifier of the IO device, not the head module. The HW identifier is shown in the device properties under "System constants" as a value of type HW_DEVICE. It is also accessible as a project-wide constant of type HW_DEVICE that you can drag into the FB interface. Avoid using slot 0 sub-slot 0 (the device itself, no AR) — it does not carry the AR state.

Why does GET_DIAG return 8091 ("module not configured") immediately after download?

After a re-download, the IO configuration is rebuilt and the AR is re-established. The HW identifier is valid as a constant, but the AR may not yet be up. Wait for the next PROFINET update cycle (typically 250 to 500 ms) and retry. If the error persists for more than 5 s, the device is not reachable; check the PROFINET device name and the topology under Online & diagnostics > Topology.

Back to blog