← Resources
Networking·11 min read·

MB_CLIENT in TIA Portal: Modbus TCP setup and STATUS codes

Set up MB_CLIENT on an S7-1200 or S7-1500: the connection, MB_MODE and addressing, polling several blocks, and what every STATUS code means and how to fix it.

By the LADX engineering team

Short answer

MB_CLIENT makes an S7-1200 or S7-1500 a Modbus TCP client. Give it a TCON_IP_v4 connection with a unique ID, the server's IP address and port 502, set MB_MODE, MB_DATA_ADDR and MB_DATA_LEN, and point MB_DATA_PTR at a buffer. STATUS 7000 to 7006 is progress, 80C8 means the server never answered, and 8381 to 8385 cover the server's exception replies.

MB_CLIENT progress codes 7000, 7001, 7002, 7004, 7005, 7006 and 0000 in order, with connection errors such as 80A3 and 80C6 branching from 7002, 80C8 and 8381 to 8385 branching from 7006, and parameter errors 8188 to 818D, 80B6, 80BB and 8200 shown apart
Reading the MB_CLIENT STATUS word

MB_CLIENT turns an S7-1200 or S7-1500 CPU into a Modbus TCP client. It opens the connection, sends the request, waits for the reply and reports through DONE, BUSY, ERROR and a 16-bit STATUS word. Most commissioning time goes on that word, so most of this article is about reading it.

Everything here follows Siemens' TIA Portal V21 documentation for the Modbus TCP library from V4.0, which the S7-1500 and current S7-1200 CPUs use; Siemens notes that an S7-1200 with firmware V4.0 is limited to library V3.1. If Modbus itself is new, Modbus explained covers the register areas and the 40001 numbering used below.

Before you start

Collect the server's IP address and port (502 unless its manual says otherwise), a connection ID from 1 to 4095 that nothing else in the CPU uses, and, for a device behind a TCP to serial gateway, its serial address. Above all, get the register map: addresses, whether they count from 0 or 1, data types and the word order of 32-bit values. Write it into an I/O list with the numbering convention stated.

COM18. ModbusTCP Client via Siemens S7-1200/S7-1500 PLC and TIA Portal, from Electrical Automation Hands-OnPrivacyWatch on YouTube

The parameters

ParameterTypeWhat it does
REQBool, inputLevel-controlled: while TRUE, requests are sent. Changed inputs take effect only after the reply or an error
DISCONNECTBool, input0 establishes the connection; 1 closes it, and STATUS shows 0003 when closed
MB_MODEUSInt, inputRead, write or diagnostics, or a direct function code
MB_DATA_ADDRUDInt, inputStart address; its meaning depends on MB_MODE
MB_DATA_LENUInt, inputNumber of bits or registers
MB_DATA_PTRVariant, in-outThe buffer read into or written from
CONNECTVariant, in-outThe connection description, usually TCON_IP_v4
DONE, BUSY, ERRORBool, outputsJob finished without error; job in progress (not while connecting); error in STATUS
STATUSWord, outputDetailed status, in the tables below

Editable Static tags in the instance DB that matter on site:

Static tagStart valueMeaning
RCV_TIMEOUT2.0 sHow long to wait for a reply; 0.5 to 55 s
RETRIES0Send attempts made before 80C8 is reported
Blocked_Proc_Timeout3.0 sWait before a blocked instance is released; 0.5 to 55 s
MB_Unit_ID255Unit identifier; selects the serial device behind a gateway
MB_Transaction_ID1Change only if the server needs another value
Connected01 while connected

The connection: TCON_IP_v4

Create one TCON_IP_v4 structure per MB_CLIENT instance, normally in a global DB:

FieldSet it toNotes
InterfaceIdThe hardware identifier of the local interface0 to 65535. TCON reports 809B for a wrong value
ID1 to 4095Unique for each MB_CLIENT instance
ConnectionType11TCP. Anything else gives 80B6
ActiveEstablishedTRUEThe client opens the connection. FALSE gives 80BB
RemoteAddressThe server's IP, for example 192, 168, 0, 20Array[1..4] of Byte
RemotePort5021 to 49151
LocalPort00 means any local port

Siemens forbids the local TCP ports 20, 21, 25, 80, 102, 123, 5001, 34962, 34963 and 34964. Migrating from library V2.1, CONNECT_ID becomes ID, IP_PORT becomes RemotePort and the IP_OCTET parameters become RemoteAddress; moving from any version before V4.0 also means replacing the Open User Communication library.

MB_MODE and the address

Modes 0, 1 and 2 use the traditional numbering, from which MB_CLIENT works out the function code and the zero-based remote address. Modes 101 to 116 name the function and send the address as given.

To do thisMB_MODEMB_DATA_ADDRMB_DATA_LENFunction
Read coils01 to 9,9991 to 2,00001
Read discrete inputs010,001 to 19,9991 to 2,00002
Read holding registers040,001 to 49,999 or 400,001 to 465,5351 to 12503
Read input registers030,001 to 39,9991 to 12504
Write one coil11 to 9,999105
Write one holding register140,001 to 49,999 or 400,001 to 465,535106
Write several coils11 to 9,9992 to 1,96815
Write several holding registers140,001 to 49,999 or 400,001 to 465,5352 to 12316
Always use 15 or 16, even for one value2As for mode 1From 115 or 16
Name the function directly101 to 106, 115, 1160 to 65,535As for that functionThe last two digits
Read and write in one job, V6.0 and later123Not usedNot used23

A worked example. A meter's manual lists a value at holding register 40101, two registers long. MB_MODE 0, MB_DATA_ADDR 40101, MB_DATA_LEN 2 sends function 03 for remote address 100, because 40001 maps to remote address 0. The same request in direct mode is MB_MODE 103, MB_DATA_ADDR 100. If the manual already numbers from zero, use the direct modes so nobody subtracts one twice.

MB_MODE 2 always sends the multiple-write functions. A server that only implements 06 answers that with exception 01, reported as 8381; use mode 1 or 106 for single registers on such devices.

The data buffer

In a global DB with optimised access, MB_DATA_PTR can point to one elementary tag or an array of elementary types such as Word, Int, DInt or Real. In bit memory or a standard-access DB it can also point to a PLC data type, using an ANY pointer such as P#M1000.0 WORD 500 for memory. A 32-bit value arrives as two registers; if a REAL reads as nonsense, suspect the word order (Modbus explained covers it, and PLC data types the types).

A working call

One read of ten holding registers in SCL. Siemens' rules for parameter lists allow any order, and expressions as actual parameters.

scl
// "Meter" is a global DB holding Conn : TCON_IP_v4 and Regs : Array[0..9] of Word
"Meter_Client_DB"(REQ := "Meter".Poll,
                  DISCONNECT := FALSE,
                  MB_MODE := 103,          // read holding registers, direct address
                  MB_DATA_ADDR := 100,
                  MB_DATA_LEN := 10,
                  DONE => "Meter".Done,
                  BUSY => "Meter".Busy,
                  ERROR => "Meter".Error,
                  STATUS => "Meter".Status,
                  MB_DATA_PTR := "Meter".Regs,
                  CONNECT := "Meter".Conn);

IF "Meter".Error THEN
  "Meter".LastError := "Meter".Status;   // keep it for the HMI
END_IF;

Copy STATUS into your own tag, as Siemens' examples do; it changes with the next call.

Polling several register blocks

One instance can serve several requests on one connection. Siemens' rules: the same instance DB, connection ID and port; one request at a time, in an order your program sets; and no input changes while a request runs. Another instance with the same connection parameters sending while the first is busy gets 8200. Separate servers each need their own instance DB, connection ID and IP address.

A step pattern, each call with its own result tags:

scl
// Step 0: read 10 registers from 100. Step 1: write 2 registers at 200.
"Meter_Client_DB"(REQ := #Step = 0, DISCONNECT := FALSE,
                  MB_MODE := 103, MB_DATA_ADDR := 100, MB_DATA_LEN := 10,
                  DONE => #Done0, ERROR => #Error0, STATUS => #Status0,
                  MB_DATA_PTR := "Meter".ReadRegs, CONNECT := "Meter".Conn);
IF #Step = 0 AND (#Done0 OR #Error0) THEN
  IF #Error0 THEN
    "Meter".ReadStatus := #Status0;
  END_IF;
  #Step := 1;
END_IF;

"Meter_Client_DB"(REQ := #Step = 1, DISCONNECT := FALSE,
                  MB_MODE := 116, MB_DATA_ADDR := 200, MB_DATA_LEN := 2,
                  DONE => #Done1, ERROR => #Error1, STATUS => #Status1,
                  MB_DATA_PTR := "Meter".WriteRegs, CONNECT := "Meter".Conn);
IF #Step = 1 AND (#Done1 OR #Error1) THEN
  IF #Error1 THEN
    "Meter".WriteStatus := #Status1;
  END_IF;
  #Step := 0;
END_IF;

STATUS: progress codes

These come with ERROR = 0. They are not faults; they say how far the current request got.

STATUSSiemens' meaningOn site
0000Executed without errorsData in the buffer, or the write accepted
0001Connection established
0003Connection terminatedExpected after DISCONNECT = 1
7000No job active and no connection (REQ = 0, DISCONNECT = 1)Idle
7001Connection establishment triggered
7002Intermediate call: connection being establishedStuck here: the TCP connection never completes. IP address, subnet, port, cabling, or a server refusing another client
7003Connection being terminatedAlso appears just before a communication error is reported
7004Connected and monitored, no job activeHealthy, with REQ off
7005Data being sent
7006Data being receivedStuck here: the request went out and nothing came back. Ends in 80C8

STATUS: protocol errors

These come with ERROR = 1. Several are the server's exception reply, translated: the second column gives the Modbus exception for the remote case, and Modbus exception codes explains each.

STATUSExceptionSiemens' meaningWhat to check
80C8noneNo response within the set time, after the configured retries; also when replies keep arriving with the wrong transaction IDReachability, the unit ID behind a gateway, RCV_TIMEOUT for slow gateways
8380noneReceived frame has the wrong format or is too shortThe device's protocol on this port
838101Function code not supportedUse a function the device lists, such as 106 rather than 116 for one register
838203Remote: invalid length. Local: length, byte count, start address or word count in the reply does not match the requestMB_DATA_LEN against the device's limits
838302Remote: outside the server's address area. Local: outside the MB_DATA_PTR bufferRegister numbering and block length; buffer size
838403Remote: invalid data value for function 5. Local: invalid exception code, a changed echo (functions 5, 6, 8) or an invalid status (function 11)The device's handling of single writes
838503Diagnostics code not supported (function 8)The device's diagnostic functions
8386noneFunction code in the reply does not match the requestAnother client or a gateway answering out of turn
8387noneProtocol ID in the received frame is not 0That the device speaks Modbus TCP
8388noneDifferent data length returned (functions 5, 6, 15, 16)The device's write limits

STATUS: parameter errors

Also ERROR = 1, and all are fixed in the call, not on the network.

STATUSSiemens' meaningFix
80B6Invalid connection type: only TCPConnectionType 11
80BBInvalid ActiveEstablishedTRUE for a client
8188Invalid MB_MODEA value from the mode table
8189Invalid MB_DATA_ADDR (or RD_ and WR_ addresses from V6.0)An address inside the mode's range
818AInvalid MB_DATA_LEN (or RD_ and WR_ lengths from V6.0)The function's limits, such as 125 registers per read
818BInvalid pointer at MB_DATA_PTR; check address and length tooBuffer type and size
818CBLOCKED_PROC_TIMEOUT or RCV_TIMEOUT outside 0.5 to 55 sCorrect the Static tags
818DParameters the function does not use are not at their defaultsZero RD_ and WR_ unless MB_MODE is 123; with 123, zero MB_DATA_ADDR and MB_DATA_LEN and leave MB_DATA_PTR empty
8200Another MB_CLIENT instance with the same connection parameters is processing a requestSequence the requests

STATUS: connection codes from TCON and TDISCON

MB_CLIENT uses TCON, TDISCON, TSEND, TRCV, T_DIAG and TRESET internally, and Siemens says their error codes can appear too; each one's own STATUS sits in the Static section of the instance DB. After 80C4, 80C5 or 80A1 while sending or receiving, the connection is ended, so 7003 shows first and the cause once it has closed. Meanings from Siemens' TCON and TDISCON references:

STATUSMeaningWhat to check
809BInterfaceId does not reference an interface of the CPU or a CM/CPThe hardware identifier in TCON_IP_v4
80A1The connection or the local port is already in useA unique ID; LocalPort 0
80A3TCON: ID already used by a user-program connection with the same description. TDISCON: closing a connection that does not exist or is already closedOne ID and one TCON_IP_v4 per instance
80A4Remote IP address invalid or equal to the local oneRemoteAddress
80B7Remote port 0 for active TCP, or partner IP 0.0.0.0RemotePort and RemoteAddress
80C4Temporary: cannot connect now, firewall ports closed, interface being reconfiguredRetry; firewalls on the path
80C5The partner refused or closed the connectionThe server's client limit or IP filtering
80C6The partner cannot be reached (network error)Cabling, switch, subnet, routing

One overlap: TCON's own table uses 80C8 for an ID already used by a connection with different settings. At MB_CLIENT's STATUS output, 80C8 means no reply; inside the TCON status in the instance DB, it means the ID clash.

A commissioning order that saves time

  1. Prove the server from a PC first with any Modbus TCP test client, using the same IP address, port, unit ID and register. If that fails, the PLC will too.
  2. Start with one register: MB_MODE 103, MB_DATA_LEN 1. Set REQ and watch STATUS run 7001, 7002, 7005, 7006 and 0000 with DONE.
  3. Stuck at 7002 is a connection problem: read the TCON code. Stuck at 7006 and ending in 80C8 is a server that is not answering the Modbus request: unit ID, timeout or transaction ID.
  4. 8381 to 8385 means the server answered and refused. Fix the request, not the network.
  5. Then scale up, log STATUS on error for the HMI, and add the Modbus test to the commissioning checklist. For intermittent faults, follow a troubleshooting method rather than swapping parameters.

Sources and further reading

Common questions

What is the difference between MB_CLIENT and MB_SERVER?
MB_CLIENT makes the CPU the side that asks: it connects to a Modbus TCP server and sends requests. MB_SERVER makes it the side that answers, serving the data block or bit memory area set at MB_HOLD_REG. Siemens warns that every connected client can then read and write that area and the process image.
Why does MB_CLIENT stay on STATUS 7002?
7002 means the connection is still being established, so the TCP connection to the server never completes. Check the server's IP address and port, that the two devices can reach each other's subnet, that nothing blocks port 502, and that the server will accept another client. The underlying TCON code, such as 80C6, narrows it down.
How many MB_CLIENT connections can one CPU handle?
Siemens does not give one figure: the limit is the CPU's maximum number of connections, and Modbus TCP client and server connections all count towards it. Check the connection resources in your CPU's technical data. Each separate server needs its own MB_CLIENT instance DB, its own connection ID and its own IP address.
Can MB_CLIENT read a Modbus RTU device through a gateway?
Yes. Address the gateway's IP address and port, and put the serial device's address in the MB_Unit_ID static tag of the MB_CLIENT instance DB, which starts at 255. A gateway that cannot reach the device either replies with exception 0A or 0B or stays silent, and silence ends in STATUS 80C8.
Does MB_CLIENT support Modbus function 23?
Yes, from instruction version V6.0. Set MB_MODE to 123 and use the RD_ and WR_ parameters for the read and write addresses, lengths and buffers, leaving MB_DATA_ADDR, MB_DATA_LEN and MB_DATA_PTR at their defaults. If any unused parameter is not at its default, the instruction returns STATUS 818D.

Keep reading