PLC PROFINET IO Configuration: GSDML Files, IO Devices & Structured Text Data Exchange

Configure PROFINET IO devices from scratch — understand GSDML files, slot/subslot mapping, IO data exchange, and diagnostic handling in Structured Text.

What Is PROFINET IO?

PROFINET IO is the leading Industrial Ethernet standard for real-time communication between PLCs and field devices. Unlike classic PROFIBUS (which uses serial RS485), PROFINET runs on standard Ethernet hardware — but adds deterministic, real-time scheduling that regular TCP/IP cannot guarantee.

Why PROFINET Dominates Modern Automation

  • Speed: Cycle times as low as 31.25 µs (IRT mode) for servo drives
  • Standard hardware: Uses regular Ethernet switches, cables, and connectors
  • Scalability: Up to 256 IO devices per controller, thousands of data points
  • Diagnostics: Built-in channel-level fault detection — know exactly which wire is broken
  • Coexistence: PROFINET and IT traffic (HTTP, OPC UA) share the same cable
  • PROFINET vs. Other Industrial Ethernet Protocols

    FeaturePROFINET IOEtherNet/IPModbus TCPEtherCAT
    VendorSiemens / PIRockwell / ODVASchneiderBeckhoff
    Real-timeRT / IRTCIP SyncNoneDC (Distributed Clocks)
    TopologyStar, Line, RingStar, DLR RingStarLine (daisy-chain)
    Min cycle31.25 µs (IRT)1 ms~10 ms62.5 µs
    Device fileGSDML (XML)EDSNoneESI (XML)
    DiagnosticsExcellentGoodBasicExcellent

    Understanding GSDML Files

    Every PROFINET IO device ships with a GSDML file (General Station Description Markup Language). This XML file tells the PLC engineering tool everything about the device:

  • Device identity (vendor, model, hardware/firmware revision)
  • Available modules and submodules
  • IO data lengths (input bytes, output bytes)
  • Supported parameters and their ranges
  • Diagnostic capabilities
  • GSDML File Structure

    GSDML-V2.3x-VendorName-DeviceName-20240101.xml
    │
    ├── ProfileHeader (standard version)
    ├── DeviceIdentity
    │   ├── VendorID: 0x002A
    │   └── DeviceID: 0x0001
    ├── DeviceAccessPointList
    │   └── DeviceAccessPoint (the head module / coupler)
    │       ├── ModuleList (pluggable modules)
    │       │   ├── Module: 4DI (4 Digital Inputs)
    │       │   ├── Module: 2AI (2 Analog Inputs)
    │       │   └── Module: 4DO (4 Digital Outputs)
    │       └── SubmoduleList
    │           └── Submodule IO data definitions
    └── ApplicationProcess
        └── ParameterRecordData (device-specific config)
    

    Key GSDML Concepts

    Slots and Subslots: Physical module positions. Slot 0 is always the coupler/head. Slots 1–N hold IO modules. Each slot has subslots for individual channels.

    API (Application Process Identifier): Groups related IO data. Most devices use API 0.

    Module Ident Number: Unique ID for each module type within the GSDML.

    Setting Up a PROFINET IO Device — Step by Step

    Step 1: Install the GSDML File

    In TIA Portal, CODESYS, or your engineering tool:

  • Download the GSDML file from the device manufacturer's website
  • Import it: Options → Manage Device Descriptions → Install
  • The device now appears in the hardware catalog
  • Step 2: Add the IO Device to Your Project

  • Open the network/hardware view
  • Drag the IO device from the catalog onto the PROFINET network
  • Assign a device name (e.g., io-station-01) — PROFINET uses names, not addresses
  • Configure the IP address (or let DHCP/DCP assign it)
  • Step 3: Configure Module Slots

    Map physical modules to slots matching your actual hardware:

    Slot 0: Coupler / Head Module (auto-configured)
    Slot 1: 8DI Module — 1 byte input
    Slot 2: 8DO Module — 1 byte output
    Slot 3: 4AI Module — 8 bytes input (4 × INT16)
    Slot 4: 2AO Module — 4 bytes output (2 × INT16)
    

    Step 4: Map IO Addresses

    Each module occupies a range in the PLC's IO address space:

    SlotModuleDirectionStart AddressLength
    18DIInputIB01 byte
    28DOOutputQB01 byte
    34AIInputIW28 bytes
    42AOOutputQW24 bytes

    Reading IO Data in Structured Text

    Once the hardware is configured, accessing PROFINET IO data in Structured Text is straightforward — it's just memory-mapped I/O:

    Digital Inputs

    PROGRAM ReadDigitalInputs
    VAR
        // PROFINET 8DI module at Slot 1
        Sensor_Prox1    AT %IX0.0 : BOOL;   // Channel 0
        Sensor_Prox2    AT %IX0.1 : BOOL;   // Channel 1
        Sensor_Photo1   AT %IX0.2 : BOOL;   // Channel 2
        LimitSwitch_Fwd AT %IX0.3 : BOOL;   // Channel 3
        LimitSwitch_Rev AT %IX0.4 : BOOL;   // Channel 4
        EStop_Channel   AT %IX0.5 : BOOL;   // Channel 5
        DoorSwitch      AT %IX0.6 : BOOL;   // Channel 6
        Spare_DI        AT %IX0.7 : BOOL;   // Channel 7
        
        ConveyorRunning : BOOL := FALSE;
    END_VAR

    // Use PROFINET inputs like any other I/O IF Sensor_Prox1 AND NOT LimitSwitch_Fwd THEN ConveyorRunning := TRUE; END_IF;

    IF EStop_Channel THEN ConveyorRunning := FALSE; END_IF; END_PROGRAM

    Analog Inputs with Scaling

    PROGRAM ReadAnalogInputs
    VAR
        // PROFINET 4AI module at Slot 3
        AI_Raw_0 AT %IW2  : INT;    // Channel 0 raw (0–27648)
        AI_Raw_1 AT %IW4  : INT;    // Channel 1 raw
        AI_Raw_2 AT %IW6  : INT;    // Channel 2 raw
        AI_Raw_3 AT %IW8  : INT;    // Channel 3 raw
        
        // Scaled engineering values
        Temperature : REAL;   // °C
        Pressure    : REAL;   // bar
        FlowRate    : REAL;   // L/min
        Level       : REAL;   // %
    END_VAR

    // Scale 4-20mA input (raw 0–27648) to engineering units // Formula: EU = ((Raw - RawMin) / (RawMax - RawMin)) * (EUMax - EUMin) + EUMin

    Temperature := (INT_TO_REAL(AI_Raw_0) / 27648.0) * 200.0; // 0–200°C Pressure := (INT_TO_REAL(AI_Raw_1) / 27648.0) * 10.0; // 0–10 bar FlowRate := (INT_TO_REAL(AI_Raw_2) / 27648.0) * 500.0; // 0–500 L/min Level := (INT_TO_REAL(AI_Raw_3) / 27648.0) * 100.0; // 0–100% END_PROGRAM

    Writing Digital and Analog Outputs

    PROGRAM WriteOutputs
    VAR
        // PROFINET 8DO module at Slot 2
        Valve_Inlet     AT %QX0.0 : BOOL;
        Valve_Outlet    AT %QX0.1 : BOOL;
        Motor_Conveyor  AT %QX0.2 : BOOL;
        Alarm_Beacon    AT %QX0.3 : BOOL;
        
        // PROFINET 2AO module at Slot 4
        AO_Speed_Cmd    AT %QW2 : INT;     // VFD speed reference
        AO_Valve_Pos    AT %QW4 : INT;     // Control valve position
        
        DesiredSpeed : REAL := 50.0;       // 0–100%
        ValveSetpoint : REAL := 75.0;      // 0–100%
    END_VAR

    // Scale engineering units back to raw output AO_Speed_Cmd := REAL_TO_INT(DesiredSpeed / 100.0 * 27648.0); AO_Valve_Pos := REAL_TO_INT(ValveSetpoint / 100.0 * 27648.0);

    // Digital outputs IF DesiredSpeed > 0.0 THEN Motor_Conveyor := TRUE; END_IF; END_PROGRAM

    PROFINET Diagnostics in Structured Text

    One of PROFINET's biggest advantages is channel-level diagnostics. You can detect exactly which module, channel, or wire has a fault:

    Checking Device Status

    PROGRAM ProfinetDiagnostics
    VAR
        // System status words (platform-dependent addresses)
        IO_DeviceStatus   : WORD;          // Overall device status
        IO_ModuleStatus   : ARRAY[0..7] OF WORD;  // Per-slot status
        
        DeviceOnline      : BOOL;
        ModuleFault       : ARRAY[0..7] OF BOOL;
        DiagCount         : INT := 0;
        
        // Diagnostic message buffer
        LastFaultSlot     : INT := -1;
        LastFaultChannel  : INT := -1;
        DeviceOK          : BOOL := FALSE;
    END_VAR

    // Check if the entire IO device is communicating DeviceOnline := (IO_DeviceStatus AND 16#0001) = 16#0001;

    IF NOT DeviceOnline THEN // Device lost — could be cable, switch, or power issue LastFaultSlot := 0; LastFaultChannel := -1; // Entire device END_IF;

    // Check individual module status DiagCount := 0; FOR i := 0 TO 7 DO ModuleFault[i] := (IO_ModuleStatus[i] AND 16#0002) <> 0; IF ModuleFault[i] THEN LastFaultSlot := i; DiagCount := DiagCount + 1; END_IF; END_FOR;

    DeviceOK := DeviceOnline AND (DiagCount = 0); END_PROGRAM

    PROFINET Device Naming & Discovery

    Unlike PROFIBUS (which uses station addresses 1–126), PROFINET uses device names for identification. The DCP (Discovery and Configuration Protocol) handles this:

    Naming Conventions

    ✅ Good naming:
      io-conveyor-01
      robot-cell-a-safety
      vfd-pump-station-3

    ❌ Bad naming: device1 (not descriptive) My IO Device (spaces not allowed) STATION.01 (dots not allowed in older firmware)

    Network Topology Best Practices

    Controller (PLC)
        │
        ├── Managed Switch ─── io-filling-01 (Star topology)
        │       ├──────────── io-filling-02
        │       └──────────── io-filling-03
        │
        └── io-conveyor-01 ─── io-conveyor-02 ─── io-conveyor-03
                            (Line / daisy-chain topology)
    

  • Star topology: Best reliability — one cable fault affects only one device
  • Line topology: Saves cabling cost, but a fault breaks all downstream devices
  • Ring topology (MRP): Self-healing — recovers from a single cable break in <200ms
  • Real-Time Classes: RT vs. IRT

    PROFINET offers different performance levels:

    RT (Real-Time) — Most Common

  • Uses standard Ethernet switches
  • Cycle times: 1–10 ms typical
  • Suitable for: sensors, valves, VFDs, most IO modules
  • This is what 90% of applications use
  • IRT (Isochronous Real-Time) — High Performance

  • Requires IRT-capable switches (Siemens SCALANCE, device-integrated)
  • Cycle times: down to 31.25 µs
  • Jitter: < 1 µs
  • Suitable for: servo drives, synchronized multi-axis motion
  • Requires careful topology planning
  • Performance Comparison:
    ──────────────────────────────────────────
    │ Standard TCP/IP │  ~10-100 ms  │ HMI, SCADA    │
    │ PROFINET RT     │  1-10 ms     │ IO, VFDs      │
    │ PROFINET IRT    │  0.25-1 ms   │ Servo drives  │
    ──────────────────────────────────────────
    

    Common PROFINET Commissioning Issues

    1. "BF" (Bus Fault) LED Flashing

    Cause: Device name mismatch between project and actual device.

    Fix: Use the PLC engineering tool to assign the correct device name via DCP: Online → Accessible Devices → Assign Device Name

    2. Module Configuration Mismatch

    Cause: GSDML module order doesn't match physical hardware.

    Fix: Verify slot assignments match physical module positions exactly.

    3. IO Data Not Updating

    Cause: Wrong IO address mapping or module not in "Data Exchange" state.

    Fix: Check the module status — it should show "RUN" / "Data Exchange Active."

    4. Intermittent Communication Loss

    Cause: Usually a cabling issue — PROFINET is sensitive to cable quality.

    Fix:

  • Use industrial-rated Cat5e or Cat6 cables
  • Check cable length (max 100m per segment)
  • Verify connector pin crimping with a cable tester
  • Complete PROFINET IO Exchange Example

    PROGRAM ProfinetIOExchange
    VAR
        // === PROFINET IO Device: "io-station-01" ===
        
        // Slot 1: 8DI Module (1 byte input)
        DI_Byte AT %IB0 : BYTE;
        
        // Slot 2: 8DO Module (1 byte output)
        DO_Byte AT %QB0 : BYTE;
        
        // Slot 3: 4AI Module (8 bytes input)
        AI_Ch0 AT %IW2 : INT;
        AI_Ch1 AT %IW4 : INT;
        AI_Ch2 AT %IW6 : INT;
        AI_Ch3 AT %IW8 : INT;
        
        // Slot 4: 2AO Module (4 bytes output)
        AO_Ch0 AT %QW2 : INT;
        AO_Ch1 AT %QW4 : INT;
        
        // Process variables
        StartButton   : BOOL;
        StopButton    : BOOL;
        SensorActive  : BOOL;
        Temperature   : REAL;
        Pressure      : REAL;
        
        PumpRunning   : BOOL := FALSE;
        PumpSpeed     : REAL := 0.0;
        ValvePosition : REAL := 0.0;
        HighTempAlarm : BOOL := FALSE;
    END_VAR

    // ── Read Digital Inputs (bit extraction from byte) ── StartButton := (DI_Byte AND 16#01) <> 0; // Bit 0 StopButton := (DI_Byte AND 16#02) <> 0; // Bit 1 SensorActive := (DI_Byte AND 16#04) <> 0; // Bit 2

    // ── Scale Analog Inputs ── Temperature := (INT_TO_REAL(AI_Ch0) / 27648.0) * 150.0; // 0–150 °C Pressure := (INT_TO_REAL(AI_Ch1) / 27648.0) * 16.0; // 0–16 bar

    // ── Process Logic ── IF StartButton AND NOT StopButton AND Pressure < 12.0 THEN PumpRunning := TRUE; PumpSpeed := 75.0; // 75% speed END_IF;

    IF StopButton OR Pressure >= 14.0 THEN PumpRunning := FALSE; PumpSpeed := 0.0; END_IF;

    HighTempAlarm := Temperature > 120.0; IF HighTempAlarm THEN ValvePosition := 100.0; // Full open cooling valve ELSE ValvePosition := 50.0; // Normal position END_IF;

    // ── Write Digital Outputs ── IF PumpRunning THEN DO_Byte := DO_Byte OR 16#01; // Set bit 0 (pump contactor) ELSE DO_Byte := DO_Byte AND 16#FE; // Clear bit 0 END_IF;

    IF HighTempAlarm THEN DO_Byte := DO_Byte OR 16#02; // Set bit 1 (alarm beacon) ELSE DO_Byte := DO_Byte AND 16#FD; // Clear bit 1 END_IF;

    // ── Write Analog Outputs ── AO_Ch0 := REAL_TO_INT(PumpSpeed / 100.0 * 27648.0); // VFD speed ref AO_Ch1 := REAL_TO_INT(ValvePosition / 100.0 * 27648.0); // Valve position END_PROGRAM

    Summary

    PROFINET IO is the backbone of modern Siemens and multi-vendor PLC systems. The key concepts to master are: GSDML files define what a device can do; slots and subslots map to physical modules; device names (not addresses) identify devices on the network; and IO data exchange is simply reading/writing memory-mapped addresses in Structured Text. Combined with built-in diagnostics, PROFINET gives you unmatched visibility into your field devices — from the physical cable all the way up to individual sensor channels.