Overview
When an S7-1200 CPU (such as the S7-1214C DC/DC/DC or DC/DC/Rly) is connected to a Modbus TCP gateway that terminates an RS485 multidrop bus, the PLC cannot simply poll the gateway's own register map and expect to see the downstream field devices. The gateway only acts as a transport relay. To reach the slaves on the serial side, the MB_CLIENT instruction must be parameterized with the slave's Modbus Unit ID (also known as the slave address or station address). This article walks through the exact configuration in TIA Portal V15.1 and later, the relevant instance-DB parameters, the alternative TCON/TSEND/TRECV path for non-Joshua/Elpro gateways, and the verification steps that confirm end-to-end register access.
The reference architecture addressed here is:
- S7-1214C CPU firmware V4.2 or later (MB_CLIENT ships in the S7-1200 base instruction library from V4.0 onwards)
- Modbus TCP-to-RS485 gateway (e.g., Elpro 105U, Moxa MGate MB3170, HMS Anybus, Phoenix Contact EW50, or a generic "transparent" gateway)
- One or more RS485 slaves (Modbus RTU) with station addresses 1–247
- Default Modbus TCP port 502
Prerequisites
Confirm the following before you start configuring the PLC project:
-
CPU firmware and library: The S7-1200 must be firmware V4.0 or higher to expose
MB_CLIENTin the standard instruction palette. Open TIA Portal, select the device, and verify the firmware under Online > Diagnostics > Module Information. -
License-free instruction:
MB_CLIENT(FB 1083) andMB_SERVER(FB 1084) are part of the S7-1200 base library and require no additional license, but the CPU must support Modbus TCP communication (any standard S7-121x/15x/15xC does). - Gateway in transparent/unit-ID passthrough mode: The gateway must be configured to forward Modbus TCP requests to the serial bus using the embedded Unit ID as the RTU slave address. Most modern gateways expose this as a setting labeled Unit ID forwarding, Slave ID pass-through, or Transparent mode. If the gateway strips or replaces the Unit ID, the S7-1200 will only ever reach whatever slave address the gateway assigns by default.
- Ethernet connectivity: PLC, gateway, and engineering PC all on the same subnet (e.g., 192.168.0.0/24). The PLC's PROFINET interface must be assigned a fixed IP, not obtained from the router.
- TCP port 502 open: Confirm no firewall blocks port 502 between PLC and gateway.
- RS485 bus terminated and biased: 120 Ω termination at both ends, fail-safe bias resistors if the slaves are not internally biased.
MB_Unit_ID.How MB_CLIENT Routes Requests Through a Gateway
The MB_CLIENT instruction builds a standard Modbus TCP ADU (Application Data Unit) consisting of:
- MBAP header (7 bytes): Transaction ID, Protocol ID (0x0000 for Modbus), Length, Unit ID.
- PDU (up to 253 bytes): Function code and payload.
The MBAP header's Unit Identifier byte is the field that tells the gateway which downstream serial slave to address. By default, TIA Portal sets this byte to 255 (0xFF) for the default Modbus TCP behavior. When a gateway is in the path, that byte must be overwritten with the RTU slave address you want to reach (1–247).
| MBAP Field | Length | Default in MB_CLIENT | Value Needed for Gateway |
|---|---|---|---|
| Transaction ID | 2 bytes | auto-incremented | auto |
| Protocol ID | 2 bytes | 0x0000 | 0x0000 |
| Length | 2 bytes | auto | auto |
| Unit ID | 1 byte | 255 (0xFF) | Slave address, e.g., 5 |
Step-by-Step Configuration in TIA Portal
Step 1 - Add MB_CLIENT to the Program
Open the S7-1200 program block (e.g., Main [OB1]) and drag Instructions > Communication > Modbus TCP > MB_CLIENT into a network. The first time you place it, TIA Portal automatically generates an instance data block (e.g., MB_CLIENT_DB) where the connection parameters are stored.
Step 2 - Configure the Connection Parameters
Open the instance DB and populate the following static tags. These are the values that define the gateway connection:
| Parameter | Type | Example Value | Description |
|---|---|---|---|
Connect |
BOOL | TRUE | Trigger to (re)establish TCP connection |
IP1..IP4 |
USINT[4] | 192, 168, 0, 10 | Gateway IPv4 octets (PLC sends to this IP) |
Port |
UINT | 502 | Modbus TCP port on the gateway |
MB_Unit_ID |
BYTE | 5 | RTU slave address on the RS485 bus |
Mode |
USINT | 0 = TCP | Communication mode (TCP/IP) |
DataPtr |
VARIANT | P#DB20.DBX0.0 BYTE 100 | Pointer to the data buffer in a global DB |
DataLen |
UINT | 100 | Length of the data buffer in bits/words (function-code dependent) |
Function |
USINT | 3 (Read Holding) or 16 (Write Multiple) | Modbus function code |
Step 3 - Set MB_Unit_ID to the Serial Slave Address
This is the critical parameter. Most engineers miss it because TIA Portal's default wizard places 255 in MB_Unit_ID, which is the broadcast value for Modbus TCP/IP-direct devices. For a gateway scenario, you must hard-code the Unit ID to the slave's RTU station address:
Example ladder snippet in STL/structured text to set the Unit ID dynamically for two slaves polled alternately:
// Slave 5 - read 10 holding registers
IF "poll_cycle" = 0 THEN
"MB_CLIENT_DB".MB_Unit_ID := 5; // RTU slave address
"MB_CLIENT_DB".Function := 3; // Read Holding Registers
"MB_CLIENT_DB".DataPtr := P#"DB_SlaveData".Slave5 BYTE 20;
"MB_CLIENT_DB".DataLen := 10;
"MB_CLIENT_DB".REQ := TRUE;
END_IF;
// Slave 12 - read 10 holding registers
IF "poll_cycle" = 1 THEN
"MB_CLIENT_DB".MB_Unit_ID := 12;
"MB_CLIENT_DB".Function := 3;
"MB_CLIENT_DB".DataPtr := P#"DB_SlaveData".Slave12 BYTE 20;
"MB_CLIENT_DB".DataLen := 10;
"MB_CLIENT_DB".REQ := TRUE;
END_IF;
Step 4 - Compile, Download, and Go Online
- Compile the project (Project tree > S7-1200 station > Compile > Software).
- Download to the CPU (Online > Download to device).
- Go online and open the instance DB in monitor mode.
Step 5 - Verify with a Read Request
Trigger REQ once and observe the output parameters:
| Status Tag | Expected Value if OK | Meaning |
|---|---|---|
DONE |
TRUE (one cycle) | Request completed without error |
BUSY |
FALSE | Not currently executing |
ERROR |
FALSE | No error detected |
STATUS |
0 | 0 = no error; 16#7001/7002 = in progress |
Alternative Path: TCON, TSEND, TRECV for "Dumb" Gateways
If your gateway does not honor the MBAP Unit ID byte (some legacy or lower-cost units strip it and only forward to a fixed slave address), MB_CLIENT alone will not work. In that case you must construct the Modbus TCP frame manually using the Open User Communication (OUC) instructions:
| Instruction | Purpose |
|---|---|
TCON |
Establish/configure TCP connection (FB 186) |
TSEND |
Send the constructed Modbus ADU (FB 187) |
TRECV |
Receive the response ADU (FB 188) |
TDISCON |
Tear down the connection (FB 189) |
A minimal Modbus TCP read-holding-registers request for slave 5, starting at register 0, length 10 would look like this when constructed in a byte buffer:
// Modbus TCP ADU for FC 03, slave 5, addr 0, qty 10
// Bytes 0..6 = MBAP header, bytes 7..12 = PDU
gw_request[0] := 16#00; // Transaction ID high (any unique)
gw_request[1] := 16#01; // Transaction ID low
gw_request[2] := 16#00; // Protocol ID high
gw_request[3] := 16#00; // Protocol ID low
gw_request[4] := 16#00; // Length high
gw_request[5] := 16#06; // Length low (6 bytes follow)
gw_request[6] := 16#05; // Unit ID = slave 5
gw_request[7] := 16#03; // Function code 03 (Read Holding Regs)
gw_request[8] := 16#00; // Starting address high
gw_request[9] := 16#00; // Starting address low
gw_request[10] := 16#00; // Quantity high
gw_request[11] := 16#0A; // Quantity low (10)
Then feed that buffer to TSEND and parse the response in TRECV. This is significantly more work than MB_CLIENT and is only recommended when the gateway cannot be reconfigured for Unit ID passthrough.
Why SCADA/HMI Worked but MB_CLIENT Did Not
Commercial SCADA packages such as Wonderware InTouch/AVEVA and Weintek cMT HMI have native Modbus drivers that expose a IP:Port:UnitID addressing scheme in the channel configuration (e.g., 192.168.0.10:502:5). The driver builds the ADU with the Unit ID byte set to 5 from the channel definition. MB_CLIENT, by contrast, hard-codes the Unit ID in the instance DB and uses its own connection-management logic. The two systems are not magically different on the wire; the HMI simply makes the Unit ID visible in a way the TIA Portal MB_CLIENT wizard does not.
| Tool | Where Unit ID is set | Default |
|---|---|---|
| MB_CLIENT instance DB | Static tag MB_Unit_ID
|
255 |
| Wonderware Modbus TCP driver | Channel property "Unit ID" | 1 |
| Weintek cMT Modbus gateway | Device address suffix | 1 |
| Modscan32 / Modbus Poll | Connection dialog "Unit ID" | 1 |
Polling Multiple Slaves Through One Gateway
The S7-1200 only allows a limited number of concurrent MB_CLIENT connections (CPU-dependent: S7-1214C supports up to 8 active Modbus TCP connections; S7-1215C supports up to 16). To poll many slaves, you typically:
- Use a single
MB_CLIENTinstance and rotateMB_Unit_ID,DataPtr, andFunctionin a cyclic OB (e.g., OB35 at 100 ms) or in a state machine in OB1. - Maintain a per-slave status word in a global DB so the HMI can see whether each slave is currently responding.
- Respect Modbus RTU turnaround timing: a typical request/response over RS485 at 9600 baud with 10 registers takes 30–80 ms. Cycle the poll list no faster than the worst-case slave.
Troubleshooting Matrix
| Symptom | Likely Root Cause | Remedy |
|---|---|---|
STATUS = 16#80C8 "No response from the partner" |
Gateway not reachable on IP/port | Ping gateway, verify port 502, check firewall |
STATUS = 16#80C9 "Connection lost" |
Gateway rebooted or cable unplugged | Cycle Connect input to re-establish |
STATUS = 16#80D2 "Modbus exception from slave" |
Slave received request but rejected it (illegal address, etc.) | Check Slave_Status_Ex for exception code, verify register map |
All requests time out but Connect=TRUE |
Gateway in server-only mode, not forwarding Unit ID | Enable Unit ID pass-through in gateway config |
| PLC reads its own gateway only, not downstream |
MB_Unit_ID still 255 |
Set MB_Unit_ID to the RTU slave address (1–247) |
| Intermittent failures with CRC errors | RS485 wiring / termination issue | Add 120 Ω terminators, check shield grounding, lower baud |
| Reads return zeros, no error | Wrong starting address or function code | Verify register map; many RTU devices use 1-based addressing |
Verification Checklist
- In TIA Portal's online watch table, force
REQto TRUE for one cycle and confirmDONE=TRUE,ERROR=FALSE,STATUS=0. - Inspect the data buffer in the target DB; values should match the slave's actual register contents (compare with a Modbus scanner on a laptop).
- Toggle the slave's physical output by writing to a coil with FC 05/15 and observe the change in the field.
- From a PC, run Wireshark on the PLC switch port and confirm MBAP Unit ID matches the configured
MB_Unit_ID. - Disconnect the RS485 bus; the next request should return a Modbus exception or timeout, not a stale success.
Field-Proven Tips
- Keep
MB_Unit_IDin a single global DB tag and write it before settingREQ; some engineers have chased phantom bugs for hours becauseREQwas fired before the Unit ID was updated. - If the slave list is dynamic, store it in a UDT array (slave IP, Unit ID, register range) and iterate over it in OB35.
- For deterministic bus traffic, place the MB_CLIENT call in a cyclic interrupt OB (OB30–OB38) rather than OB1 to avoid jitter from the main scan.
- Document the gateway's Unit ID pass-through setting in the project HMI tag comments so the next commissioning engineer does not toggle it off.
Why can my SCADA reach the slaves through the gateway but MB_CLIENT cannot?
SCADA drivers let you specify the Unit ID directly in the channel (e.g., 192.168.0.10:502:5). MB_CLIENT hides the Unit ID inside the instance DB and defaults it to 255. Change the MB_Unit_ID static tag in the MB_CLIENT instance DB to the RTU slave address (1–247) to match what your SCADA is sending.
Do I need TCON/TSEND/TRECV or can I stay with MB_CLIENT?
Use MB_CLIENT whenever the gateway passes the MBAP Unit ID byte through to the serial bus transparently. Switch to TCON/TSEND/TRECV only when the gateway strips or rewrites the Unit ID, because MB_CLIENT has no way to bypass that behavior.
How many slaves can I poll through one MB_CLIENT instance?
There is no hard slave limit; MB_CLIENT sends one request at a time. The practical limit is the connection budget of the CPU (8 connections on S7-1214C, 16 on S7-1215C) and the Modbus RTU turnaround time. Cycle the Unit ID and DataPtr in a cyclic OB to poll many slaves sequentially.
What is the default value of MB_Unit_ID and why does it not work for gateways?
The default is 255 (0xFF), which is the Modbus broadcast address and tells the gateway "route to the serial device at the gateway's own default address". For per-slave addressing you must set MB_Unit_ID to the actual RTU station address (1–247).
What is the difference between a Modbus gateway and a Modbus converter?
A converter gives every serial slave its own IP and MB_CLIENT can poll each one directly. A gateway keeps a single IP and demultiplexes by Unit ID; MB_CLIENT must set MB_Unit_ID to select which slave behind the gateway should answer.