1. Problem Overview
When commissioning a Siemens S7-1200 or S7-1500 PLC as a Modbus TCP server, integrators frequently need to expose multiple data blocks (DBs) to a single client or to several masters. The intuitive approach is to call the MB_SERVER instruction twice from OB1 (one call per data block) and change the ID input parameter on each instance DB to a different value, expecting the client to select the target DB by transmitting a matching Unit ID (also called Slave ID or Station Address) in the Modbus Application Protocol (MBAP) header.
Symptom: only the first MB_SERVER instance executed in the cyclic OB responds. Swapping the call order causes the second instance to respond instead. Changing the ID parameter at runtime has no effect on which DB is read.
ID input on the Modbus TCP library instructions for S7-1200/S7-1500 identifies the local TCP connection descriptor, not the Modbus Unit ID. This is the root cause of the routing confusion.2. Root Cause: MB_SERVER ID Parameter Behavior
The MB_SERVER block (FB 1172 / FB 1800 depending on firmware generation, called from the MODBUS / MODBUS_TCP program block library) uses the ID parameter as a reference into the local connection database managed by the Open Communication (Open User Communication / TCON) layer of the CPU. The connection descriptor couples a passive socket to the instance DB that owns the Modbus data registers.
| Parameter | Intended Role | Misconception |
|---|---|---|
ID |
Local handle for the TCON/TSEND/TRECV connection description on the PLC | Often mistaken for the Modbus Unit ID broadcast in MBAP header |
UNIT_ID |
Optional filter inside MB_SERVER (available in firmware updates from V4.2 of the Modbus TCP library for S7-1200 and V2.0 for S7-1500) | Used to validate the slave address field of incoming requests; does NOT route to different instance DBs |
PORT |
Local TCP port the server listens on (default 502) | Correct discriminator when multiple MB_SERVER instances must coexist |
When two MB_SERVER instances share the same port and same instance DB type, only the first instance registered with the Open Communication runtime wins the listen socket. Subsequent calls either fail to bind or remain dormant. The MBAP Unit ID is forwarded to the active instance and cannot steer the request to a sibling instance because that sibling never receives the TCP stream.
3. Architecture: Single-Port vs Multi-Port Modbus TCP
The Modbus TCP specification reserves port 502 for the well-known service, but it permits any additional TCP port for parallel servers. The MBAP header is identical across all ports, so a client that opens a connection to 192.168.0.10:503 sees the same protocol framing as a connection to 192.168.0.10:502.
| Topology | Local Ports | Use Case | CPU Resource Impact |
|---|---|---|---|
| Single-port, single MB_SERVER | 502 | One DB exposed to one or many clients | Lowest; one passive socket |
| Single-port, multiple MB_SERVER (Unit ID filtering) | 502 | DB selection inside one instance based on Unit ID | Moderate; one socket, larger DB map |
| Multi-port, multiple MB_SERVER (port routing) | 502, 503, 504, 505... | Isolated DBs per logical server, simple client configuration | Linear; N passive sockets for N DB groups |
4. Solution: Multi-Port Instance DB Configuration
The proven resolution is to assign a unique TCP port to each MB_SERVER instance DB. The client then opens separate sockets per logical data block. This mirrors the multi-port gateway pattern documented for inter-vendor Modbus integration where each master terminates on its own port.
4.1 Recommended Port Allocation
- Port 502 - DB1, default Modbus TCP service, primary register map
- Port 503 - DB2, diagnostic or secondary register map
- Port 504 - DB3, floating-point process values
- Port 505 - DB4, configuration / recipe data
- Above port 1024, use unregistered ephemeral ports if the firewall policy permits
4.2 Why Port Routing Beats Unit ID Filtering
- No firmware-version dependency on Unit ID handling inside
MB_SERVER. - Each instance owns a dedicated register map (typically a 1:1 image of a DB), simplifying the human-readable data layout.
- Clients can be scoped by port, making security segmentation (firewall ACLs per port) straightforward.
- Disconnection of one client does not stall reads against the other DBs.
5. TIA Portal Implementation Steps
5.1 Prerequisites
- TIA Portal V15.1 or later (V17 / V18 recommended for current Modbus TCP library).
- S7-1200 firmware V4.2 or later, or S7-1500 firmware V2.0 or later.
- "Modbus TCP" program blocks from the global library, located under Instructions > Communication > MODBUS TCP.
- CPU with sufficient Open User Communication resources for the chosen number of passive ports.
5.2 Step-by-Step Configuration
-
Add MB_SERVER instructions. In OB1, drag four
MB_SERVERblocks. TIA Portal auto-generates instance DBs (DB1172, DB1173, ...). Rename them descriptively:iDB_Modbus_DB1,iDB_Modbus_DB2,iDB_Modbus_DB3,iDB_Modbus_DB4. -
Set the static connection parameters. Open each instance DB and populate the
CONNECTparameter with the local port and connection ID. Two adjacent instance DBs must never share bothIDandPORT.// iDB_Modbus_DB1 CONNECT := TCON_IP_v4 { // TCON_IP_v4 UDT from "PLC data types" InterfaceId := 64 // 64 = PROFINET IO [X1] Id := 1 ConnectionType := 16#0B // 0x0B = TCP passive (server) ActiveEstablished := FALSE RemoteAddress := '' // accept any client RemotePort := 0 LocalPort := 502 LocalTsapId := '' } // iDB_Modbus_DB2 - identical except: Id := 2 LocalPort := 503 -
Wire the register pointer. Each instance DB exposes
MB_HOLD_REG(holding registers input),MB_DATA_PTR(typed pointer to the source DB), and length parameters. SetMB_DATA_PTRto point at the matching data DB, e.g.P#DB10.DBX0.0 WORD 100for DB1. -
Assign the client-side parameters on each call of MB_SERVER:
// Call 1 MB_SERVER_DB1( ID := 1, MB_DATA_PTR := P#DB10.DBX0.0 WORD 100, MB_HOLD_REG := ... , NDR := ... , DR := ... , ERROR := ... , STATUS := ... , CONNECT := "iConn_DB1" ); // Call 2 MB_SERVER_DB2( ID := 2, MB_DATA_PTR := P#DB20.DBX0.0 WORD 100, ... CONNECT := "iConn_DB2" ); - Compile and download. TIA Portal will issue warnings if the connection parameters overlap. Resolve every warning before going online.
-
Verify the listen sockets. Open the online & diagnostics view of the CPU and navigate to Communication > Open User Communication > Active connections. Confirm four
LISTENentries on ports 502-505 with stateESTABLISHEDonly when a client is connected.
6. MB_CLIENT Master Configuration
The master side must establish one TCP session per target DB. In TIA Portal this is achieved with one MB_CLIENT instance per port. The CONNECT parameter of MB_CLIENT points to a different connection description whose ActiveEstablished flag is set to TRUE and whose RemotePort matches the server's local port.
// Master side, S7-1500 talking to four S7-1200 server DBs
MB_CLIENT_1(
REQ := bTrigger1,
ID := 100,
MB_MODE := 1, // 1 = read holding registers
MB_DATA_ADDR := 40001, // Modbus address 0 = register 40001
MB_DATA_LEN := 100,
DONE := bDone1,
BUSY := bBusy1,
ERROR := bErr1,
STATUS := wStatus1,
MB_DATA_PTR := P#DB200.DBX0.0 WORD 100,
CONNECT := "iMasterConn_DB1"
);
Each MB_CLIENT blocks while the transaction is in flight. To prevent collisions when polling all four DBs, schedule the triggers in mutually exclusive time slices using an IEC timer cascade:
// Staggered polling every 100 ms total cycle
IF bPollSlot1 THEN
bTrigger1 := TRUE;
bPollSlot1 := FALSE;
bPollSlot2 := TRUE;
ELSIF bPollSlot2 THEN ...
ELSIF bPollSlot3 THEN ...
ELSIF bPollSlot4 THEN ...
bPollSlot1 := TRUE;
END_IF;
7. Connection Diagnostics & Verification
7.1 STATUS / ERROR Codes from MB_SERVER
| STATUS (hex) | Meaning | Corrective Action |
|---|---|---|
| 16#0000 | No error, no active connection | Normal idle state |
| 16#0001 | Connection established, data exchange active | Healthy runtime state |
| 16#7001 | Connection establishment in progress | Wait; transient after client connect |
| 16#7002 | Data exchange in progress | Normal during Modbus transaction |
| 16#80C8 | No resources available for the requested connection | Reduce number of Open User Communication connections or upgrade CPU |
| 16#80C9 | Connection ID already in use | Each instance DB must have a unique ID value |
| 16#8187 | Invalid CONNECT parameter | Re-enter the TCON_IP_v4 UDT, verify interface selection |
| 16#80A1 | TCP listen port conflict | Two instances share LocalPort; assign unique ports |
| 16#80B1 | Connection aborted by client | Investigate client watchdog or network drop |
7.2 Field Verification Procedure
- Open TIA Portal online view; force
MB_SERVERon each instance DB to showDISCONNECT=0 andNDR=1 after a successful read. - Use
netstat -anon the engineering station or a PC on the same subnet; verify four ESTABLISHED entries pointing at ports 502-505 of the CPU IP. - Send a Modbus poll from a generic tool such as
mbpollor a vendor test utility. Example:mbpoll -m tcp -a 1 -r 1 -c 10 -p 502 192.168.0.10should read holding registers from DB1 only. - Switch the port to 503:
mbpoll -m tcp -a 1 -r 1 -c 10 -p 503 192.168.0.10must return the data set published by DB2. - Capture a Wireshark trace filtered by
tcp.port == 502 || tcp.port == 503 || tcp.port == 504 || tcp.port == 505and confirm the MBAP Transaction ID, Protocol ID 0x0000, and Unit ID fields are correctly formed.
8. Edge Cases & Limitations
8.1 Firewall and NAT Traversal
Industrial firewalls frequently close ports above 1023 unless explicitly allowed. Stay within the registered range (502, 503, 504, 505, 506) where the deployment policy permits, or request formal rule changes for higher ports.
8.2 CPU Firmware Compatibility
The legacy Modbus library shipped with S7-1200 firmware V4.0 lacked the Unit ID filtering feature entirely. Older CPUs that cannot be upgraded must rely exclusively on port routing. S7-1500 firmware V2.5 and later support the extended MODBUS_TCP library with improved connection management.
8.3 Performance Considerations
Each passive socket consumes memory in the CPU's communication stack. Four ports increase the per-scan evaluation overhead marginally but do not affect cyclic OB execution time beyond a few microseconds. The dominant cost is on the wire and in the client polling logic, not on the server.
8.4 Multi-Master Scenarios
Two clients reading the same server port can coexist because MB_SERVER accepts multiple incoming TCP connections on the same listen socket (up to the configured "MaxConnections" inside the connection UDT). For full isolation - for instance when one master must not see another master's traffic - assign a dedicated port per master or use a managed multi-port gateway that bridges legacy serial Modbus devices into isolated TCP sessions per master, as described in the multi-master Modbus TCP gateway architecture.
8.5 Watchdog Behaviour
If the client application crashes, the TCP socket eventually closes via the OS keepalive mechanism (default 2 hours on Windows). To accelerate detection on the PLC side, set the MB_KEEPALIVE or enable the CPU-level TCP keepalive interval (TIA Portal > PLC properties > Communication > TCP keepalive).
9. S7-1500 vs S7-1200 Considerations
| Feature | S7-1200 (CPU 1215C/1217C) | S7-1500 (CPU 1515/1516) |
|---|---|---|
| Max Open User Communication connections | 16 (CPU 1217C) | 128 (CPU 1516) |
| Modbus TCP library version | V4.x (firmware >= V4.2) | V2.x and V3.x (firmware >= V2.0) |
| Unit ID filtering inside MB_SERVER | Optional via MB_DATA_PTR mapping | Optional via dedicated parameter |
| Diagnostic block visibility | Limited; use STATUS codes | Native in TIA Portal online diagnostics |
| Recommended port range | 502-509 for compact installations | 502-5103 for large SCADA rollouts |
10. Frequently Asked Questions
Why does changing the MB_SERVER ID parameter not let me read a second data block?
The ID is a local handle that binds the Modbus server to a specific Open User Communication (TCON) connection on the PLC. It is not the Modbus Unit ID sent in the MBAP header. To expose a second DB you must give each MB_SERVER instance its own local TCP port (for example 502 and 503) so that each one owns a distinct listen socket.
Can multiple masters read the same Modbus TCP port on the S7-1200?
Yes. A single MB_SERVER listen socket accepts up to the configured number of simultaneous TCP connections. Increase the MaxConnections field inside the CONNECT UDT if your application needs more than one master per port. For full traffic isolation between masters, assign a unique port per master instead.
How many MB_SERVER instances can a single S7-1500 CPU run?
The practical limit is the CPU's Open User Communication budget. CPU 1515 supports 96 connections, CPU 1516 supports up to 128. Each MB_SERVER reserves at least one passive socket; an active MB_CLIENT also counts. Plan the topology against the published connection count in the S7-1500 system manual before commissioning.
Does MB_SERVER support Unit ID filtering to select between data blocks?
Firmware V4.2 of the Modbus TCP library for S7-1200 and V2.0 for S7-1500 introduced the ability to read the Unit ID from the MBAP header and forward it to user code, but it does not automatically route the request to a different instance DB. Port routing remains the recommended approach for multi-DB access.
What STATUS code indicates a TCP port conflict between MB_SERVER instances?
STATUS = 16#80A1 on the second instance means the listen socket could not bind because another instruction already owns the local port. Change the LocalPort of the second instance to a free value (503 or higher) and recompile. STATUS = 16#80C9 indicates the connection ID is duplicated; assign unique ID values alongside unique ports.