S7-1200 Modbus RTU Master: Sequencing 5 Slaves with MB_MASTER

David Krause14 min read
S7-1200SiemensTutorial / 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

S7-1200 Modbus RTU Master: Sequencing 5 Slaves with MB_MASTER

Overview

A SIMATIC S7-1200 CPU1214C acting as a Modbus RTU master can poll up to 247 slave addresses on a single RS485 segment, but the on-board firmware MB_MASTER instruction handles only one outstanding request at a time per PtP (point-to-point) port. To exchange data with five slaves (three read-only, one write-only, one read/write) you must implement a sequencer that arbitrates the shared port, fires each transaction when its turn comes up, and processes the DONE/ERROR outputs of every MB_MASTER instance.

This reference walks through the hardware, the TIA Portal configuration of the MB_COMM_LOAD and MB_MASTER instructions, the sequencer state machine, sample SCL code, diagnostics, and a troubleshooting matrix for the most common fault codes (STATUS = 0x0001 through 0x80C8).

Prerequisites

  • S7-1200 CPU1214C with firmware V4.0 or higher (CPU 1214C DC/DC/DC or DC/DC/Rly; order number 6ES7214-1AG40-0XB0 or later).
  • Communications module CM 1241 RS485 (6ES7241-1CH30-1XB0) or CB 1241 RS485 (6ES7241-1CH31-0XB0) plugged into the left bus of the CPU.
  • TIA Portal V15.1 or later with the SIMATIC S7-1200 Communication Processor and Modbus RTU documentation installed.
  • Five Modbus RTU slaves each with a unique address in the range 1-247. Confirm each device's register map (coil, holding, input register).
  • Two-wire RS485 daisy-chain cable, 120 Ω termination resistors at both physical ends, and a common ground reference.
Hardware note: The CM 1241 and CB 1241 are isolated RS485 transceivers rated for 3,000 VRMS isolation. Do not mix RS485 and RS232 on the same segment. Maximum cable length is 1,200 m at 9,600 bit/s; derate to 200 m at 115,200 bit/s per the EIA/TIA-485-A standard.

Hardware and Network Topology

Wire the CM 1241 RS485 to the bus as follows:

CM 1241 pin Signal RS485 conductor
3 TxD+/RxD+ (non-inverting) Conductor A (Data+)
8 TxD-/RxD- (inverting) Conductor B (Data-)
5 Functional Earth / shield Shield, one end only

The CM 1241 provides internal 10 kΩ fail-safe bias resistors that hold the line idle at logical 1 (Mark). External 120 Ω termination is mandatory at the two farthest physical nodes only; adding extra terminators attenuates the signal and causes intermittent framing errors (status 0x80C4).

Set the RS485 bias/termination DIP switches on the module itself (CM 1241 has SW1–SW3; CB 1241 has none, termination is software-selected). On the CM 1241, SW1 = termination, SW2 = pull-up, SW3 = pull-down.

TIA Portal Project Configuration

Adding the Modbus RTU Instructions

No extra library is required for firmware V4.0 and later. The instructions ship with the global instruction set:

  1. In the project tree, expand PLC_1 → Program blocks → System blocks.
  2. Insert MB_COMM_LOAD (DB-type, instance DB auto-generated). It configures the port once at startup.
  3. Insert one MB_MASTER instance per slave (5 instances minimum). Each instance owns its own instance DB holding the request and status data.

MB_COMM_LOAD Parameter Mapping

Input Data type Value (typical) Meaning
REQ BOOL TRUE (pulse) Trigger port reconfiguration
PORT HW_IO CM/CB slot Identifier of the PtP port
BAUD DINT 9600 / 19200 Baud rate (110 to 115 200)
PARITY UINT 2 (even) 0=none, 1=odd, 2=even
FLOW_CTRL UINT 0 0=none for RS485 half-duplex
RTS_ON_DLY UINT 0 RTS-ON delay (ms)
RTS_OFF_DLY UINT 0 RTS-OFF delay (ms)
RESP_TO UINT 1000 Response timeout (ms), 5-65535
DONE BOOL – Configuration complete (one-shot)
ERROR BOOL – Configuration error
STATUS WORD – Error code when ERROR=TRUE
Critical: RESP_TO must exceed the worst-case slave turnaround. Most RTU slaves answer within 50 ms; set 1,000 ms for safety. A timeout smaller than the slave's processing time produces status 0x80C6 (response timeout).

MB_MASTER Instruction Deep Dive

The MB_MASTER instruction handles the Modbus ADU (Application Data Unit), assembles the CRC-16, and posts one transaction per rising edge of REQ. Per the SIMATIC S7-1200 Communication manual, the supported MODE values map to standard Modbus function codes:

MODE FC Direction Data type Data_ADDR unit
0 03 Read Holding Registers Word array Register number (40001 base)
1 01 Read Coils Bool array Coil number (00001 base)
2 02 Read Discrete Inputs Bool array Input number (10001 base)
4 04 Read Input Registers Word array Input register (30001 base)
5 05 Write Single Coil Bool array[1] Coil number (00001 base)
6 06 Write Single Register Word array[1] Register number (40001 base)
100 15 Write Multiple Coils Bool array Coil number (00001 base)
101 16 Write Multiple Registers Word array Register number (40001 base)

The DATA_ADDR parameter uses the zero-based Modbus address. To read holding register 40001, set DATA_ADDR = 0. To read 40010, set DATA_ADDR = 9. Maximum DATA_LEN is 125 words (FC 03/04/16) or 2,048 bits (FC 01/02/15). See the TIA Portal S7-1200 Modbus RTU instruction reference for full specifications.

Sequencer State Machine for 5 Slaves

Because the port is half-duplex and the firmware does not queue, you need a deterministic round-robin sequencer. The pattern is:

  1. Cycle through five steps (one per slave).
  2. On entry to step N, set REQ = TRUE on the corresponding MB_MASTER.
  3. Wait until DONE = TRUE or ERROR = TRUE.
  4. Reset REQ, copy data on success, log error on failure.
  5. Advance to step N+1 mod 5.

Use a small cyclic OB (OB1 or OB35) plus an instance FB that owns the state. The minimum inter-frame gap is 3.5 character times per Modbus RTU specification; the firmware inserts this automatically when the next REQ is fired, so no manual delay is needed as long as you release the bus within RESP_TO.

Sample SCL Implementation

The following code creates one instance DB per slave and a single sequencer. Declare in a static area of FB_ModbusMasterPoll:

FUNCTION_BLOCK FB_ModbusMasterPoll
VAR
    mbCommLoad : MB_COMM_LOAD;            // port configuration
    mbMaster_1 : MB_MASTER;                // slave 1 - read holding regs (10 words)
    mbMaster_2 : MB_MASTER;                // slave 2 - read input regs (8 words)
    mbMaster_3 : MB_MASTER;                // slave 3 - read coils (16 bits)
    mbMaster_4 : MB_MASTER;                // slave 4 - write multiple regs (5 words)
    mbMaster_5 : MB_MASTER;                // slave 5 - read 4 / write 2 words

    step            : INT  := 0;
    cycleCount      : DINT;
    errorCount_1..5 : DINT;

    // data buffers - sized for the largest expected payload
    dataSlave1 : ARRAY[0..9]  OF WORD;      // 10 holding regs from device #1
    dataSlave2 : ARRAY[0..7]  OF WORD;      // 8 input regs from device #2
    dataSlave3 : ARRAY[0..15] OF BOOL;      // 16 coils from device #3
    dataSlave4 : ARRAY[0..4]  OF WORD;      // 5 holding regs to device #4
    dataSlave5In  : ARRAY[0..3] OF WORD;    // 4 holding regs from device #5
    dataSlave5Out : ARRAY[0..1] OF WORD;    // 2 holding regs to device #5
END_VAR

BEGIN
    // -- 1) Configure port on first cycle --
    mbCommLoad(REQ := TRUE, PORT := "Cm1241_RS485",
               BAUD := 9600, PARITY := 2, FLOW_CTRL := 0,
               RESP_TO := 1000);

    IF NOT mbCommLoad.DONE THEN RETURN; END_IF;

    // -- 2) Sequencer: one transaction per OB1 pass --
    CASE step OF
        0: // Slave 1, read 10 holding registers (FC 03) starting at 40001
            mbMaster_1(REQ := TRUE, MB_ADDR := 1, MODE := 0,
                       DATA_ADDR := 0, DATA_LEN := 10,
                       DATA_PTR := dataSlave1);
            IF mbMaster_1.DONE THEN
                errorCount_1 := 0;
                step := 1;
            ELSIF mbMaster_1.ERROR THEN
                errorCount_1 := errorCount_1 + 1;
                step := 1;     // advance even on error to keep polling
            END_IF;

        1: // Slave 2, read 8 input registers (FC 04) starting at 30001
            mbMaster_2(REQ := TRUE, MB_ADDR := 2, MODE := 4,
                       DATA_ADDR := 0, DATA_LEN := 8,
                       DATA_PTR := dataSlave2);
            IF mbMaster_2.DONE OR mbMaster_2.ERROR THEN step := 2; END_IF;

        2: // Slave 3, read 16 coils (FC 01) starting at 00017
            mbMaster_3(REQ := TRUE, MB_ADDR := 3, MODE := 1,
                       DATA_ADDR := 16, DATA_LEN := 16,
                       DATA_PTR := dataSlave3);
            IF mbMaster_3.DONE OR mbMaster_3.ERROR THEN step := 3; END_IF;

        3: // Slave 4, write 5 holding registers (FC 16) starting at 40010
            mbMaster_4(REQ := TRUE, MB_ADDR := 4, MODE := 101,
                       DATA_ADDR := 9, DATA_LEN := 5,
                       DATA_PTR := dataSlave4);
            IF mbMaster_4.DONE OR mbMaster_4.ERROR THEN step := 4; END_IF;

        4: // Slave 5, read 4 holding registers (FC 03) starting at 40001
            mbMaster_5(REQ := TRUE, MB_ADDR := 5, MODE := 0,
                       DATA_ADDR := 0, DATA_LEN := 4,
                       DATA_PTR := dataSlave5In);
            IF mbMaster_5.DONE OR mbMaster_5.ERROR THEN step := 5; END_IF;

        5: // Slave 5, write 2 holding registers (FC 16) starting at 40006
            // Re-trigger the same MB_MASTER instance with a different MODE/DATA_LEN.
            mbMaster_5(REQ := TRUE, MB_ADDR := 5, MODE := 101,
                       DATA_ADDR := 5, DATA_LEN := 2,
                       DATA_PTR := dataSlave5Out);
            IF mbMaster_5.DONE OR mbMaster_5.ERROR THEN
                cycleCount := cycleCount + 1;
                step := 0;
            END_IF;
    END_CASE;

    // -- 3) Edge-detect REQ so each step fires once --
    mbMaster_1.REQ := FALSE; mbMaster_1.REQ := (step = 0) AND NOT mbMaster_1.DONE;
    mbMaster_2.REQ := FALSE; mbMaster_2.REQ := (step = 1) AND NOT mbMaster_2.DONE;
    mbMaster_3.REQ := FALSE; mbMaster_3.REQ := (step = 2) AND NOT mbMaster_3.DONE;
    mbMaster_4.REQ := FALSE; mbMaster_4.REQ := (step = 3) AND NOT mbMaster_4.DONE;
    mbMaster_5.REQ := FALSE; mbMaster_5.REQ := (step = 4 OR step = 5) AND NOT mbMaster_5.DONE;
END_FUNCTION_BLOCK
Code note: Step 5 reuses the mbMaster_5 instance because the same slave has both a read and a write transaction. Each instance of MB_MASTER can service any number of sequential transactions; the only requirement is that REQ is pulsed only after the previous DONE/ERROR has cleared.

Mapping 5 Slave Profiles to MB_MASTER

Slave Address Function FC MB_MASTER MODE DATA_ADDR (zero-based) DATA_LEN Buffer
#1 Read Holding Regs 1 Read 03 0 0 10 words dataSlave1[0..9]
#2 Read Input Regs 2 Read 04 4 0 8 words dataSlave2[0..7]
#3 Read Coils 3 Read 01 1 16 16 bits dataSlave3[0..15]
#4 Write Holding Regs 4 Write 16 101 9 5 words dataSlave4[0..4]
#5 Read+Write 5 Read 03 0 0 4 words dataSlave5In[0..3]
#5 Read+Write 5 Write 16 101 5 2 words dataSlave5Out[0..1]

The total wall-clock scan time for one full round is approximately 6 × (Tframe + Tslave + Tgap). At 9,600 bit/s and a 32-byte payload, Tframe ≈ 35 ms; budget 50 ms per slave response → 300 ms round. To halve that, increase the baud rate to 38,400 bit/s and confirm each slave supports it.

Master vs Slave Instructions: When to Use MB_SLAVE

If the S7-1200 itself needs to be polled by a higher-level SCADA or by another PLC, deploy the MB_SLAVE instruction on a second PtP port (a CB 1241 can be added to the left bus). MB_SLAVE supports function codes 1, 2, 4, 5, and 15 for direct bit/word access into the process image. Refer to the MB_SLAVE instruction documentation for the full I/O map.

In the configuration discussed here, the S7-1200 is the master. MB_SLAVE is mentioned only to clarify the asymmetric role; it must not be called simultaneously with MB_MASTER on the same port.

Diagnostics and STATUS Code Matrix

STATUS hex Meaning Root cause Fix
0x0000 Idle No active transaction Normal
0x0001 Success, in progress REQ accepted Normal
0x80C8 Invalid MB_ADDR / MODE Wrong parameter or unsup. FC Validate slave # 1-247, MODE = 0/1/2/4/5/6/100/101
0x80D1 REQ issued before previous DONE Sequencer race Add edge-detection on REQ
0x80D2 DATA_LEN out of range LEN > 125 or < 1 Re-size buffer; for FC 16 max 123 wrds
0x80D4 DATA_PTR not WORD/BOOL array Wrong type at instance DB Match MODE → BOOL for coils, WORD for registers
0x80E1 CRC error from slave Electrical noise / baud mismatch Check wiring, ground, parity, baud
0x80E2 Slave address mismatch Wrong MB_ADDR or duplicate address on bus Verify each slave's address switch
0x80E3 Function code not supported Slave does not implement this FC Check slave datasheet
0x80E4 Quantity out of slave range DATA_ADDR + DATA_LEN exceeds map Reduce DATA_LEN or shift address
0x80E5 Slave rejected write Read-only register Verify writeable memory map
0x80C4 Framing/parity error Line noise, wrong parity, baud Inspect wiring; check parity (most slaves use Even)
0x80C6 Response timeout RESP_TO too low or slave silent Increase RESP_TO; verify slave is powered
Pro tip: Each instance DB stores the last STATUS in "InstModbusMaster".STATUS. Create a watch table in TIA Portal with all five instances plus the sequencer step and cycleCount to monitor live polling health without pausing the CPU.

Verification and Commissioning Procedure

  1. Compile and download the program. Switch the CPU to RUN; MB_COMM_LOAD should pulse DONE within 200 ms.
  2. Open Online & Diagnostics → Modbus trace (TIA V16+) or use the watch table to verify step cycles 0 → 5 → 0 in less than 500 ms for a full round.
  3. Disconnect one slave physically. The corresponding MB_MASTER.ERROR should rise with STATUS 0x80C6; the sequencer must continue to the next step.
  4. Reconnect and confirm STATUS returns to 0 and DONE pulses true.
  5. Trigger a Modbus scan from a third-party tool (e.g., Modbus Poll) using the same baud/parity and verify the S7-1200's view matches the slave's real registers.
  6. For write slaves, change dataSlave4[0] online; confirm the slave reflects the new value within one cycle.
  7. Record a 60-second Modbus trace. Expect exactly six transactions per cycle; any extra frames indicate bus collisions (typically a termination or duplicate address issue).

Troubleshooting Matrix

Symptom Likely cause Diagnostic step Remediation
All slaves return 0x80C6 timeout No TX from CPU Check "MB_COMM_LOAD".DONE Verify PORT HW identifier; re-run MB_COMM_LOAD
One slave returns 0x80E2 Duplicate or wrong address Scan bus with master tool Re-address slave with DIP or software
Random 0x80E1 CRC errors Missing termination Inspect both ends of RS485 Install 120 Ω at the two farthest nodes only
Sequencer stuck on one step REQ held high continuously Watch MB_MASTER.REQ Edge-detect REQ with previous-step DONE
Write transactions report 0x80E5 Read-only register addressed Compare DATA_ADDR with map Use only FC 03 to read-only zones
Slaves 1-2 OK, slave 3 fails Coil-buffer type mismatch Check DATA_PTR declaration Declare as ARRAY OF BOOL for MODE 1/2/5/100
High MB_MASTER cycle time Multiple writes per cycle Profile OB1 execution Move sequencer to OB35 (100 ms) for periodic polling

Performance and Tuning Notes

  • For polling rates above 50 Hz aggregate, move the sequencer from OB1 to OB35 (cyclic interrupt, 100 ms) so the CPU's main scan stays responsive to HMI and safety logic.
  • If slaves support broadcast (address 0) and identical read maps, MB_MASTER can broadcast one FC 03 request; however most RTU slaves ignore writes via broadcast by design.
  • The internal instance DBs (InstModbusMaster_1 etc.) retain their STATUS across STOP→RUN transitions; clear them with RESET_BITS during startup if you need a clean slate.
  • For deterministic timing, set RESP_TO to 3.5 × (1 / baud) × 40 ms plus the slave's worst-case latency.

Alternative Approaches

Beyond the manual sequencer, two production-ready patterns exist:

  1. Siemens Support library (legacy): The S7-1200/S7-1500 Modbus RTU Master sample project on the Siemens Industry Online Support portal (entry ID 109742061) provides a ready-made FB MB_RTU_MASTER with cycle dispatch and 16-slot table. Use it for rapid deployment without hand-coding the sequencer.
  2. Third-party libraries (e.g., rexhip): An open-source Modbus RTU master library for S7-1200 is available, providing high-level blocks for read/write with built-in reconnection. Such libraries are suitable for non-safety applications; validate CRC handling and STATUS mapping before deployment.

For most small-scale installations (≤ 8 slaves, < 100 ms scan) the sequencer pattern in this document outperforms a generic library because you retain direct visibility of every STATUS word and can scale the cycle to your application's precision needs.

FAQ

How many MB_MASTER instances do I need for 5 slaves with different read and write tag counts?

One instance per transaction direction per slave address. Five slaves with mixed read/write can be served by 6 instances if one slave needs both directions (e.g., 4 read-only slaves = 4 instances plus 1 slave with read+write = 2 instances, total 6). Each instance must be triggered one at a time via the sequencer.

What STATUS code indicates the slave is offline or unpowered?

STATUS 0x80C6 (response timeout). Increase RESP_TO in MB_COMM_LOAD to at least 1,000 ms, then verify the slave's power supply and RS485 wiring. No response within the timeout window always raises this code regardless of the underlying electrical issue.

Can MB_MASTER and MB_SLAVE run on the same S7-1200 simultaneously?

No. They share the same port resource and the firmware cannot arbitrate master vs slave on one half-duplex RS485 channel. Add a second CM/CB 1241 module if the CPU must act as both master and slave in the same project. See the MB_SLAVE documentation for port-binding rules.

Why does my read-only slave return 0x80E5 even though I only read?

STATUS 0x80E5 is returned for slave-side exceptions other than illegal function or address; it usually means the slave does not support the requested function code or the requested quantity. Verify the FC mapping in the slave's documentation and reduce DATA_LEN so it does not cross into unmapped register space.

What is the maximum total number of registers I can poll across 5 slaves?

There is no firmware-imposed aggregate limit, only the per-transaction ceiling of 125 words (or 2,048 bits for coils) and the port's response timeout. A typical 5-slave configuration with 32 registers each fits well within 300 ms at 19,200 bit/s. If you exceed that, lower the polling priority of non-critical slaves by skipping them every N cycles in the sequencer.

Back to blog