Configuring Modbus TCP on S7-1500: TIA Portal V12+ Technical Reference
This reference covers the engineering, commissioning, and field-troubleshooting of Modbus TCP communications on the S7-1500 family using the native MB_CLIENT and MB_SERVER instructions in the TIA Portal. The focus is on programmed connections using the TCON_IP_V4 data structure, the most common variant in field deployments, with explicit attention to hardware identifier selection, the MB_DATA_PTR pointer rules, and the most common STATUS error codes reported in commissioning (809B, 818B, 8086, 80C8, and others).
The native Modbus TCP instructions were introduced for the S7-1500 in TIA Portal V12 SP1 (released via the firmware/support download at Siemens Industry Online Support) and have been refined in subsequent releases. The configuration mechanism is similar on the S7-1200, but the S7-1500 has the additional advantage of being simulated with PLCSIM Advanced, which simplifies bench validation before deployment to a real CPU.
MB_MASTER/MB_SLAVE on the S7-1500 serial interface) and uses a different data flow.
1. Prerequisites and Compatibility
| Item | Requirement | Notes |
|---|---|---|
| CPU firmware | S7-1500 firmware V1.5 or higher (recommended V2.0+) | MB_CLIENT/MB_SERVER were added in the V12 SP1 timeframe; later firmware adds extended diagnostics. |
| TIA Portal | V12 SP1 minimum, V13 SP2 / V15 / V16 / V17 for current projects | Optimized block access is the default for S7-1500 from V13 onward. |
| Library | "ModbusTCP" or instruction library containing MB_CLIENT, MB_SERVER, TCON, TDISCON, TSEND, TRCV
|
Provided with TIA Portal installation under the standard instructions. |
| Ethernet interface | PROFINET port of the S7-1500 CPU or a CP 1543-1 (e.g., 6GK7543-1AX00-0XE0) | Interface must be configured with a valid IP address and subnet. |
| Port | TCP 502 (standard) or any free TCP port for non-standard servers | Reserved port 502 is the default Modbus TCP port. |
| Functional license | None for native MB_CLIENT/MB_SERVER on S7-1500 | The legacy "ModbusTCP" library may require a license depending on version. |
2. Connection Architecture: TCON_Configured vs Programmed TCON_IP_V4
The S7-1500 supports two distinct ways to define a Modbus TCP connection.
2.1 Configured Connection (TCON_Configured)
The connection is established in the TIA Portal "Devices & Networks" editor under "Connections". The TIA Portal generates a connection DB that holds a TCON_Configured structure. This approach is preferred when:
- The peer IP and port are static and known at design time.
- The same connection is used by multiple program blocks.
- You want automatic download of connection parameters with the hardware configuration.
2.2 Programmed Connection (TCON_IP_V4)
The connection parameters live in a user data block that contains a variable of system data type TCON_IP_V4. This approach is preferred when:
- The peer IP/port is dynamic (computed at runtime, e.g., a recipes-driven IP).
- You need to spin up many connections (one per peer) from a single FB.
- You want to keep all connection metadata in the user program rather than the hardware config.
Both approaches consume the same CPU connection resources and behave identically at runtime as far as the Modbus instructions are concerned. The block's CONNECT input accepts either variant.
TCON_IP_V4 DB is to drop a TSEND_C instruction in the program, open the block properties, click "Configuration" on the connection, then click "Apply". TIA Portal will create the connection DB with the correct structure. You can then delete the TSEND_C call and its instance DB and reuse the generated connection DB for the MB_CLIENT / MB_SERVER instruction.
3. Building a TCON_IP_V4 Data Block
Manual creation is straightforward:
- Add a new global DB (e.g.,
Client_Send_DB). - In the DB, add a new variable, name it
Connection. - In the "Data type" column, type
TCON_IP_V4literally. The type browser will not show it — it must be entered by hand. - Fill the structure fields per the table below.
| Field | Client Value | Server Value | Description |
|---|---|---|---|
InterfaceId |
Hardware ID of the PROFINET interface or CP port (decimal) | Locate in Device View > Properties > System constants. See Section 9. | |
ID |
1, 2, 3 ... (must be unique per CPU project) | Local connection resource ID; ties TCON/TDISCON to the same session. | |
ConnectionType |
16#0B (TCP/IP) for IPv4 |
Use 0B for standard Modbus TCP. | |
ActiveEstablished |
TRUE |
FALSE |
Client initiates the connection; server listens. |
RemoteAddress (ADDR array) |
Server IP, e.g. 192.168.0.10
|
Any / all-zeros | For the server, set ADDR[1..4] = 0 to accept any remote IP. |
RemotePort |
502 (or the server's port) | 0 | For the server, 0 accepts any port; many use 502 explicitly. |
LocalPort |
0 (any) or a specific port | 502 (or a non-standard port for multi-port servers) | Server must specify a concrete port; 502 is the standard. |
4. Configuring MB_CLIENT (Modbus Client Role)
MB_CLIENT is called cyclically (typically every OB1 cycle) and is edge-sensitive on REQ. Each rising edge on REQ triggers one Modbus transaction.
4.1 Inputs
| Input | Data Type | Meaning | Typical Use |
|---|---|---|---|
REQ |
BOOL | Trigger a new transaction on rising edge | From sequencer or pulse timer. |
DISCONNECT |
BOOL | Drop the TCP connection | Used for session control. |
MB_MODE |
USINT | 0 = read, 1 = write | Select per transaction. |
MB_DATA_ADDR |
UINT | Starting Modbus address | 0 for coils, 1 for discrete inputs, etc. |
MB_DATA_LEN |
UINT | Number of elements | 1..125 for FC01/02/03/04; 1..123 for FC15/16. |
MB_DATA_PTR |
VARIANT | Pointer to data buffer | See Section 7. |
CONNECT |
VARIANT | Pointer to TCON_xxx DB | Either a configured connection or a TCON_IP_V4 DB. |
MB_UNIT_ID |
USINT | Modbus Unit Identifier (server) | Default 16#FF; some slaves require 0. |
4.2 Outputs
| Output | Data Type | Meaning |
|---|---|---|
DONE |
BOOL | Last transaction completed without error |
BUSY |
BOOL | Transaction in progress |
ERROR |
BOOL | Last transaction ended in error (see STATUS) |
STATUS |
WORD | Detailed error/status code |
MB_DATA_PTR |
VARIANT | Echoes the input pointer (used as in-out) |
4.3 Function Code Mapping
MB_MODE |
Read/Write | FC | Data Type | Modbus Area |
|---|---|---|---|---|
| 0 | Read | 01 | BOOL array (bit) | Coils (0x) |
| 0 | Read | 02 | BOOL array (bit) | Discrete Inputs (1x) |
| 0 | Read | 03 | WORD / INT / REAL / DWORD / DINT | Holding Registers (4x) |
| 0 | Read | 04 | WORD / INT / REAL / DWORD / DINT | Input Registers (3x) |
| 1 | Write | 05 | Single BOOL | Single coil |
| 1 | Write | 06 | Single register | Single holding register |
| 1 | Write | 15 | BOOL array | Multiple coils |
| 1 | Write | 16 | WORD / INT / REAL array | Multiple holding registers |
REQ from a sequencer (e.g., a 200 ms timer) rather than BUSY in a tight loop. Re-asserting REQ while BUSY = TRUE is ignored and is a common cause of "stuck" sessions in the field.
5. Configuring MB_SERVER (Modbus Server Role)
MB_SERVER is a passive listener. It does not require a REQ edge. Internally it calls TCON/TRCV/TSEND/TDISCON based on the connection state machine.
5.1 Critical Configuration Rules
- Set
ActiveEstablished = FALSEin the TCON_IP_V4. - Set
RemotePort = 0to accept any client port, or set a specific value to filter. - Set
RemoteAddressto all-zeros ([0,0,0,0]) for any-client, or to a specific client IP for one-client-only. - Specify a
LocalPort(typically 502). A singleMB_SERVERinstance is bound to a single port.
5.2 Multiple Clients on a Single CPU
To accept multiple simultaneous clients, instantiate one MB_SERVER call (with its own connection DB and instance DB) per port. See Section 11 for a worked example with port 502 and 503.
6. MB_DATA_PTR: Pointer Formats and Data Types
The MB_DATA_PTR accepts two addressing modes on the S7-1500.
6.1 Absolute Pointer (S7-300/400 Style)
Use a fully qualified pointer in the M area or in a non-optimized DB:
P#M0.0 BYTE 100 // 100 bytes starting at MB0
P#DB10.DBX0.0 BYTE 200 // 200 bytes in DB10 (any structure allowed)
This form is mandatory when the data block has standard (non-optimized) access. The DB itself may contain any data type structure.
6.2 Symbolic Pointer (Optimized Block)
For optimized DBs (default for S7-1500), pass a tag of an array of WORD or INT (registers) or an array of BOOL (bits):
"Data".HoldingReg[0..9] // array of INT, 10 elements, FC03 read
"Data".Coils[0..31] // array of BOOL, 32 elements, FC01 read
"Data".InputReg[0..4] // array of INT, FC04 read
STRUCT directly to MB_DATA_PTR can produce STATUS = 818B ("The MB_DATA_PTR parameter has an invalid pointer"). Workaround: use an explicit array of INT or WORD, or pass a pointer to the first element of the struct. This issue is documented in field reports on early TIA Portal V13 SP2 builds with S7-1516 CPUs at firmware V1.1.2.
7. ID Parameters: CONNECT ID vs MB_Unit_ID
Two distinct identifiers are in play. Confusing them is one of the most common setup errors.
| Parameter | Scope | Default | When to change |
|---|---|---|---|
ID (in TCON_IP_V4) |
Local CPU connection resource | 1, 2, 3 ... | Always set to a unique number across all open connections in the project. The same ID must be used in any matching TDISCON/TSEND/TRCV calls. |
MB_UNIT_ID (in MB_CLIENT) |
Modbus Unit Identifier on the wire (server-side routing) |
16#FF (255) |
Keep 255 when the remote server is a direct TCP peer. Set to 0 (or 1..247) for Modbus gateways or specific slaves that reject FF. |
MB_UNIT_ID = 16#FF. Initialize the input to 0 for any traffic destined for that gateway's downstream RTU slaves.
8. Hardware Identifier (InterfaceId) Configuration
The InterfaceId in TCON_IP_V4 is the hardware identifier of the interface, not of the module. On a CP 1543-1, the module itself and each of its ports (X1, X2) have separate identifiers in TIA Portal.
| Hardware Element | Typical Hardware ID | Used For |
|---|---|---|
| CP 1543-1 module | 259 (example) | Module diagnostics, not TCON |
| CP 1543-1 Port X1 | 260 (example) | Use this value in InterfaceId
|
| CPU PROFINET interface (PN/IE) | 64 (varies) | Use this if the cable is plugged into the CPU port |
| CPU Port[X1 P1 R] | 65 (example for S7-1516-3 PN/DP) | Use this when communicating via the CPU's X1 port |
8.1 Locating the Correct Hardware ID
- Open the Device View of the CPU/CP.
- Select the port to which the Ethernet cable is physically attached.
- Open Properties → System constants.
- Note the value next to "Hardware identifier" — that is the
InterfaceId.
8.2 Common Interface ID Errors
- Using the module ID (e.g., 259) instead of the port ID (e.g., 260) →
809B. - Using a value below 64 (default CPU interface) when traffic is going through a CP →
809B. - Using a value above 64 that is not a valid hardware identifier →
8086(ID out of range) or80C8(resource problem).
9. Error Code Reference and Diagnostics
The STATUS output of MB_CLIENT and MB_SERVER returns hex codes drawn from the TCON instruction set and Modbus specification.
| STATUS (hex) | Source | Meaning | Field-Proven Fix |
|---|---|---|---|
7000 |
MB_xxx | No active transaction (idle) | Informational. Wait for REQ edge. |
7001 |
MB_xxx | First call, establishing connection | Normal. Wait. |
7002 |
MB_xxx | Connection establishing, request denied (DISCONNECT was on) | Drop DISCONNECT = FALSE. |
8000 |
MB_xxx | Connection being terminated | Normal teardown. |
8086 |
TCON | "The ID parameter is outside the valid range." | Set ID to a small integer (1, 2, 3, ...). Used wrong field — ensure ID is in TCON_IP_V4, not MB_Unit_ID. |
809B |
TCON | "The element InterfaceId within the TCON_xxx structure does not reference a hardware identifier of a CPU or CM/CP interface or has the value 0." | Pick the port (X1/X2) hardware ID, not the module ID. See Section 8. |
80C3 |
TCON | All connection resources in use | Reduce concurrent open connections; check for orphaned TCON calls. |
80C4 |
TCON | Temporary resource problem | Retry; if persistent, check CPU connection limits in the manual. |
818B |
MB_xxx | "The MB_DATA_PTR parameter has an invalid pointer." | Replace a STRUCT with an array of WORD/INT or use an absolute P# pointer. See Section 6. |
818C |
MB_xxx | "The MB_DATA_LEN parameter is 0 or greater than the maximum allowed value." | Hold to range: 1..125 for FC01/02/03/04; 1..123 for FC15/16. |
80A8 |
TCP | Connection partner terminated | Verify server is running and reachable. |
80A1 / 80A2
|
TCP | Connection establishment failed / rejected | Check IP, port, firewall, server ActiveEstablished. |
80Cx range while REQ is being toggled faster than the transaction can complete, the CPU is being asked to allocate more connection resources than are available. Insert a BUSY-gated one-shot so REQ cannot rise while BUSY = TRUE.
10. Multi-Port Server: Supporting Multiple Modbus TCP Clients
A single MB_SERVER instance is bound to one local port. To accept N simultaneous clients, instantiate N MB_SERVER blocks, each with:
- Its own connection DB (different
LocalPort). - Its own instance DB.
- Its own data buffer tags (use the same symbolic tags if the same data must be exposed to all clients).
10.1 Example: Two Servers on Ports 502 and 503
| Block | Connection DB | LocalPort | ActiveEstablished | RemotePort |
|---|---|---|---|---|
MB_Server_1 |
Server_502_DB |
502 | FALSE | 0 |
MB_Server_2 |
Server_503_DB |
503 | FALSE | 0 |
Both blocks must be called in OB1. Each will accept the first client that connects to its port. The data tags in user memory (e.g., "Modbus".HoldingReg) can be shared symbolically across both blocks.
MB_SERVER calls is the most common cause of "only one client can connect at a time" behavior. Each block needs its own pair of DBs.
11. Vendor Interoperability Notes
| Vendor / Device | Specific Behavior | Workaround |
|---|---|---|
| Schneider NOC0402 (Ethernet→Modbus RTU gateway) | Rejects MB_Unit_ID = 16#FF
|
Initialize MB_Unit_ID = 0 in the MB_CLIENT instance DB. |
| Moxa MGate (Modbus TCP gateways) | Default Unit ID is 1 for downstream RTU | Set MB_Unit_ID = 1 (or whatever the gateway is configured to forward). |
| Wago 750-352 / 750-375 | Expects Unit ID 1 by default | Set MB_Unit_ID = 1. |
| Generic Modbus TCP servers | Most ignore Unit ID | Leave default 16#FF. |
| Siemens SIMOCODE / SIRIUS 3RW55 / 3VA molded case | Standard Modbus TCP on port 502 | No adjustment; follow general rules. |
12. Verification and Commissioning Checklist
Use this sequence on first power-up of any S7-1500 Modbus TCP link.
-
Network reachability. From a laptop on the same subnet,
pingthe CPU's PROFINET IP. Confirm the port LED on the CP/CPU is lit. -
Watch table test. Force
MB_CLIENT.REQ = TRUEfor a read of FC03 from address 0, length 1. ObserveDONEgoing high and the data inMB_DATA_PTRupdating. -
Server visibility. From a Modbus client tool (e.g.,
mbpollon Linux, "Modbus Tools" on Windows), poll the CPU's IP on port 502. Confirm that the data is mirrored inMB_SERVER's configured tags. -
STATUS inspection. While the link is idle, observe
STATUS = 7000(client) or7000(server). A non-zero STATUS that does not match the table in Section 9 indicates a configuration error. -
Disconnect / reconnect. Pull the Ethernet cable at the remote end. Confirm
STATUSmoves to80A8or similar, then recovers to7000when the cable is reinserted. -
Multi-client stress. Connect two clients on ports 502 and 503. Verify both
MB_SERVERinstances reportSTATUS = 7000and respond to polls. - Throughput check. With FC03 reads at 100 ms cadence, confirm the cycle time impact on OB1 is < 5 ms on a typical S7-1516.
13. Frequently Asked Questions
What STATUS means "MB_DATA_PTR has an invalid pointer" on the S7-1500?
STATUS = 818B is reported when MB_DATA_PTR is passed a STRUCT or any tag that is not a flat array of WORD/INT/REAL/BOOL or an absolute P# pointer. Replace the tag with an array or with P#DBx.DBXy.z BYTE n.
How do I find the correct InterfaceId for a CP 1543-1?
In TIA Portal Device View, click the port X1 (not the module). Open Properties → System constants and read the Hardware identifier. The CP module ID and the port ID are different values — using the module ID produces STATUS 809B.
Can the S7-1500 act as a Modbus TCP server for multiple clients at the same time?
Yes, but each client must connect on a different local port. Instantiate one MB_SERVER block per port (e.g., 502 and 503), each with its own connection DB and instance DB. The CPU permits up to 64 concurrent Modbus TCP connections on a single PROFINET interface, depending on firmware.
Why does a Schneider NOC0402 drop my Modbus TCP requests?
The Schneider NOC0402 ignores Modbus TCP requests with MB_Unit_ID = 16#FF (the S7-1500 default). Change the MB_Unit_ID input on the MB_CLIENT instance to 0 for that gateway.
What is the difference between the ID in TCON_IP_V4 and MB_Unit_ID?
The ID field in TCON_IP_V4 is a local CPU connection resource identifier — it must be unique per project and links the connection to the TCON state machine. MB_Unit_ID is a Modbus protocol field (the Unit Identifier on the wire) used for server-side routing on gateways. They are unrelated and have different defaults (1+ and 16#FF respectively).
References and Documentation
- Siemens Industry Online Support: Modbus/TCP with instructions MB_CLIENT and MB_SERVER (sample project) — net_modbus_tcp_s7-1500_s7-1200_en.pdf
- Siemens Industry Online Support entry 76276623 — STEP 7 V12 SP1 release notes / S7-1500 firmware
- S7-1500 Communication Function Manuals (S7-1500, ET 200MP communication) — S7-1500 Communication Function Manual on Siemens Industry Online Support