Configuring S7-1500 as Modbus TCP Client for Wago 750-891

David Krause12 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

Architecture Overview

The SIMATIC S7-1515-2 PN is a mid-range CPU from the S7-1500 family with an integrated PROFINET interface. It can act as a Modbus TCP client using the MB_CLIENT instruction available in the TIA Portal library. The Wago 750-891 is a 4th-generation Modbus TCP controller with two Ethernet ports designed to function as a Modbus server (slave) by default.

Modbus TCP is a standard Ethernet-based variant of the Modbus protocol defined by the Modbus Organization. Communication is request/response based: a single client exchanges messages with one or more servers over TCP port 502. Because the protocol is standardized, interoperability between Siemens and Wago controllers does not require vendor-specific libraries; only correct parameterization is required.

Use the following decision table when selecting the instruction block on the S7-1500 side:

Block Role Direction Recommended Use
MB_CLIENT Modbus TCP client (master) Read/Write via TCP Primary choice for S7-1500 ↔ Wago 750-891
MB_MASTER Modbus RTU master over serial Serial RS-485 Not applicable; the 750-891 connection is Ethernet
MB_SERVER Modbus TCP server (slave) Receives requests Only if a third-party master polls the S7-1500
MB_SERIAL (legacy) Modbus RTU slave over serial Serial RS-485 Not applicable for Ethernet 750-891

Use MB_CLIENT as the S7-1500 client. Avoid MB_MASTER; that instruction is for serial RTU on the PtP interface and will not establish a TCP connection.

Prerequisites

  • SIMATIC S7-1515-2 PN (firmware V2.0 or later recommended; V2.6+ provides the enhanced MB_CLIENT with diagnostics MB_CLIENT_DB fields).
  • Wago 750-891 with two Ethernet interfaces configured in the same subnet as the S7-1500 PROFINET port.
  • WAGO Ethernet Settings (WBM) access to configure the controller's IP, subnet mask, and Modbus TCP port (default 502).
  • WAGO IO-Link Configurator or WAGO e!COCKPIT / CODESYS 2.3 / 3.5 project with the Modbus variables mapped to the process image.
  • Siemens TIA Portal V16 or later (V17/V18 recommended for cross-referencing the latest Siemens Industry Online Support entries).
  • Physical Ethernet cabling: at minimum a Cat 5e patch cable between the S7-1500 PROFINET port X1 and either X1 or X2 of the 750-891.

Wago 750-891 Server-Side Configuration

The Wago 750-891 is shipped with a Modbus TCP server (slave) configuration active. The controller exposes its I/O process image and selected flag words over Modbus register areas documented in the 750-891 manual (available from the WAGO product page for 750-891).

Configure the following parameters in the WBM:

  1. Set IP address, Subnet mask, and Default gateway in Configuration → TCP/IP. Example: 192.168.1.10 / 255.255.255.0.
  2. Confirm the Modbus TCP port is set to the default 502 unless your network policy requires otherwise.
  3. Enable the Modbus server role under Configuration → Services → Modbus TCP.
  4. Map the application variables to Modbus registers using the WAGO IO Configurator or CODESYS. Register areas follow the 750-891 mapping convention (coils, input discretes, input registers, holding registers). Always cross-check the offset (base address) for the data block you intend to access.
  5. Set the Unit ID (also called Slave Address) on the Wago. For direct Modbus TCP, leave it at 255 or 1 per the network plan.
Important: The Siemens MB_CLIENT block uses Unit ID in the MB_UNIT_ID input. If the Wago is configured to ignore the Unit ID (default behavior for Modbus TCP gateways), the S7-1500 must still send a value that the controller accepts; the typical value is 1 or 255.

TIA Portal Project Setup

Build the S7-1500 project with the following structure:

  1. Add the S7-1515-2 PN device and create the PROFINET subnet.
  2. Set the CPU's PROFINET interface IP, e.g., 192.168.1.20 / 255.255.255.0.
  3. Verify Protection & Security → Connection mechanisms → Permit access with PUT/GET is enabled (required for some legacy Modbus flows and useful for diagnostics).
  4. Install the Modbus TCP library: Options → Manage library → "Modbus TCP" (Siemens V17/V18 library or included blocks in TIA Portal >= V14). The instructions are available directly in the project under Communication → Other → MODBUS TCP.
  5. Create a global DB named MB_Client_DB as the instance DB when inserting MB_CLIENT.

Connection Configuration with TCON_IP_v4

The CONNECT parameter of MB_CLIENT accepts a structure describing the partner. Use the structured type TCON_IP_v4 (S7-1500 style) to define the remote endpoint.

// PLC tag of type TCON_IP_v4
#ConnParam : TCON_IP_v4;

// Initialize once (e.g., in OB100 / startup)
#ConnParam.InterfaceId := 64;        // HW identifier of the PROFINET interface X1
#ConnParam.ID           := 1;        // Connection ID, must be unique on CPU
#ConnParam.ConnectionType := 16#0B;  // 0x0B = TCP/IP (native, S7-1500 style)
#ConnParam.ActiveEstabl := TRUE;     // Client initiates connection
#ConnParam.LocalDeviceId := 1;       // Local PROFINET device ID (interface X1)
#ConnParam.LocalTSelector[1] := 0;   // Local TSAP high byte
#ConnParam.LocalTSelector[2] := 0;   // Local TSAP low byte
#ConnParam.LocalTSelector[3] := 0;
#ConnParam.LocalTSelector[4] := 0;
#ConnParam.RemoteStation   := 0;     // Not used for TCP native
#ConnParam.RemoteTSelector[1] := 0;  // Remote TSAP high byte
#ConnParam.RemoteTSelector[2] := 0;  // Remote TSAP low byte
#ConnParam.RemoteTSelector[3] := 0;
#ConnParam.RemoteTSelector[4] := 0;
// Remote address is assigned directly to the MB_CLIENT block
// via the partner IP inside the instruction's extended parameters.

The remote IP and port are passed through the MB_CLIENT instruction itself; on the S7-1500 they appear as inputs IP1..IP4 (or a single REMOTE_IP STRING in newer firmware) and PORT (default 502).

MB_CLIENT Instruction Setup

Insert MB_CLIENT from Instructions → Communication → MODBUS TCP. Configure the inputs as follows:

Input Type Example Description
REQ BOOL MB_REQ (pulse) Rising edge triggers a Modbus request
DISCONNECT BOOL FALSE Set TRUE to drop the TCP connection
MB_MODE USINT 0 = Read, 1 = Write Selects read or write operation
MB_DATA_ADDR UINT 40001 Modbus register start address
MB_DATA_LEN UINT 10 Number of registers/coils (1..125 words / 1..2000 bits)
MB_DATA_PTR VARIANT P#DB20.DBX0.0 WORD 10 Pointer to local data buffer
CONNECT VARIANT #ConnParam Connection description (TCON_IP_v4)
MB_UNIT_ID BYTE 1 or 255 Unit identifier / slave address

Example SCL invocation in OB1:

// Cyclic read of 10 holding registers from Wago
IF #bStartRead AND NOT #bBusyRead AND NOT #bErrorRead THEN
    #MB_CLIENT_DB.MB_MODE       := 0;                     // 0 = Read
    #MB_CLIENT_DB.MB_DATA_ADDR  := 40001;                 // Wago holding register base
    #MB_CLIENT_DB.MB_DATA_LEN   := 10;
    #MB_CLIENT_DB.MB_DATA_PTR   := P#DB20.DBX0.0 WORD 10; // local read buffer
    #MB_CLIENT_DB.REQ           := TRUE;
    #bReadTriggered := TRUE;
END_IF;

"MB_CLIENT_DB"(REQ         := #MB_CLIENT_DB.REQ,
              DISCONNECT   := FALSE,
              MB_MODE      := #MB_CLIENT_DB.MB_MODE,
              MB_DATA_ADDR := #MB_CLIENT_DB.MB_DATA_ADDR,
              MB_DATA_LEN  := #MB_CLIENT_DB.MB_DATA_LEN,
              MB_DATA_PTR  := #MB_CLIENT_DB.MB_DATA_PTR,
              CONNECT      := #ConnParam,
              MB_UNIT_ID   := 1,
              DONE         => #bDoneRead,
              BUSY         => #bBusyRead,
              ERROR        => #bErrorRead,
              STATUS       => #wStatusRead);

Read and Write Cycle Management

The MB_CLIENT block executes a single request per rising edge of REQ. You cannot read and write simultaneously over one TCP connection to the same server, so two common patterns exist:

  1. Two independent blocks, two connections – the Wago 750-891 will reject a second connection on the same IP and port, so this approach requires the Wago to allow multiple Modbus TCP sessions. If supported, call one MB_CLIENT instance for read and another for write using distinct ID values and the same TCON_IP_v4 description.
  2. Single block, alternating read/write – the more common and recommended approach. Drive REQ from a time-based sequencer (e.g., cyclic OB with a counter) that alternates MB_MODE between 0 (read) and 1 (write) every N milliseconds.
// Time-based alternation in OB35 (100 ms) or OB1
#iTick := #iTick + 1;
IF #iTick >= 5 THEN            // 5 * 100 ms = 500 ms cadence
    #iTick := 0;
    #bDoRead := NOT #bDoRead;
END_IF;

IF #bDoRead THEN
    #MB_CLIENT_DB.MB_MODE      := 0;
    #MB_CLIENT_DB.MB_DATA_ADDR := 40001;     // Inputs (read)
    #MB_CLIENT_DB.MB_DATA_PTR  := P#DB20.DBX0.0 WORD 10;
ELSE
    #MB_CLIENT_DB.MB_MODE      := 1;
    #MB_CLIENT_DB.MB_DATA_ADDR := 40011;     // Outputs (write)
    #MB_CLIENT_DB.MB_DATA_PTR  := P#DB20.DBX20.0 WORD 10;
END_IF;

Modbus Function Codes Reference

Select the appropriate function code through MB_MODE and the data address range. The S7-1500 MB_CLIENT supports the codes listed below. These match the Modbus TCP functions documented for the ET 200MP interface module family, which uses the same library.

FC Name Access Address Range (S7-1500 notation) MB_MODE
FC 1 Read Coils Bit-by-bit (read) 00001..09999 0
FC 2 Read Discrete Inputs Bit-by-bit (read) 10001..19999 0
FC 3 Read Holding Registers Word (read) 40001..49999 0
FC 4 Read Input Registers Word (read) 30001..39999 0
FC 5 Write Single Coil Bit-by-bit (write) 00001..09999 1
FC 6 Write Single Register Word (write) 40001..49999 1
FC 15 Write Multiple Coils Bit-by-bit (write) 00001..09999 1
FC 16 Write Multiple Registers Word (write) 40001..49999 1
FC 23 Read/Write Multiple Registers Word (read+write) 40001..49999 0 (with simultaneous write in MB_WRITE_* fields on V2.6+)
Function code 23 is available on firmware V2.6 and later. The S7-1500 will automatically issue the correct FC based on the data length and target area.

Byte Order and Endianness

Modbus TCP transmits 16-bit registers in big-endian (network byte order). The S7-1500 stores WORD and INT values in little-endian. The library handles the 16-bit swap for single registers, but multi-word data types (DWORD, DINT, REAL) require explicit byte reversal at the application level.

Use the SWAP or TAW / TAD instructions on the buffer data after a read or before a write. Example for REAL values:

// After reading 20 holding registers into DB20
FOR #i := 0 TO 4 DO
    // Each REAL occupies 2 Modbus registers = 4 bytes
    #tmpByte0 := DB20.DBB[8 * #i + 0];
    #tmpByte1 := DB20.DBB[8 * #i + 1];
    #tmpByte2 := DB20.DBB[8 * #i + 2];
    #tmpByte3 := DB20.DBB[8 * #i + 3];

    // Reverse word order to match big-endian Modbus transmission
    DB20.DBB[8 * #i + 0] := #tmpByte2;
    DB20.DBB[8 * #i + 1] := #tmpByte3;
    DB20.DBB[8 * #i + 2] := #tmpByte0;
    DB20.DBB[8 * #i + 3] := #tmpByte1;
END_FOR;

The S7-300/400 family is big-endian; the S7-1500 is little-endian. If you migrate legacy S7-300 code that communicated with the same Wago controller, you must add or remove swapping logic accordingly.

Diagnostics and Status Words

The instance DB of MB_CLIENT exposes a structured status area on firmware V2.0 and later:

Tag Type Meaning
DONE BOOL Request completed without error
BUSY BOOL Request still in progress
ERROR BOOL Request terminated with error
STATUS WORD Detailed status code (see Siemens help)
MB_DATA_LEN (current) UINT Number of bytes actually transferred
CONNECTED BOOL TCP connection state (V2.6+)

Common STATUS values for client-side errors:

STATUS (hex) Meaning Remedy
0x0000 No error -
0x7000 Call without active job Trigger REQ
0x7001 First call, job running Wait for DONE / ERROR
0x7002 Subsequent call, job running Wait
0x8380 Connection ID in use Use a different ID in TCON_IP_v4
0x8381 Connection establishment rejected/timeout Check Wago IP, port, firewall
0x8382 Lost connection during job Check cabling, Wago power, idle timeout
0x8383 Connection already established Idle the block briefly, then re-trigger
0x80C8 Modbus exception code from server (gateway path unavailable) Verify Wago register range and Unit ID
0x80C9..0x80D2 Modbus exception codes 1..10 See Modbus spec for code meaning

Enrich the diagnosis with the Wago 750-891's Web-Based Management (WBM) page Diagnostics → Modbus, which logs the last received requests and exception responses.

Verification Procedure

  1. Compile and download the TIA Portal project to the S7-1515-2 PN.
  2. Open the Wago 750-891 WBM and confirm the Modbus TCP service is enabled and listening on port 502.
  3. Go online in TIA Portal and force REQ on the MB_CLIENT instance.
  4. Watch STATUS; a successful read returns 0x0000 and sets DONE := TRUE.
  5. Inspect the data buffer DB; values must change as the Wago inputs change.
  6. Toggle a write coil / register from the S7-1500 and verify the Wago output changes physically or in the WBM.
  7. Use a packet capture (e.g., Wireshark with filter tcp.port == 502) to confirm MBAP headers are well-formed.

Troubleshooting Matrix

Symptom Probable Cause Corrective Action
STATUS 0x8381, BUSY stays TRUE Wago unreachable on TCP 502 Ping Wago from a laptop in the same subnet; verify IP, mask, gateway, and that the 750-891 IP is not duplicated
STATUS 0x80C8 / 0x80CA Modbus exception "Illegal data address" Confirm MB_DATA_ADDR exists in the Wago process image; review 750-891 manual register map
STATUS 0x8380 Connection ID already in use Use unique ID per MB_CLIENT instance; avoid restarting a TCON that another block holds
Data received but values are rotated or mirrored Endianness mismatch on DWORD/REAL Insert a byte-swap routine on multi-word variables
Write never reaches the Wago Wago in slave role but write area not mapped Confirm in CODESYS / IO Config that the target Modbus register is mapped to a process variable
DONE pulses only once after a cold restart Single TCP connection used for both read and write without alternation Implement time-based alternation of MB_MODE or use two connections if Wago permits
No data on coils (FC 1/FC 5/FC 15) Coil address not within 0x range Use 00001..09999 base for coils; 10001..19999 for discrete inputs; the S7-1500 maps the prefix to FC
WBM shows "Modbus server disabled" Service stopped after firmware update Re-enable in Configuration → Services and reboot the controller

Field-Proven Notes

  • The Wago 750-891 manual uses the term slave (legacy RTU vocabulary). In Modbus TCP and in the S7-1500 MB_CLIENT documentation the same role is called server. Treat the two terms as synonyms for this project.
  • The 750-891's two Ethernet ports form a managed switch; you may connect the S7-1500 and a programming PC to the same controller, but disable any Ethernet loop and keep a single VLAN.
  • Update the Wago firmware to a recent 4th-generation release (FW 04.x or later) when possible. Older versions do not support the "Modbus TCP over multiple connections" feature, which is required if you need parallel read/write blocks.
  • If you reprogram the 750-891 in CODESYS to act as a Modbus client (uncommon for this topology), the S7-1500 must then use MB_SERVER instead of MB_CLIENT.
  • Always define a watch-dog on the application layer: if no successful DONE is received for N seconds, raise a PLC-side fault and switch outputs to a safe state.

Frequently Asked Questions

Should I use MB_CLIENT or MB_MASTER for the S7-1500 to Wago 750-891 link?

Use MB_CLIENT. MB_MASTER operates over a serial PtP interface, not Ethernet, and will never establish a TCP session to the 750-891 on port 502.

How many Modbus TCP connections can the Wago 750-891 accept simultaneously?

The 4th-generation 750-891 supports multiple Modbus TCP sessions (typically up to 8), each on port 502. You can therefore use two MB_CLIENT instances on the S7-1500 with different connection IDs for parallel read and write.

Why are my 32-bit values reversed on the S7-1500?

Modbus TCP carries registers in big-endian order, while the S7-1500 stores multi-byte data in little-endian. Swap the byte order with SWAP or a manual byte reversal for every DWORD / REAL / DINT transferred.

What Unit ID should I configure in MB_UNIT_ID?

For a direct Modbus TCP connection to a single 750-891, use 1 or 255. The Unit ID is meaningful mainly when the 750-891 is acting as a gateway to downstream Modbus RTU slaves; otherwise the controller usually ignores it.

How do I confirm the S7-1500 is actually polling the Wago?

Watch the Wago 750-891 WBM page Diagnostics → Modbus for a live counter of received requests, and use Wireshark with the filter tcp.port == 502 to capture the MBAP/PDU traffic from the CPU.

Back to blog