Problem Overview
Engineers commissioning a SIMATIC S7-1200 CPU (firmware V4.0 or higher) as a Modbus TCP client frequently report that the MB_CLIENT instruction freezes, returns error code 0x0001 (protocol error) or stays in BUSY=1 indefinitely when the Modbus Unit ID of the target server is 0. The most common case in the field is a Schneider Electric Altivar Process ATV630 / ATV660 / ATV680 / ATV6xx drive, which is shipped with Modbus Unit ID (a.k.a. Slave Address) = 0 in its COMM menu, and the user mistakenly believes this value cannot be changed.
The real cause is a conceptual collision between two distinct identifiers:
-
MB_CLIENT Connection ID – a local, in-PLC reference number (Word, range
1..65535in modern TIA Portal versions, historically1..4095) used to differentiate multiple active TCP connections inside the S7-1200 program. -
Modbus Unit Identifier (formerly Slave Address, MBAP field) – the protocol-level address of the target device on the Modbus bus, range
0..247for serial,0..255for Modbus TCP (only0..247have a defined meaning in the Modbus Application Protocol Specification).
These two IDs are independent. A valid MB_CLIENT configuration must supply both, and Unit ID = 0 is perfectly valid for Modbus TCP because the MBAP Unit Identifier is largely used to identify a sub-device on a serial segment behind a Modbus TCP/Modbus RTU gateway – on a pure Modbus TCP link, the value is ignored or echoed back by IP-addressed devices.
Root Cause: ID Confusion, Not Protocol Limitation
According to the Siemens SIMATIC S7-1200 Programmable Controller – Communication Processor and Modbus TCP manual (entry ID 109741593), “each MB_CLIENT connection must assign a unique connection ID; unique IP port numbers may or may not be required depending upon the server configuration.” The ID input on the FB is therefore a project-scoped reference, not a Modbus protocol field. It is the symbolic handle you give to the connection in your user program and in the instance DB.
The MB_UNIT_ID input on the same block is the value placed into the Modbus Application Protocol (MBAP) header, byte 6, and reaches the target drive. If the ATV630 is configured to ignore Unit ID (the AdIP = 0 default on Ethernet) it will still answer the request. Therefore the perceived freeze at ID = 0 is almost always caused by one of the following:
- The drive is not in Modbus TCP mode – the embedded Ethernet port is still set to
Ethernet IPor is in a state where it does not open port 502. - The drive IP address / subnet does not match the S7-1200 interface, so the TCP open succeeds with a 3-second timeout and the block sits in
WAIT_FOR_CONNECTION. - The Unit ID of the drive has been changed by the user (e.g.
1) but theMB_UNIT_IDinput on the FB was left at0, or vice-versa. - The user wrote
0to the FB'sIDinput (a connection ID) and the SCL/ST compile accepts it but the runtime rejects it becauseID = 0is reserved as “no connection”.
0 is invalid for MB_CLIENT. Always use IDs 1..4095 (TIA V13/14) or 1..65535 (TIA V15.1+). The same ID must not be used on a second MB_CLIENT instance with the same connection parameters.Technical Details: MB_CLIENT Inputs
The following parameter map is from the SIMATIC S7-1200 manual collection – MB_CLIENT instruction:
| Input | Type | Range / Meaning |
|---|---|---|
REQ |
Bool | Rising edge triggers a single Modbus transaction |
ID |
Word / UInt | Local connection reference, 1..4095 (V13/14) or 1..65535 (V15.1+). NOT transmitted on the wire. |
CONNECT |
TCON_IP_v4 | PLC-side IP, server IP, port 502, connection mode = 11 (TCP, ISO-on-TCP not used) |
MB_MODE |
USInt | 0 = Read, 1 = Write, 2 = Write-Read, 3..6 = diagnostics |
MB_DATA_ADDR |
UInt | Modbus starting register (0..65535). For ATV630 Holding registers add 1 if address list is 0-based. |
MB_DATA_LEN |
UInt | Word count: 1..125 for FC03, 1..100 for FC16, etc. |
MB_UNIT_ID |
USInt / Byte | Modbus Unit Identifier (MBAP field). 0..255. Sent over Ethernet. |
DATA_PTR |
Variant | Pointer to standard DB or M area, byte aligned to MB_DATA_LEN*2 |
Solution: Correct ID Configuration for S7-1200 → ATV630
To read data from an ATV630 (firmware ≥ V1.6 for full Modbus TCP support) on an S7-1200 (CPU 1214C DC/DC/DC, firmware V4.4 used for this example) carry out the steps below.
Prerequisites
- ATV630 with embedded Ethernet port (or VW3A3600 module). Modbus TCP enabled in
Menu > Communication > Ethernet > Protocol– must showModbus TCP, notEtherNet/IP. - Drive's IP address known (default
192.168.1.4), subnet mask255.255.255.0. - S7-1200 CPU with at least one PROFINET interface configured, firmware V4.0 or higher (T-CONNECT block requires V4.0).
- TIA Portal V16 or higher, with “S7-1200 Motion / Communication blocks” installed.
Step 1 – Enable Modbus TCP on the ATV630
- Power up the drive, enter the main menu with the jog wheel.
- Navigate:
5 - COMMUNICATION > 1 - Ethernet > 1 - Protocol– selectModbus TCP. - Navigate:
5 - COMMUNICATION > 1 - Ethernet > 3 - Modbus Unit ID– set to any value1..247. The default0is legal for Modbus TCP but most installation guides (including the Schneider Altivar Process 630 Modbus manual EAV64300) recommend1to mirror the serial line. - Confirm with
OKand cycle control power if prompted.
Step 2 – Create the Connection DB in TIA Portal
Create a global DB named MB_Atv630_Conn with the following structure (matches the TCON_IP_v4 UDT):
DATA_BLOCK "MB_Atv630_Conn"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
STRUCT
InterfaceId : HW_ANY := 64; // 64 = PN interface of CPU
Id : WORD := 1; // TCON connection ID 1
ConnectionType : BYTE := 16#0B; // 11 = TCP native
ActiveEstablished : BOOL := TRUE; // client is active
RemoteAddress : IP_V4 := 192.168.1.4; // ATV630 IP
RemotePort : UINT := 502;
LocalPort : UINT := 0; // 0 = any
END_STRUCT;
END_DATA_BLOCK
Step 3 – Instantiate MB_CLIENT and Poll Holding Registers
The next network reads 8 words from the ATV630 (status word, output frequency, motor current, motor torque, drive thermal state, DC bus voltage, drive state, last fault code). The standard Modbus address range used in the ATV630 Modbus manual (EAV64300) is:
| Modbus Register (Word) | Symbol | Description | Access |
|---|---|---|---|
| 3201 | ETA |
Status word (ETI / ETA) | R |
| 3202 | RFRD |
Output speed (rpm) | R |
| 3203 | FRHD |
Output frequency (0.1 Hz) | R |
| 3204 | IHR |
Motor current (0.1 A) | R |
| 3205 | OTR |
Motor torque (% of nominal) | R |
| 3209 | ETAT |
Drive state code | R |
| 3241 | LCOD |
Last fault code | R |
| 8501 | CMD |
Control word (CMD) | R/W |
| 8502 | LFRD |
Speed reference (rpm) | R/W |
| 8601 | FR1 |
Acceleration ramp (0.1 s) | R/W |
Note: ATV630 manual registers are written as logical addresses starting at 1. The Modbus protocol uses zero-based addressing, so the S7-1200 must use the value minus one: 3201 - 1 = 3200. The above is the Siemens convention used in their official Modbus TCP example projects.
// SCL example – one-shot poll, period 100 ms via cyclic OB1
IF "Clock_100ms" AND NOT "MB_CLIENT_DB".BUSY AND NOT "MB_CLIENT_DB".ERROR THEN
"MB_CLIENT_DB".REQ := TRUE;
"MB_CLIENT_DB".ID := 1; // local connection ID, NOT the Modbus Unit ID
"MB_CLIENT_DB".CONNECT := "MB_Atv630_Conn";
"MB_CLIENT_DB".MB_MODE := 0; // 0 = FC03 Read Holding
"MB_CLIENT_DB".MB_DATA_ADDR := 3200; // register 3201 (Status Word) - 1
"MB_CLIENT_DB".MB_DATA_LEN := 8; // 8 words = 16 bytes
"MB_CLIENT_DB".MB_UNIT_ID := 1; // matches ATV630 Unit ID
"MB_CLIENT_DB".DATA_PTR := P#DB100.DBX0.0 BYTE 16;
// DATA_PTR points to 16 bytes; 8 words will be returned.
ELSE
"MB_CLIENT_DB".REQ := FALSE;
END_IF;
Map the read words from DB100 symbolically in the user program. For example DB100.DBW0 = ETA (Status Word), DB100.DBW2 = RFRD (output speed in rpm), etc.
Step 4 – Verify the Connection
- Compile and download the project to the CPU.
- Open Online & Diagnostics > Watch table on
DB100– within 100 ms the values should start to update. - Read
MB_CLIENT_DB.STATUS and compare to the Siemens error code table:
| STATUS (hex) | Meaning | Action |
|---|---|---|
| 0x0000 | Idle – ready for next request | None |
| 0x7000 | Waiting for activation (no REQ edge) | Trigger REQ |
| 0x7001 | Processing request (BUSY=1) | Wait |
| 0x7002 | Received response, doing internal copy | Wait |
| 0x0001 / 0x8380 | TCP connection error – no listener on port 502 | Check ATV630 protocol selection |
| 0x0002 / 0x80C8 | Modbus exception 02 (Illegal Data Address) | Verify MB_DATA_ADDR; may be read-only |
| 0x0003 / 0x80C9 | Modbus exception 03 (Illegal Data Value) | Reduce MB_DATA_LEN or check end of range |
| 0x80D2 | Timeout (3 s default) | Subnet, IP, firewall, drive state |
Troubleshooting Matrix
| Symptom | Root Cause | Fix |
|---|---|---|
| FB never returns from BUSY; STATUS = 0x7000 | ID = 0 entered on FB, connection not created | Set ID to a value in 1..4095 (V14) or 1..65535 (V15.1+) |
| STATUS = 0x80D2 timeout | Drive is in EtherNet/IP mode, port 502 closed |
Set drive protocol to Modbus TCP; cycle power |
| STATUS = 0x0001 / 0x8380 | Wrong RemoteAddress or wrong LocalPort collision | Use 0 for LocalPort; verify IP with ping from CPU webserver |
| DATA_PTR shows zeros but STATUS = 0x0000 | Optimized access mismatch – DATA_PTR points to non-optimized area while DB is optimized | Make target DB non-optimized or use AT-view |
| All reads return Modbus exception 02 | ATV630 firmware uses 1-based register list; program uses raw protocol address | Subtract 1 from the manual address |
| Block works on first scan, then ERROR=1 forever | REQ remains TRUE – new transaction started before previous one finished | Reset REQ after DONE; poll cyclically with one-shot edge |
| PLC sees drive but drive IP not reachable from HMI | Different VLAN or router between PLC and HMI | Use managed switch; allow TCP/502 between subnets |
| ATV630 reports CFF2 (Modbus Interruption) on its HMI | Modbus timeout shorter than PLC scan | Raise ATV630 Modbus Timeout to ≥ 1.0 s in Communication menu |
Why Connection ID 1..4095 Is Mandatory
The S7-1200 firmware uses the ID field of the TCON_IP_v4 UDT as a key into the internal connection management table (CMT). The CMT has 16 (V13/14) or up to 64 (V15.1+) entries. Each MB_CLIENT instance must reserve one of these entries, and the reservation is identified by the ID you write into the TCON_IP_v4 structure. ID = 0 is treated internally as “free slot” and the FB rejects it. Two FB instances using the same ID will silently override each other – you will see responses intended for FB1 delivered to FB2, with the classic symptom of “sometimes works, sometimes freezes”.
Best practice: assign IDs in a project-wide constant block (e.g. MBID_ATV630 := 1, MBID_PM5000 := 2, …) to prevent duplicates. This is also the recommendation in the Siemens FAQ 109741593.
Advanced: Polling Multiple ATV630 Drives
For more than one drive on the same subnet, instantiate one MB_CLIENT per drive, each with:
- Its own
ID(1, 2, 3, …) - Its own
DATA_PTRto a per-drive DB - Its own
TCON_IP_v4(or shared if you wish to reconnect dynamically, but a permanent per-drive connection is recommended) - Its own
MB_UNIT_IDmatching the slave address configured in the drive
Drive the REQ inputs from a sequencer FB (e.g. a 100-ms cyclic time-slice scheduler) to avoid concurrent transactions. Trying to fire more than one MB_CLIENT with the same ID while BUSY=1 returns STATUS = 0x7001 with no effect.
Cross-Vendor Notes
The same code pattern works against any Modbus TCP server: Schneider PowerLogic PM5000, ABB M4M, Eaton Power Xpert, ABB ACH580 drives, Danfoss FC 302, etc. Adjust the MB_DATA_ADDR and the unit ID according to the vendor manual. The Schneider PowerLogic PM5000 register map is published in the PowerLogic PM5000 series user manual; ABB drives follow the Common Industrial Protocol Drive Profile (CiA 402) – registers 0x2000 (control) and 0x2001 (speed reference) for ABB ACH580 in Modbus TCP mode.
Safety and Commissioning Caveats
Control Source must be set to Network and the Freq. Ref. Source to Modbus. Forcing an enabled drive to start with a stray 0x0006 (Decelerate + Enable) or 0x0007 (Run) command is a known cause of unexpected motion. Wire the drive's STO (Safe Torque Off) inputs and prove them before live commands. Drive manuals (EAV64300) explicitly require category-1/2 stop verification when Modbus is the control source.During commissioning, force the control word (CMD, register 8501) to 0x0000 and the speed reference (LFRD, register 8502) to 0 until the wire-up is verified. Use Trace on the drive to log ETA (status word) – a value of 0x0237 (Ready, Run command, Quick stop inactive, No fault) confirms a healthy handshake.
Verification Checklist
-
MB_CLIENT_DB.BUSYtoggles to0within 100 ms ofREQ := TRUE. -
MB_CLIENT_DB.DONEis1for one scan after each successful transaction. -
MB_CLIENT_DB.ERRORstays0for ≥ 1000 transactions. - DB100 first word (ETA) is non-zero when the drive is in
Readystate (typical0x0637). - DB100 second word (RFRD) updates within 200 ms when the drive is started via the local HMI.
- Disconnect the Ethernet cable – STATUS =
0x80D2after 3 s, ERROR = 1, then re-connects within 10 s when the cable is plugged back in.
FAQ
Is MB_CLIENT Connection ID the same as the Modbus slave address?
No. The ID input on the S7-1200 MB_CLIENT FB is a local handle used by the PLC's connection manager (range 1..4095 or 1..65535 depending on TIA Portal version). The Modbus Unit ID / slave address is set via MB_UNIT_ID (range 0..255) and is placed in the Modbus Application Protocol header on the wire.
Can MB_CLIENT read from a Modbus device with Unit ID 0?
Yes, Unit ID 0 is valid for Modbus TCP. The Schneider ATV630 default of 0 is supported, but you can also set the drive Unit ID to any value 1..247 from the HMI menu COMM > Ethernet > Modbus Unit ID. The S7-1200 MB_UNIT_ID must match the drive setting.
Why does my MB_CLIENT stay BUSY forever and never return an error?
Three typical reasons: (1) the drive is not in Modbus TCP mode (port 502 is closed), (2) the drive IP address is unreachable – check with a ping from the CPU's webserver, (3) the Connection ID is shared with another MB_CLIENT instance. STATUS will remain 0x7001 until the internal 3-second TCP retransmit triggers STATUS = 0x80D2.
Do I need to subtract 1 from the ATV630 register address shown in the manual?
Yes, in most TIA Portal examples the Modbus register 3201 (Status Word ETA) is written as 3200 in MB_DATA_ADDR because the protocol is zero-based. The Schneider Modbus manual EAV64300 shows the manual numbers in 1-based form to match their legacy serial-line convention.
Which MB_CLIENT firmware is required on the S7-1200?
CPU firmware V4.0 or higher. The Modbus TCP instruction library shipped with TIA Portal V13 SP1 / V14 onwards is the recommended path. The S7-1200 firmware must be upgraded if the FB is not visible in the Instructions pane. For the older library the MB_CLIENT V2.2 is the stable release; in TIA V15.1+ use the V4.0 instruction block with extended connection ID range.