Configuring Modbus RTU on S7-1500 with MB_CLIENT: Complete Guide

David Krause14 min read
SiemensTIA PortalTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

1. Overview: Modbus RTU on S7-1500

Modbus RTU (Remote Terminal Unit) is a serial master/slave protocol used extensively in power conversion equipment, UPS systems, inverters, and protection relays. The S7-1500 CPU family (S7-15xx) supports Modbus RTU through the MB_CLIENT instruction when a serial communication module such as the CM PtP RS422/485 (e.g., 6ES7540-1AB00-0AA0) or a communications processor (e.g., CP 340/341/440/441) is installed in the backplane.

This article documents a working configuration for reading measurement registers (current, alarms, status) and writing multi-register command sequences to a power unit, addressing the most common commissioning error: incorrect MB_MODE selection and address offset handling. The reference target is the Siemens S7-1500 family running TIA Portal V14 SP1 through V20, communicating with a third-party Modbus RTU slave that exposes holding registers in the 4xxxx range.

For the architectural background of Modbus RTU on S7-1500 point-to-point links, refer to the Siemens TIA Portal V20 Modbus RTU configuration overview.

2. Prerequisites

Component Specification
CPU S7-1500 (any variant with PN/DP and PtP-capable backplane slot)
PtP module CM PtP RS422/485 BA (6ES7540-1AB00-0AA0) or CM PtP RS232 (6ES7540-1AD00-0AA0)
Programming environment TIA Portal V14 SP1 minimum; V15-V20 for MB_MODE=103 native addressing
Library Modbus_Comm_Load (V2.x or V3.x) and Modbus_Master / MB_CLIENT (V3.x or V4.x)
Slave device Power unit with Modbus RTU slave, default slave ID, 19200 8N1 typical
Wiring RS485 two-wire (D+/D-) shielded twisted pair, 120 Ω termination at both ends if bus length exceeds 10 m
Critical: Always ground the cable shield at one end only (typically the master/PLC end) to prevent ground loop noise on the RS485 bus. Verify the slave's Modbus address (default 1 in most power units) and baud rate match the MB_DB configuration.

3. The MB_CLIENT Instruction: Parameter Reference

The MB_CLIENT (formerly Modbus_Master in V13) instruction is a single-instance block that sends one Modbus request per rising edge of REQ. All Modbus PDU types are exposed through the MB_MODE parameter.

Input Data type Purpose
REQ BOOL Rising edge triggers transmission
DISCONNECT BOOL TRUE drops the connection after the current job
MB_MODE USINT Modbus function code and addressing mode (see Section 4)
MB_DATA_ADDR UINT Starting register address (mode-dependent interpretation)
MB_DATA_LEN UINT Number of registers/words to transfer (1-125 read, 1-123 write)
MB_DATA_PTR VARIANT Pointer to a data block or tag of matching length
CONNECT BOOL Rising edge establishes the connection on first use
DONE BOOL TRUE on successful completion (one PLC cycle)
BUSY BOOL TRUE while request is in progress
ERROR BOOL TRUE on transmission or slave exception
STATUS WORD Hex error/status code (see Section 7)

4. MB_MODE Selection: The Address Offset Trap

This is the most common commissioning error when reading holding registers. MB_MODE in TIA Portal V14+ is split into two families:

MB_MODE Function Address convention Example for register 2200
0 FC 03 - Read Holding Registers 0-based (register 0 maps to address 0) MB_DATA_ADDR = 2200
1 FC 03 - Read Holding Registers 1-based classic Modicon (register 1 maps to address 0, register 2200 maps to 42199) MB_DATA_ADDR = 42199
103 FC 03 - Read Holding Registers (extended) Native register number (register 2200 maps to 2200) MB_DATA_ADDR = 2200
100 FC 04 - Read Input Registers 0-based MB_DATA_ADDR = 2200
101 FC 04 - Read Input Registers 1-based Modicon MB_DATA_ADDR = 42199
104 FC 04 - Read Input Registers (extended) Native MB_DATA_ADDR = 2200
2 FC 06 - Write Single Register 0-based MB_DATA_ADDR = 8000
5 FC 06 - Write Single Register 1-based MB_DATA_ADDR = 48000
105 FC 06 - Write Single Register (extended) Native MB_DATA_ADDR = 8000
15 FC 16 - Write Multiple Registers 1-based MB_DATA_ADDR = 48000
115 FC 16 - Write Multiple Registers (extended) Native MB_DATA_ADDR = 8000

The original problem report shows MB_MODE = 1 with MB_DATA_ADDR = 2200. With mode 1, the slave will attempt to read holding register 2200 in Modicon convention, which translates to Modbus PDU address 2199. The power unit's actual register 2200 (in user documentation) lives at PDU address 2199, so the correct MB_DATA_ADDR for MB_MODE = 1 is 42199 (offset 40000 + 2199) or simply 42199 if interpreted as 4xxxx addressing.

The cleanest solution on TIA Portal V14 SP1 and later is to use the extended addressing modes (100-115), which accept the register number as written in the slave's documentation. For register 2200 use MB_MODE = 103 with MB_DATA_ADDR = 2200. This eliminates the offset mental load entirely.

Backward compatibility: TIA Portal V13 only supports MB_MODE 0/1/2/3/4/5/6/15. The extended modes (101, 103, 105, 115) require the Modbus library V3.0 or later, which ships with TIA Portal V14 SP1. If the project is locked to V13, either upgrade the library via the global library manager or stick with the 1-based modes and add 40000 manually.

5. Reading UINT16: Current Demand on Phase 1 (Register 2200)

The power unit's register map declares register 2200 as a 16-bit unsigned integer reporting the current demand on phase 1, scaled in 0.1 A per LSB. The following TIA Portal code implements the read cycle at a 1-second cadence using a 1-Hz clock bit.

5.1 Data Block Layout

DATA_BLOCK "DB_Modbus_Phase1"
  STRUCT
    CurrentRaw : UINT;      // Raw register value (0-65535)
    CurrentA   : REAL;      // Scaled value in amperes (CurrentRaw * 0.1)
    Status     : WORD;      // MB_CLIENT STATUS word
    ErrorFlag  : BOOL;      // MB_CLIENT ERROR
    DoneFlag   : BOOL;      // MB_CLIENT DONE
    BusyFlag   : BOOL;      // MB_CLIENT BUSY
  END_STRUCT;
END_DATA_BLOCK

5.2 Cyclic OB1 Read Call

// 1-Hz clock from timer or system clock bit (e.g., "Clock_1Hz")
"MB_Client_DB"(REQ        := "Clock_1Hz" AND NOT "MB_Client_DB".BUSY,
               DISCONNECT := FALSE,
               MB_MODE    := 103,                  // FC 03, extended addressing
               MB_DATA_ADDR := 2200,                // Native register 2200
               MB_DATA_LEN  := 1,                   // 1 register
               MB_DATA_PTR  := "DB_Modbus_Phase1".CurrentRaw,
               CONNECT   := FALSE,                 // Connect only once via init OB
               DONE      => "DB_Modbus_Phase1".DoneFlag,
               BUSY      => "DB_Modbus_Phase1".BusyFlag,
               ERROR     => "DB_Modbus_Phase1".ErrorFlag,
               STATUS    => "DB_Modbus_Phase1".Status);

5.3 Scaling Logic (Cyclic)

// Convert raw 0.1-A LSB to engineering units
IF "DB_Modbus_Phase1".DoneFlag THEN
    "DB_Modbus_Phase1".CurrentA := INT_TO_REAL("DB_Modbus_Phase1".CurrentRaw) * 0.1;
END_IF;

If you must remain on TIA V13 or use the classic MB_MODE 1 family, change MB_MODE := 1 and MB_DATA_ADDR := 42199 (or 42001-40000+2200 = 42200 if the slave uses 1-based user addressing). Always cross-check with the slave vendor's Modbus Register Map PDF — vendor A's "register 2200" is sometimes PDU address 2200 (0-based) and sometimes PDU address 2199 (1-based).

6. Writing a 6-Register Command Sequence (Alarm Reset 8000-8005)

The alarm reset on the referenced power unit requires writing six consecutive holding registers in a single FC 16 (Write Multiple Registers) transaction. The data layout per the source specification is:

Register Value (decimal) Value (hex) Meaning
8000 41096 0xA088 Command code (reset alarms)
8001 10 0x000A Sub-command or parameter
8002 8193 or 8449 0x2001 or 0x2101 IO channel selector (1 or 2)
8003 1 0x0001 Enable flag
8004 13107 ('3') 0x3333 Password high word (ASCII '33')
8005 13107 ('3') 0x3333 Password low word (ASCII '33')

6.1 Build the Payload in a Separate DB

DATA_BLOCK "DB_Reset_Cmd"
  STRUCT
    Word0_Cmd     : UINT := 41096;     // 0xA088
    Word1_Sub     : UINT := 10;        // 0x000A
    Word2_IO      : UINT := 8193;      // IO 1; change to 8449 for IO 2
    Word3_Enable  : UINT := 1;         // 0x0001
    Word4_PwdHi   : UINT := 16#3333;   // ASCII '33' upper
    Word5_PwdLo   : UINT := 16#3333;   // ASCII '33' lower
    Trigger       : BOOL;              // Rising edge triggers write
    Done          : BOOL;
    Busy          : BOOL;
    Error         : BOOL;
    Status        : WORD;
  END_STRUCT;
END_DATA_BLOCK

6.2 FC 16 Write Call with Extended Addressing

// One-shot write triggered by HMI button or alarm-clear logic
"MB_Client_DB"(REQ        := "DB_Reset_Cmd".Trigger AND NOT "DB_Reset_Cmd".Busy,
               DISCONNECT := FALSE,
               MB_MODE    := 115,                   // FC 16, extended addressing
               MB_DATA_ADDR := 8000,                // Native starting register
               MB_DATA_LEN  := 6,                   // Six consecutive registers
               MB_DATA_PTR  := "DB_Reset_Cmd".Word0_Cmd,
               CONNECT      := FALSE,
               DONE      => "DB_Reset_Cmd".Done,
               BUSY      => "DB_Reset_Cmd".Busy,
               ERROR     => "DB_Reset_Cmd".Error,
               STATUS    => "DB_Reset_Cmd".Status);

// Reset trigger after completion (one-cycle pulse)
IF "DB_Reset_Cmd".Done OR "DB_Reset_Cmd".Error THEN
    "DB_Reset_Cmd".Trigger := FALSE;
END_IF;

6.3 If You Are Stuck on TIA V13

Use MB_MODE := 15 (classic FC 16, 1-based) and set MB_DATA_ADDR := 48000 (40000 + 8000). The data pointer still references the same six-word structure. Verify the result by reading the alarm status word back on a subsequent cycle to confirm the slave accepted the command.

Atomicity: FC 16 is treated as a single atomic transaction by the slave. If the PLC loses the connection mid-write, the slave will discard the entire frame. Always poll the DONE flag and re-issue on ERROR if the slave permits retry.

7. STATUS Word Decoding and Error Diagnosis

When ERROR is TRUE, the STATUS output contains either a Modbus exception code (returned by the slave) or a Siemens protocol-stack error (generated locally). Distinguishing the two is critical for correct diagnosis.

STATUS (hex) Source Meaning Corrective action
0x0001 Stack Illegal function code (unsupported FC) Verify the slave supports FC 03/06/16; check MB_MODE mapping
0x0002 Stack Illegal data address (PDU address out of range) Check address offset; verify the register exists in the slave map
0x0003 Stack Illegal data value Inspect payload for out-of-range words (e.g., reserved bit patterns)
0x0006 Stack Slave device busy Increase retry delay; verify the slave is not in a local-mode lockout
0x0007 Stack Negative acknowledge (write protect, password fail) Confirm password bytes in 8004-8005; check write-enable jumper on slave
0x0080 Stack CRC or framing error on receive Check cabling, termination, baud rate, parity (8N1 vs 8E1)
0x0081 Stack Timeout — no response within response timeout Check slave address, bus biasing resistors, supply voltage
0x0082 Stack Inter-character timeout gap violated (RTU framing) Confirm 8N1 and that the slave enforces the 3.5-character silent gap
0x0083 Stack Frame length error (response shorter than expected) Verify MB_DATA_LEN matches the slave's register width (UINT vs ULONG)
0xC091 Local MB_DATA_PTR points to a DB that is not downloaded Recompile and download the referenced DB
0xC092 Local MB_DATA_PTR is NIL or uninitialized Verify the DB exists; reload the instance DB
0xC0B0 Local Connection not established (CONNECT never pulsed) Send a one-shot pulse to the CONNECT input on startup
0xC0B1 Local MB_MODE value not supported in this library version Upgrade library to V3.0+ or change to a legacy mode
0x80C8 Local Library version mismatch (MB_CLIENT vs MB_COMM_LOAD) Use matched library versions; clear the reference DB and reinsert

For a deeper discussion of the specific error originally observed in the source — MB_MODE = 1 with MB_DATA_ADDR = 2200 producing an immediate error — see the Siemens support entry 83130159 on Modbus addressing modes. The document 100633819 further details the offset behavior of the MB_CLIENT instruction across TIA Portal versions.

8. TIA Portal Version Compatibility Matrix

MB_MODE range
TIA Portal version Library Recommended for this application
V13 SP1 / V13 SP2 Modbus_Comm_Load V2.0 / Modbus_Master V2.0 0-15 only Use MB_MODE 1 + offset 42199 / MB_MODE 15 + offset 48000
V14 SP1 / V14 SP2 Modbus_Comm_Load V3.0 / Modbus_Master V3.0 0-115 Use MB_MODE 103 / 115 (extended)
V15 / V15.1 / V16 Modbus_Comm_Load V4.0 / Modbus_Master V4.0 0-115 Same as V14; F-library bug fixes
V17 / V18 / V19 / V20 Modbus_Comm_Load V5.0+ / Modbus_Master V5.0+ 0-115 Same; full CPU 1505/1518 redundancy support
Migration warning: When porting a working V13 project to V14+, the system sometimes retains the legacy Modbus_Master name but the mode mapping is unchanged. If you replace the F-block with the newer MB_CLIENT, the mode numbers will not shift — only the addressing convention remains your responsibility.

9. Hardware Configuration of the CM PtP

  1. In the device view of the S7-1500 station, drag the CM PtP RS422/485 module into the configured slot.
  2. Open the module properties and select RS485 as the interface mode (not RS422 — the power unit is two-wire).
  3. Set the protocol to Modbus master (RTU) — this auto-fills the MB_COMM_LOAD parameters with 8 data bits, no parity, 1 stop bit, and the user-selected baud rate.
  4. Assign a hardware identifier (e.g., HW_ID = 269) — this is the value used by the HW_ID input of MB_COMM_LOAD.
  5. Wire D+ to terminal T/R+ and D- to terminal T/R-. Activate the internal 120 Ω termination on the module DIP switch if the slave is the last node on the bus and no external terminator is fitted.

10. MB_COMM_LOAD Configuration (One-Shot in OB100)

// OB100 — startup; pulse CONNECT once after CPU restart
"MB_Comm_Load_DB"(REQ       := TRUE,
                  PORT      := "CM_PtP".Configuration,
                  BAUD      := 19200,
                  PARITY    := 0,        // 0=none, 1=odd, 2=even
                  FLOW_CTRL := 0,        // 0=none (RS485 half-duplex)
                  RTS_ON_DLY := 0,
                  RTS_OFF_DLY := 0,
                  RESP_TO   := 1000,     // 1000 ms response timeout
                  DONE      => "StartFlag_DB".MbCommLoadDone,
                  ERROR     => "StartFlag_DB".MbCommLoadError,
                  STATUS    => "StartFlag_DB".MbCommLoadStatus);

11. Verification and Commissioning Checklist

Step Test Pass criterion
1 Connect a Modbus RTU sniffer (e.g., on a laptop with a USB-RS485 adapter) in parallel to the bus Sniffer captures the exact bytes the PLC is sending
2 Power up the slave, verify it answers poll requests even before the PLC is connected Sniffer shows valid response frames
3 Start the PLC program, watch MB_COMM_LOAD.DONE DONE pulses TRUE on the first scan
4 Trigger a single read of register 2200, observe STATUS STATUS = 0 and CurrentRaw updates each cycle
5 Apply a known load on phase 1 (e.g., 12.3 A) and compare to the scaled reading Reading matches 12.3 A ±0.1 A (one LSB)
6 Trigger the 6-register write to 8000-8005 with the password STATUS = 0, slave acknowledges, alarm flags clear on the next read cycle
7 Disconnect the cable mid-transaction and observe error handling ERROR pulses TRUE, STATUS = 0x0081 (timeout), BUSY clears, no CPU stop
8 Hot-swap the slave (cycle power) and confirm automatic reconnection First read after reconnection succeeds within two cycles

12. Troubleshooting Matrix

Symptom Most likely cause First check
ERROR pulses on every read, STATUS = 0xC0B0 CONNECT never pulsed Add a one-shot on first OB100 cycle
ERROR with STATUS = 0x0002 Address out of range (mode/offset mismatch) Switch to MB_MODE = 103 and use native register numbers
ERROR with STATUS = 0x0007 Password bytes in 8004-8005 are wrong or out of order Swap high/low word; verify ASCII '33' = 0x33 per byte
ERROR with STATUS = 0x0081 Slave address mismatch or wrong baud Verify slave ID matches MB_DB.MB_ADDR; check parity and baud in MB_COMM_LOAD
ERROR with STATUS = 0x0080 Electrical noise or missing termination Add 120 Ω at both ends; shield grounded at PLC end only
ERROR with STATUS = 0xC0B1 MB_MODE not supported in this library version Upgrade Modbus library to V3.0+ or fall back to mode 1/15
Reads work, writes return 0x0003 Reserved bits in the command word set to 1 Mask the command to the exact value the slave manual specifies (e.g., 0xA088 not 0xA088|0x0100)
Intermittent timeouts during heavy HMI traffic CPU scan time exceeds inter-frame gap Reduce OB1 priority, raise the cyclic interrupt OB for the read call
Safety note: Alarm reset writes to a power unit can clear latched fault conditions. Implement password gating, write-arm interlocks, and an HMI confirmation step before issuing the FC 16 command. A spurious write during a fault event may mask a real overcurrent or ground fault.

13. Performance and Timing Notes

At 19200 baud, a single FC 03 read of one register is approximately 12-15 ms round trip on a clean bus. A six-register FC 16 write is approximately 20-25 ms. Polling a single 1-Hz register consumes negligible CPU time. If you scale up to 50+ registers, switch to a higher baud (38400 or 115200) and consider using a single FC 03 read with MB_DATA_LEN = 50 instead of 50 single-register reads — this cuts the overhead per register from ~5 ms to ~0.4 ms.

14. FAQ

What is the correct MB_MODE for reading holding register 2200 on TIA Portal V14?

Use MB_MODE = 103 with MB_DATA_ADDR = 2200. Mode 103 is the extended FC 03 (Read Holding Registers) that accepts the native register number as written in the slave documentation, removing the need for the 40000 offset that mode 1 requires.

Why does my read fail immediately with MB_MODE=1 and MB_DATA_ADDR=2200?

Mode 1 uses 1-based Modicon addressing, so register 2200 in user documentation maps to PDU address 2199. The correct value is MB_DATA_ADDR = 42199 (offset 40000 + 2199). The STATUS word will typically return 0x0002 (illegal data address) until the offset is corrected.

How do I write six consecutive registers (8000-8005) in one transaction?

Use MB_MODE = 115 (extended FC 16) with MB_DATA_ADDR = 8000 and MB_DATA_LEN = 6. Point MB_DATA_PTR to a DB containing six consecutive UINT words matching the data layout the slave expects. On TIA V13 use MB_MODE = 15 and MB_DATA_ADDR = 48000.

What is the difference between MB_CLIENT and Modbus_Master?

They are functionally identical. Starting with TIA Portal V14, the block was renamed to MB_CLIENT to align with the new MB_SERVER instruction. The input/output parameter set is unchanged. Projects compiled under V13 retain the legacy Modbus_Master name in the program blocks view.

How do I diagnose a STATUS word value of 0xC0B0?

This means the Modbus connection has not been established. Pulse the CONNECT input of MB_CLIENT with a rising edge in the startup OB (OB100) before the first read or write request. The MB_COMM_LOAD block must also report DONE = TRUE with STATUS = 0 for the connection to be active.

Can I use MB_CLIENT on the S7-1500 CPU's onboard RS485 port?

The S7-1500 CPU does not have an onboard serial port. You must add a CM PtP (6ES7540-1AB00-0AA0) or a CP (340/341/440/441) module. The hardware identifier of that module is passed to the HW_ID input of MB_COMM_LOAD.

Back to blog