Modbus/TCP Between Siemens S7-400 CP 443-1 and Modicon Premium

David Krause26 min read
ModbusSiemensTutorial / How-to
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

System Overview and Hardware Identification

This integration uses Modbus/TCP (an application layer profile registered with IANA on TCP/502 in 1996) to exchange process data between a Siemens SIMATIC S7-400 station and a Schneider Electric Modicon Premium TSX P57 3634M processor. The S7-400 is configured in STEP 7 V5.x (the S7-400 classic line is not engineered in TIA Portal); the Premium is configured in Unity Pro (legacy) or EcoStruxure Control Expert (current). Both controllers expose an Ethernet interface and speak Modbus/TCP on TCP port 502, which is the IANA-assigned port for the Modbus protocol (registered by Schneider Automation). The full protocol is defined by the Modbus Organization's "MODBUS MESSAGING ON TCP/IP IMPLEMENTATION GUIDE V1.0b" (2006).

The TSX P57 3634M "M" suffix is the critical identifier: it indicates that the embedded 10/100 Mbps Ethernet port supports Modbus/TCP natively, removing the need for an external TSX ETY 4103/5103 NOE module. Earlier Premium CPU variants ending in "34" without the M (e.g., TSX P57 1634, 2634) do not support Modbus/TCP on the embedded port and require an NOE module for industrial Ethernet connectivity. The complete TSX P57 catalog (P571634, P572634, P573634M, P574634M, P575634M) varies in program memory and execution speed, but the M-suffix is the only Ethernet/Modbus variant.

Hardware Bill of Materials

Item Article / Order Number Function
CPU 414-3DP 6ES7414-3EM05-0AB0 S7-400 central processor; supports STEP 7 V5.5+; integrated PROFIBUS DP master; work memory 4 MB code, 4 MB data
CP 443-1 6GK7443-1EX30-0XE0 (current) or 6GK7443-1EX11-0XE0 (legacy) Industrial Ethernet CP for S7-400; supports S7 communication, PROFINET IO, open TCP via TCON/TDIS/TSEND/TRCV; max 64 TCP connections
TSX P57 3634M TSXP573634M Modicon Premium processor with integrated 10/100 Ethernet supporting Modbus/TCP server and client; firmware V4.0+ for client (master) support
Modbus/TCP PN-CPU option package 2XV9450-1MB00 Siemens software package providing Modbus/TCP client and server FBs for S7-300/400 and ET 200S CPUs with PROFINET interface or CP 443-1; installs under STEP 7 V5.5+
The Modbus/TCP PN-CPU package is mandatory on the S7-400 side. The CP 443-1 itself contains only the open TCP transport layer; the FBs in this package implement the Modbus Application Protocol (MBAP) header, function code dispatcher, and exception handling. Without this package, you cannot read or write Modbus registers from STEP 7 V5.x. Reference: SIMATIC Modbus/TCP PN-CPU Function Manual (entry ID 109755501) and the product page at Modbus/TCP PN-CPU product support.

Network Topology and IP Plan

S7-400 Station CPU 414-3DP CP 443-1 192.168.10.1/24 Modbus/TCP Server TSX P57 3634M Modicon Premium Embedded Ethernet 192.168.10.2/24 Modbus/TCP Client Switch CAT5e CAT5e

Use a dedicated /24 subnet (192.168.10.0/24) with one unmanaged switch (Scalance XC-208 or equivalent). Modbus/TCP is an unauthenticated, non-encrypted protocol; do not route it over the corporate network without firewall restrictions. If the two stations must be on different subnets, configure a static route on the engineering PC and pin TCP/502 between the two specific IPs in the firewall ACL.

Modbus/TCP Protocol Stack and PDU Format

Modbus/TCP is defined by the Modbus Organization specification. The application layer PDU (Protocol Data Unit) is identical to serial Modbus (1 byte function code + N bytes data), but it is encapsulated in an MBAP (Modbus Application Protocol) header and transported over TCP/IP rather than RS-485. The TCP layer provides reliable ordered delivery, so Modbus/TCP does not include CRC/LRC fields (the TCP checksum suffices). The full payload on the wire is MBAP (7 bytes) + Function Code (1 byte) + Data (N bytes).

MBAP Header (7 bytes)

Field Size Description Example (hex)
Transaction ID 2 bytes Identifies the request/response pair; client sets, server echoes unchanged 0x0001
Protocol ID 2 bytes Always 0x0000 for Modbus; 0x0001 reserved for MODBUS+ 0x0000
Length 2 bytes Number of following bytes (Unit ID byte + PDU), i.e., size of the rest of the frame 0x0006
Unit ID 1 byte 0xFF for pure Modbus/TCP; 0x01-0xF7 for routing to a downstream serial slave 0xFF

Function Codes Used in This Integration

Code Function Schneider Tag Siemens Tag Use Case
0x01 (1) Read Coils %M (boolean) A, M, DBX Discrete outputs (8 bits per byte)
0x02 (2) Read Discrete Inputs %I (boolean) E, I, DBX Status inputs
0x03 (3) Read Holding Registers %MW (word) DBW, MW Analogue setpoints and process data
0x04 (4) Read Input Registers %IW (word) EW, IW, DBW Analogue measurements
0x05 (5) Write Single Coil %M (boolean) A, M, DBX Single bit write
0x06 (6) Write Single Register %MW (word) DBW, MW Single word write
0x0F (15) Write Multiple Coils %M (array) DBX array Block bit write (up to 1968 bits)
0x10 (16) Write Multiple Registers %MW (array) DBW array Block word write (up to 123 registers)

For S7-400 <-> TSX P57 3634M, the typical exchange uses function codes 0x03 (Read Holding Registers) and 0x10 (Write Multiple Registers). The Schneider %MW (memory word) area is exposed as Modbus Holding Registers; the Siemens DB (data block) area receives the data on the S7-400 side.

Modbus Exception Codes (response function code = 0x80 | original)

Code Name Meaning
0x01 Illegal Function Server does not support the function code
0x02 Illegal Data Address Offset + length exceeds server's data area
0x03 Illegal Data Value Value in request is structurally invalid
0x04 Slave Device Failure Server internal error or CPU in STOP
0x05 Acknowledge Deprecated; long-duration operation accepted
0x06 Slave Device Busy Retry later; back off the polling cycle
0x08 Memory Parity Error Server detected parity error in memory
0x0A Gateway Path Unavailable Gateway overloaded or misconfigured
0x0B Gateway Target No Response Downstream serial slave not responding

Server/Client Topology Decision Matrix

Modbus/TCP uses a strict client-server (master-slave) model: the client initiates the TCP connection on port 502, the server listens and responds. Either side can be the server; the choice is driven by application logic, polling rate, and engineering effort. The general rule: server side has less application code but cannot initiate; client side drives the cycle.

Criterion Siemens S7-400 as Server Schneider TSX P57 3634M as Server
Engineering effort Moderate - one FB (MB_SERVER) instantiated in OB1, no polling logic needed Low - enable Modbus server in Unity Pro, define data area, no code needed
Polling cycle determinism Driven by the client (TSX P57 polls the S7-400 in a fixed cycle) Driven by the client (S7-400 polls the TSX P57)
Data freshness Client request triggers update of exposed DB; one transaction per cycle Client request triggers update of exposed %MW; one transaction per cycle
Troubleshooting tools Wireshark with tcp.port==502; S7 diagnostic buffer (limited Modbus visibility) Unity Pro trace, OS Loader console, Modbus diagnostic LEDs on Premium rack
Data exposure security DB content is read by any client on the LAN - no authentication %MW content is read by any client on the LAN - no authentication
Connection count limits CP 443-1 supports up to 64 TCP connections (split between S7, PG, OP, and open TCP) TSX P57 3634M supports up to 32 simultaneous Modbus/TCP clients
For most S7-400 <-> TSX P57 integrations where the Schneider controller is the process owner (the Premium runs the recipe, the S7-400 is a subordinate slave) and the Schneider needs cyclic data from the S7-400, the Schneider TSX P57 3634M as the Modbus/TCP client (master) and the Siemens S7-400 as the server is the cleanest topology. If the S7-400 is the process owner, reverse the roles. The remainder of this guide uses the S7-400 server + TSX P57 client topology, but the reverse case is symmetric.

Siemens S7-400 / CP 443-1 Configuration

This section assumes the S7-400 is the Modbus/TCP server. The MB_SERVER FB (FB103 in Modbus/TCP PN-CPU V4) is instantiated in OB1 and processes incoming Modbus requests from the TSX P57 client. The underlying transport uses the TCON/TDIS/TSEND/TRCV open TCP blocks, which are configured in NetPro as a TCP connection.

Prerequisites

  1. STEP 7 V5.5 SP4 or later installed on the engineering PC (the Modbus/TCP PN-CPU V4 requires V5.5 minimum).
  2. Modbus/TCP PN-CPU option package (article 2XV9450-1MB00) installed; this adds FBs MB_CLIENT (FB102 in V4), MB_SERVER (FB103 in V4), and supporting UDTs to the STEP 7 library.
  3. CP 443-1 inserted in the STEP 7 hardware configuration with a valid IP address (192.168.10.1), subnet mask (255.255.255.0), and an Ethernet subnet attached.
  4. NetPro must be openable from the SIMATIC Manager; the CP 443-1's "Ethernet" entry is where the TCP connection is configured.
  5. License key for the option package transferred to the engineering PC (the package requires license activation; floating license via License Key USB or local license).

Hardware Configuration (HW Config)

  1. Open the S7 station in SIMATIC Manager and launch HW Config.
  2. Insert the CP 443-1 in the S7-400 rack. The order number 6GK7443-1EX30-0XE0 (current, 4-port switch) or legacy 6GK7443-1EX11-0XE0 (single port) is selectable from the HW catalog under SIMATIC 400 > CP-400 > Industrial Ethernet.
  3. Double-click the CP to open its properties. On the "General" tab, set the IP address (192.168.10.1) and subnet mask (255.255.255.0). On the "Ethernet" sub-tab, configure the MAC address if required (factory MAC is on the front panel sticker).
  4. Switch to the "Options" tab in the CP properties. Set "Connection mode" to "TCP/IP" (this enables open TCP for the Modbus/TCP PN-CPU FBs to use). Enable "Keep-Alive" with an interval of 30 seconds for the Modbus/TCP server case to detect dead connections.
  5. Compile and download the hardware configuration. After download, cycle the CP 443-1 (or perform an S7-400 STOP -> RUN) to activate the new IP.

NetPro Connection Configuration

  1. Open NetPro from SIMATIC Manager (target system menu, or icon in toolbar).
  2. Right-click the CP 443-1 in the S7-400 station and select "Insert New Connection".
  3. Select "TCP connection" as the connection type (under "Other stations" or "Unspecified").
  4. For the partner (TSX P57 3634M), select "Unspecified" because the Schneider is not a Siemens partner and you do not have a partner's connection configuration to import. The connection ID is assigned automatically (e.g., ID = 1).
  5. In the connection properties, set the "Partner address" to 192.168.10.2 (the TSX P57 IP) and the "Partner port" to 502 (the IANA-registered Modbus port). The "Local port" can be left as the default (2000 / 2001) - the open TCP transport uses this for the underlying socket.
  6. Set "Active connection establishment" to "No" (the S7-400 server does NOT initiate - the Schneider client initiates the connection). This is mandatory for a server role.
  7. Compile and download NetPro to the CPU. Verify the connection appears in the S7-400 online connection diagnostics (target system > connection status).
The NetPro connection parameters are used by the underlying TCON/TDIS/TSEND/TRCV open TCP transport. The Modbus/TCP PN-CPU FBs sit on top of this transport. The connection ID returned by NetPro (e.g., 1) must match the ID parameter passed to the MB_SERVER FB instance. If the IDs mismatch, MB_SERVER returns STATUS = 0x80D2 (TSAP/port invalid) and the connection is rejected.

Modbus/TCP PN-CPU FB Instantiation (S7-400 as Server)

  1. Open the S7 program in the project and open OB1.
  2. Open the STEP 7 library "Modbus_TCP_PN_CPU" (installed by the option package; default path: Programs > Modbus_TCP_PN_CPU) and drag MB_SERVER (FB103) into the project.
  3. Declare an instance DB: e.g., DB200 "iDB_MB_Server" with FB103 as its type.
  4. Wire the FB inputs in OB1 as shown in the code example below. Call MB_SERVER unconditionally in OB1; it manages its own state machine internally.
  5. Create a data block DB100 "DB_ModbusData" with a STRUCT containing an ARRAY[0..99] OF WORD. This DB holds the 100 Holding Registers exposed to the Modbus client.
  6. Download the program. The S7-400 will listen on TCP/502 once the CPU is in RUN and OB1 is executed.

Schneider TSX P57 3634M Premium Configuration

This section configures the TSX P57 3634M as the Modbus/TCP client (master) reading data from the S7-400 server. If the Schneider is the server, only the data exposure steps in the "Modbus Server" subsection apply.

Prerequisites

  1. Unity Pro XL (V8.0 or later) or EcoStruxure Control Expert (V14.0+) installed.
  2. TSX P57 3634M firmware version 4.0 or later for full Modbus/TCP client (master) support. Earlier firmware (V3.x) supports only server mode and requires an external NOE module for client role.
  3. The processor's embedded Ethernet port is enabled in the project and licensed.
  4. The MAST task of the TSX P57 is the location for the READ_VAR / WRITE_VAR calls. The FAST task is not suitable (can starve the OS Loader and cause Modbus timeouts).

Ethernet Port Configuration

  1. Open the TSX P57 station in Unity Pro.
  2. In the Project Browser, expand "Configuration" > "0: PLC Bus" > right-click the Ethernet port (e.g., "ETH_PORT_1") and select "Properties".
  3. Set the IP address to 192.168.10.2 and subnet mask to 255.255.255.0. Disable DHCP if static addressing is required (recommended for industrial networks).
  4. On the "Modbus TCP/IP" tab, enable "Modbus Server" (always available) and "Modbus Master" (firmware dependent - requires V4.0+).
  5. Configure "Number of simultaneous connections" for Modbus Master (default 16 is sufficient for most integrations).
  6. On the "Security" tab, disable any default firewall rules that would block inbound TCP/502; Modbus requires bidirectional traffic.
  7. Build the project and transfer to the TSX P57. The ETH LED on the front of the TSX P57 should turn solid green when the link is up.

Modbus Client (Master) Configuration with READ_VAR

  1. Create a new section in the MAST task of the TSX P57 program (e.g., Section "Modbus_Client").
  2. Declare a Derived Data Type (DDT) named "t_Modbus_Mgmt" with the structure shown in the code example below.
  3. Declare an instance variable: iModbus : t_Modbus_Mgmt;
  4. Call READ_VAR in the MAST section to read 20 words starting at Modbus address 100 of the S7-400 server. The OBJ parameter uses 1-based Schneider convention; 'OBJ' = '%MW100' means Holding Register 40100 in the Modbus addressing space.
  5. Trigger the read cyclically (e.g., every 100 ms) using a timer or %S6 (1-second system clock) divided by 10.
  6. Use WRITE_VAR to send data back to the S7-400. WRITE_VAR with NB = 0 is not valid; use NB >= 1.

Modbus Server (Slave) Data Exposure

If the TSX P57 3634M is acting as a server (alternative topology), the data is exposed automatically when the Modbus server is enabled in the Ethernet port configuration. The data is accessible as Modbus Holding Registers starting at address 40001, which maps to the first %MW word in the configured range. No application code is required for server mode.

  1. In Unity Pro, right-click the Ethernet port and select "Modbus Server Properties".
  2. Define the "Base Address" of the %MW area (default 0, meaning %MW0 = Modbus address 40001).
  3. Define the "Number of words" exposed (e.g., 100 words = Modbus address 40001 to 40100, mapping to %MW0..%MW99).
  4. Click "Apply" and download the configuration to the TSX P57.

Register and Tag Mapping Between Platforms

Modbus Address (1-based, user) Modbus Address (0-based, protocol) TSX P57 3634M Tag S7-400 Tag (MB_SERVER exposure)
40001 0 %MW0 DB100.DBW0
40002 1 %MW1 DB100.DBW2
40050 49 %MW49 DB100.DBW98
40100 99 %MW99 DB100.DBW198
40200 199 %MW199 DB100.DBW398

The mapping is bidirectional: writing Holding Register 40001 from the client updates both the TSX P57 %MW0 (if TSX is the server) and the S7-400 DB100.DBW0 (if S7 is the server). Function code 0x10 (Write Multiple Registers) supports batch updates with a single transaction; this is the recommended write pattern to minimize TCP/502 traffic and improve cycle time. Coils (function codes 0x01/0x05/0x0F) pack 8 bits per byte; the Siemens side maps each coil to a single DBX bit, while the Schneider side maps each coil to a single %M bit.

Modbus/TCP uses 0-based addressing in the protocol, but most SCADA HMI documentation uses 1-based. A 40001-based address 40100 corresponds to protocol offset 99. When configuring READ_VAR/WRITE_VAR on the TSX P57, the OBJ parameter uses the 1-based convention. When configuring MB_CLIENT/MB_SERVER on the S7-400, the MB_DATA_ADDR parameter uses 0-based offset (0..65535). Off-by-one errors between the two platforms are a common commissioning bug.

Byte Order and Endianness

Modbus/TCP uses Big Endian (most significant byte first) for multi-byte values in the PDU. Both the S7-400 and the TSX P57 3634M store WORD values in Big Endian byte order internally, so the wire format matches the in-memory layout and no SWAP instruction is needed. For DWORD (32-bit) values transferred as two consecutive Holding Registers, the high word is transmitted first (Holding Register N) followed by the low word (Holding Register N+1). When constructing a DWORD in S7-400 from two DBWs, the S7-400's native DWord representation is also Big Endian, so DBW N becomes the high word and DBW N+1 the low word. On the TSX P57, %MD (memory double word) is also Big Endian and aligns directly with the Modbus/TCP wire format.

Code Examples for Both Platforms

Siemens S7-400 (STEP 7 V5.x) - MB_SERVER

The MB_SERVER FB runs in OB1 and processes incoming Modbus requests from the TSX P57 client. It uses the connection ID configured in NetPro and updates the local data block based on the Modbus function code and offset in the request. The FB is non-blocking; call it once per OB1 scan.

DATA_BLOCK DB 100
  TITLE = Modbus Register Data
  STRUCT
    wHolding : ARRAY[0..99] OF WORD;  // 100 Holding Registers (40001-40100)
  END_STRUCT
END_DATA_BLOCK

FUNCTION_BLOCK FB 200
TITLE = Modbus TCP Server
VAR
  iMB_Server : MB_SERVER;        // FB103 from Modbus_TCP_PN_CPU library
  bNDR        : BOOL;            // New data received (write command)
  bDR         : BOOL;            // Data read complete (read command)
  bError      : BOOL;            // Error flag
  wStatus     : WORD;            // Error status word
END_VAR
BEGIN
  iMB_Server(
    ID         := 1,                       // NetPro connection ID
    MB_HOLD_REG:= 100,                     // DB number with Holding Registers
    MB_HOLD_LEN:= 100,                     // Number of Holding Registers
    MB_UNIT_ID := 255,                     // Unit ID (255 for Modbus/TCP)
    MB_MODE    := 1,                       // 1 = server mode
    MB_DATA_PTR:= P#DB100.DBX0.0 WORD 100, // Pointer to local data area
    NDR        := bNDR,                    // New data flag
    DR         := bDR,                     // Read complete flag
    ERROR      := bError,                  // Error flag
    STATUS     := wStatus                  // Error status word
  );
END_FUNCTION_BLOCK

ORGANIZATION_BLOCK OB 1
BEGIN
  CALL FB 200, DB 200;  // Instantiate MB_SERVER
END_ORGANIZATION_BLOCK

Siemens S7-400 (STEP 7 V5.x) - MB_CLIENT

If the S7-400 is the client, instantiate MB_CLIENT (FB102) and trigger it cyclically with a 100 ms timer. The MB_DATA_ADDR parameter is 0-based; to read Holding Register 40100, pass 99 (or pass 100 and subtract 1 in the application code).

FUNCTION_BLOCK FB 201
TITLE = Modbus TCP Client
VAR
  iMB_Client : MB_CLIENT;
  xTrigger   : BOOL;
  xDone      : BOOL;
  xBusy      : BOOL;
  xError     : BOOL;
  wStatus    : WORD;
  tCycle     : TIMER;             // 100 ms cycle timer
END_VAR
BEGIN
  // 100 ms cyclic trigger
  tCycle(IN := NOT tCycle.Q, PT := T#100MS);
  
  IF tCycle.Q AND NOT xBusy THEN
    iMB_Client(
      REQ        := TRUE,
      ID         := 1,
      MB_MODE    := 0,                       // 0 = Read
      MB_DATA_ADDR:= 99,                     // 0-based: 99 = Holding Reg 40100
      MB_DATA_LEN:= 20,                     // 20 words
      DATA_PTR   := P#DB200.DBX0.0 WORD 20,  // Local buffer
      DONE       := xDone,
      BUSY       := xBusy,
      ERROR      := xError,
      STATUS     := wStatus
    );
  END_IF;
END_FUNCTION_BLOCK

Schneider TSX P57 3634M (Unity Pro) - READ_VAR / WRITE_VAR

TYPE t_Modbus_Mgmt :
STRUCT
  nRetry   : UINT;        // Number of retries (3)
  nTimeout : UINT;        // Response timeout in seconds (2)
  nActivity: UINT;        // 0=Idle, 1=Read, 2=Write, 3=Error
  nError   : UINT;        // 0=OK, 1=ComErr, 2=Inactive, 3=ModExc,
                          // 4=Len, 5=Tmo, 6=Refused, 7=BadAddr
  abResult : ARRAY[0..19] OF WORD; // 20-word read buffer
END_STRUCT;
END_TYPE

PROGRAM Modbus_Client
VAR
  iModbus   : t_Modbus_Mgmt;
  xReadBusy : BOOL;
  xWriteBusy: BOOL;
  iWriteBuf : ARRAY[0..9] OF WORD; // 10-word write buffer
END_VAR

// Read 20 words from S7-400 server every 100 ms
IF NOT xReadBusy THEN
  iModbus.nActivity := 1;
  READ_VAR(
    ADR := '192.168.10.1',         // S7-400 CP 443-1 IP
    OBJ := '%MW100',                // 1-based: 100 = Holding Reg 40100
    NB := 20,                       // 20 words
    MG := iModbus
  );
  xReadBusy := (iModbus.nError = 0);
  // If nError <> 0, READ_VAR sets the flag itself; allow retry on next scan
  IF iModbus.nError <> 0 THEN
    xReadBusy := FALSE;
  END_IF;
END_IF;

// Write 10 words to S7-400 server
IF NOT xWriteBusy THEN
  iModbus.nActivity := 2;
  WRITE_VAR(
    ADR := '192.168.10.1',
    OBJ := '%MW200',                // Write to Holding Register 40201..40210
    NB := 10,
    EM := iModbus,
    // Source data: iWriteBuf[0..9] populates registers 40201-40210
    iWriteBuf[0] := 16#1234;
    iWriteBuf[1] := 16#5678;
    // ... populate remaining words
  );
  xWriteBusy := (iModbus.nError = 0);
  IF iModbus.nError <> 0 THEN
    xWriteBusy := FALSE;
  END_IF;
END_IF;

Performance, Cycle Time, and Throughput

Modbus/TCP cycle time is dominated by three factors: TCP setup/teardown overhead, request-response round-trip latency, and application processing time. For a persistent connection (client keeps the TCP socket open and reuses it for multiple requests), the per-transaction overhead is ~5-15 ms on a 100 Mbps LAN. At a 100 ms polling cycle, the throughput is sufficient for ~10,000 words per second of process data.

Parameter Typical Value Notes
Polling cycle 50-500 ms Faster than 50 ms risks overwhelming the S7-400's OB1 cycle
Words per transaction 20-100 Siemens MB_CLIENT limits to 100 words; Schneider READ_VAR allows up to 1000 but practical is ~100
TCP setup time 5-20 ms Three-way handshake; TCP/502 SYN, SYN-ACK, ACK
Round-trip latency 2-10 ms 100 Mbps LAN with <10 switches
Application processing 1-5 ms Server-side MB_SERVER OB1 scan impact
Connection idle timeout 30-300 s CP 443-1 default is 30 s; TSX P57 default is 240 s

For high-throughput integrations (more than 200 words per cycle), segment the data into multiple Modbus transactions of 100 words each, or upgrade to PROFINET or EtherNet/IP for a single tagged exchange. Modbus/TCP is a polling protocol; it does not support change-of-state notification or cyclic publish/subscribe semantics.

Step-by-Step Commissioning Procedure

  1. Verify the physical Ethernet link: link LEDs on the CP 443-1 and the TSX P57 3634M port should be solid green or amber. Use a continuity tester or the CP's diagnostic Web server (https://192.168.10.1) to confirm link up.
  2. Ping the S7-400 from the engineering PC: ping 192.168.10.1 should return <1 ms latency. If it fails, check VLAN configuration, IP routing, and physical cabling.
  3. Ping the TSX P57 3634M: ping 192.168.10.2. If it fails, verify the IP address via the OS Loader (e.g., Tera Term session on the TSX P57 console port at 19200 8-N-1) using the ETH_INFO command.
  4. On the engineering PC, run Wireshark with capture filter tcp.port == 502 and ip.addr == 192.168.10.2 to monitor Modbus traffic during commissioning.
  5. Download the STEP 7 hardware configuration, NetPro connection table, and program (with MB_SERVER in OB1) to the S7-400. Verify the CPU is in RUN and the CP 443-1's ACT LED is solid green.
  6. Download the Unity Pro project (with READ_VAR logic in MAST) to the TSX P57 3634M. Verify the CPU is in RUN and the ETH LED is solid green.
  7. Observe the first Modbus request in Wireshark: the MBAP header should have Transaction ID = 0x0001, Protocol ID = 0x0000, Length = 0x0006, Unit ID = 0xFF, Function Code = 0x03, Starting Address = 0x0063 (99 decimal = 40100 1-based), Quantity = 0x0014 (20 words).
  8. Verify the S7-400's response: a successful read returns Function Code 0x03, Byte Count 0x28 (40 bytes = 20 words), and the 20 word values. An error returns Function Code 0x83 with an exception code byte.
  9. In Unity Pro, monitor the iModbus.nError value in a watch window. It should be 0 after each successful transaction. If non-zero, refer to the diagnostic table in the next section.
  10. Force a register write from the S7-400 side (using a VAT table to modify DB100.DBW0) and verify that the corresponding %MW0 on the TSX P57 updates within one polling cycle.
  11. Force a write from the TSX P57 (using an animation table to set %MW200) and verify the S7-400 DB100.DBW198 updates accordingly. This validates bidirectional data flow.
  12. Disconnect the Ethernet cable on the S7-400 side and verify the TSX P57 sets nError = 1 (communication error) within the timeout window (typically 2-3 s).
  13. Reconnect the cable and verify the connection re-establishes automatically (TSX P57 retry logic) and nError returns to 0 within one polling cycle.

Diagnostics, Status Codes, and Troubleshooting Matrix

Siemens MB_SERVER / MB_CLIENT STATUS Word

STATUS (hex) Meaning Resolution
0x0000 No error Normal operation
0x0001-0x000F Modbus exception code (illegal function, illegal address, etc.) from the remote server Check the data area and register count on the server; verify the request offset is within the server's exposed range
0x7000-0x7FFF Modbus exception code (from MB_SERVER perspective, the local S7-400 returns this when the request is invalid) Verify the request format and data pointer; check the data type of MB_DATA_PTR
0x8085 TCP connection error (partner not responding, wrong IP, firewall) Ping test, verify partner port, check firewall ACL
0x80A1 Connection already established to the same partner Check for duplicate FB instances or stale connections in NetPro
0x80C8 Connection timeout (no response from partner within timeout window) Increase timeout, check partner CPU run state, verify partner has the Modbus FB active
0x80D2 TSAP or port invalid Recheck NetPro connection settings; ensure the connection ID matches between NetPro and MB_SERVER
0x80F7 MBAP header invalid (corrupted TCP segment or wrong byte order) Capture Wireshark trace; check for non-Modbus traffic on port 502; verify TCP MSS is not fragmenting the MBAP

Schneider READ_VAR / WRITE_VAR Error Codes (nError field)

Code Meaning Resolution
0 OK Normal operation
1 Communication error (TCP RST, no response) Check physical link, IP, firewall
2 Inactive server (port 502 not listening) Verify MB_SERVER is instantiated in OB1; verify the CP 443-1 connection mode is TCP/IP
3 Modbus exception received Check data area on server; verify offset + length fits in server's range
4 Inconsistent length (response shorter/longer than expected) Verify NB (number of words) matches server register count; check for truncated TCP segment in Wireshark
5 Timeout (no response within nTimeout) Increase nTimeout in the management structure; check partner CPU run state
6 Connection refused (TCP RST, e.g., wrong port) Verify port 502 is open on the partner; check for partner firewall
7 Invalid address (ADR format wrong) Check ADR string format 'a.b.c.d'; ensure no leading/trailing spaces

Troubleshooting Matrix

Symptom Likely Cause Resolution
No TCP SYN packets in Wireshark TSX P57 not initiating; READ_VAR not in MAST scan; ADR IP wrong Verify READ_VAR is called in MAST; check ADR string; verify TSX P57 MAST task is running
TCP SYN but no SYN-ACK MB_SERVER not in OB1; S7-400 CPU in STOP; CP 443-1 not configured for TCP Verify OB1 has MB_SERVER call; CPU RUN state; CP "Connection mode" = "TCP/IP"
TCP RST immediately after SYN Partner IP wrong, or partner firewall blocks port 502 Ping test; check ACL on managed switch; check Windows Firewall if S7 is in a VM
TCP connection OK but Modbus exception 0x02 (Illegal Data Address) Register offset out of server's %MW or DB range Reduce MB_DATA_ADDR + MB_DATA_LEN to fit server's data area; verify DB100 length in HW Config
Modbus exception 0x04 (Slave Device Failure) Server CPU in STOP, or data pointer is a non-existent DB Check CPU state on S7-400; verify DATA_PTR points to a valid DB; check for DB length mismatch
Intermittent timeouts every few hours TCP keep-alive not set, or partner reaps idle connection Enable keep-alive in CP 443-1 options; reduce polling cycle to keep connection active; or implement reconnect logic in MB_CLIENT
Wireshark shows correct requests, but iModbus.nError stays at 1 TSX P57 Ethernet port not enabled for Modbus Master (firmware dependent) Upgrade TSX P57 firmware to V4.0+; enable Modbus Master in port configuration
Successful exchange, but data appears swapped or doubled Off-by-one between 0-based and 1-based addressing Verify OBJ parameter uses 1-based on TSX P57; verify MB_DATA_ADDR uses 0-based on S7-400
Successful exchange, but DB values are byte-swapped Endian mismatch (rare for 16-bit, common for 32-bit) Verify word storage; for 32-bit values, check that the high word is in the lower DBW offset

Security Hardening and Migration Path

Modbus/TCP has no authentication and no encryption. Production deployments should implement the following hardening steps: (1) place the Modbus/TCP traffic on a dedicated VLAN with no routing to the corporate network; (2) configure the managed switch ACL to allow TCP/502 only between the two specific IP addresses; (3) disable ICMP echo on both controllers to prevent reconnaissance; (4) monitor TCP/502 traffic for anomalous polling patterns (rate-based IDS rules); (5) for sensitive applications, migrate to Modbus/TLS (introduced in the Modbus/TCP Security specification, 2018) or to OPC UA with certificate-based authentication.

The TSX P57 3634M is part of the Modicon Premium line, which Schneider Electric has discontinued (end of commercialization 2018, end of support 2024 for the Premium platform). The migration target is the Modicon M340 (BMXP342020) or Modicon M580 (BMEP582040) with the same Modbus/TCP port concept. The M580 BMEP58 CPU has an integrated Modbus/TCP server and client and uses the same READ_VAR/WRITE_VAR syntax as the Premium. The M340 also supports Modbus/TCP with a BMX NOE 0100/0110 Ethernet module or the integrated Ethernet on the BMX P34 20xx CPU variants. The same Modbus/TCP integration pattern applies to the Modicon M251 and M221 generation logic controllers used in smaller machine automation.

On the Siemens side, the S7-400 line is still supported (spare parts guarantee until 2030) but new designs use the S7-1500 with the integrated MODBUS_CLIENT and MODBUS_SERVER instructions in TIA Portal V14+ (no separate option package required). The S7-1500's data block mapping is identical: a DB of WORDs maps directly to Modbus Holding Registers. The transition from S7-400 to S7-1500 is largely a STEP 7 V5.x → TIA Portal conversion, and the application code (MB_SERVER/MB_CLIENT logic) maps cleanly to the new MODBUS_SERVER/MODBUS_CLIENT instruction blocks.

Frequently Asked Questions

Does the CP 443-1 support Modbus/TCP natively without the option package?

No. The CP 443-1 provides the open TCP transport layer, but the Modbus Application Protocol (MBAP) header parsing, function code dispatch, and exception handling are implemented by the FBs in the Modbus/TCP PN-CPU option package (article 2XV9450-1MB00). Without the package, you cannot exchange Modbus registers from STEP 7 V5.x. Reference: SIMATIC Modbus/TCP PN-CPU Function Manual (entry ID 109755501).

Which side should be the Modbus/TCP server, the S7-400 or the TSX P57 3634M?

Either side can be the server. The choice is driven by the application: if the Schneider controller is the process owner and cyclically reads process data from the S7-400, the S7-400 is the server. If the S7-400 is the process owner, the TSX P57 is the server. The server side requires less application code (one FB in OB1) but cannot initiate the connection; the client side initiates the TCP session and triggers the data exchange.

What is the maximum number of registers that can be read in a single Modbus/TCP transaction?

The Modbus standard allows up to 125 Holding Registers (function code 0x03) or 2008 Coils (function code 0x01) in a single request. In practice, the Siemens MB_CLIENT limits to 100 words per transaction; the Schneider READ_VAR allows up to 1000 words but practical cycle times drop above 100 words. For larger data sets, segment the request into multiple Modbus transactions or upgrade to PROFINET or EtherNet/IP for a single tagged exchange.

Why do I get exception 0x02 (Illegal Data Address) immediately after the first read succeeds?

The first read succeeds because the offset is valid; the subsequent read fails because the offset + length exceeds the server's data area. Verify that MB_DATA_ADDR + MB_DATA_LEN on the S7-400 side (or OBJ + NB on the TSX P57 side) does not exceed the server's exposed register count. For the S7-400 server, check that the DB size in MB_HOLD_LEN matches the requested length and that the DB has been downloaded to the CPU.

Can I route Modbus/TCP between the S7-400 and the TSX P57 3634M through a router?

Yes, but not recommended for production. Modbus/TCP is an unauthenticated, non-encrypted protocol on TCP/502; routing it over a wide-area network exposes the controllers to unauthorized polling. If routing is required, place a stateful firewall that allows TCP/502 between the two specific IPs only, and disable ICMP echo on the controllers to avoid reconnaissance. For sensitive applications, migrate to Modbus/TLS (introduced in the Modbus/TCP Security specification, 2018) or to OPC UA with certificate-based authentication.

Back to blog