S7-1200 Modbus RTU Master with CM 1241 RS485: Programming Guide

David Krause13 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 with CM 1241 RS485: Programming Guide

This field-reference covers configuring a SIMATIC S7-1200 CPU as a Modbus RTU master using a CM 1241 RS485 (or RS422/485) communication module, the Modbus_Comm_Load and Modbus_Master instruction blocks, and exposing the polled data to an HMI on TIA Portal. The workflow is identical whether the slave is a power meter, a VFD, a sensor, or a second S7-1200 acting as a slave; only the slave address, register map, baud rate, parity, and response timeout change.

1. Overview

Modbus RTU over RS-485 is the most common serial protocol used by low-voltage power devices (meters, soft starters, drives, trip units) and a long list of third-party sensors. The S7-1200 does not ship with native Modbus RTU master capability in its firmware: you must install the "SIMATIC S7-1200 Modbus Master RTU" library, place a CM 1241 (RS485 or RS422/485) module to the left of the CPU, and call Modbus_Comm_Load once per port and Modbus_Master for every request.

The S7-1200 acts as the Modbus master; the power device is a slave. The full Siemens entry on Modbus RTU between two S7-1200 CPUs (entry ID 47756141) uses the same library and provides a complete sample project for the master side. See Siemens Support Entry 47756141 - S7-1200 Modbus RTU Communication Example.

Compatibility note: The original sample was written for STEP 7 V11. The Modbus_Comm_Load and Modbus_Master instructions exist in the same library across TIA Portal V13, V14, V15, V15.1, V16, V17, and V18, and behave identically. Library versions 4.0 and later require CPU firmware V4.0 or higher.

2. Prerequisites

2.1 Hardware

  • S7-1200 CPU in the 12xxC family (CPU 1211C / 1212C / 1214C / 1215C / 1217C). Compact CPUs without a separate signal board slot require a CM 1241 to expose RS-485.
  • CM 1241 RS485 / RS422 module. Common catalog numbers:
    • 6ES7241-1CH30-1XB0 - CM 1241 RS485 (legacy)
    • 6ES7241-1CH31-0XB0 - CM 1241 RS422/485 (current, supports Modbus RTU master and slave)
    • 6ES7241-1CH32-0XB0 - CM 1241 RS232 (serial Modbus to RS-232 devices only)
  • CM 1241 must be installed directly to the left of the CPU (slot 101) or chained off another CM/CP/SM using the S7-1200 internal bus.
  • Termination: enable the terminating resistor on the CM 1241 if the device is at the physical end of the RS-485 trunk (DIP switch on the back of the module, 120 Ω between A and B).

2.2 Firmware

  • CPU firmware V2.0 minimum for the original Modbus library; V4.0 or higher is required for library V4.0+ and is recommended for any new project.
  • CM 1241 firmware: shipped at the latest revision when purchased new; flash with TIA Portal > Online > Accessible devices > Firmware update if a vendor driver requires it.

2.3 Software

  • STEP 7 (TIA Portal) Basic or Professional, V13 SP1 or higher recommended. V10.5 is referenced in the original question and continues to work, but new installs should use V17 or V18.
  • WinCC (TIA Portal) Basic or Comfort for the HMI project (Basic on the same TIA Portal instance as the PLC).
  • Third-party: MODSCAN32 (WinTech) or any Modbus master test tool to validate the slave before involving the PLC.

2.4 Wiring (RS-485, 2-wire half-duplex)

CM 1241 terminal Signal Slave A/B
3 (T/R+, A) Data + A (or D+)
8 (T/R-, B) Data − B (or D−)
5 (GND) Reference Common / GND
4 (RTS/CTS) Not used in 2-wire RS-485 n.c.

Use a shielded twisted pair (Belden 3106A or equivalent), shield grounded at one end only. Daisy-chain the A and B lines; do not use a star topology. Maximum stub length is generally 30 m at 115.2 kbit/s, shorter for higher baud rates.

3. Configuring the Project and Hardware

  1. Create a new TIA Portal project and add the S7-1200 station.
  2. In Device configuration, drag a CM 1241 (RS422/485) onto slot 101 of the CPU.
  3. Open the CM 1241 properties:
    • Port configuration > Operating mode: Half-duplex (RS485) 2-wire
    • Baud rate: match the slave (9600 is the safe default for power meters)
    • Parity: match the slave (Even is most common for Modbus RTU energy devices)
    • Data bits / Stop bits: 8 / 1 (or 8 / 2 per slave spec)
    • Flow control: None for RS-485
  4. Note the Hardware identifier of the CM 1241 (e.g. 269) from the System constants tab. Modbus_Comm_Load needs this value at its PORT input.

4. Installing the Modbus Master Library

  1. Right-click PLC_1 > External source files and choose Retrieve library elements.
  2. The library is shipped with TIA Portal: SIMATIC S7-1200 Modbus Master RTU. Locate it under Options > Global libraries > Modbus_Master_RTU.
  3. Drag the two FB types Modbus_Comm_Load (FB 1080) and Modbus_Master (FB 1081) into your project under Program blocks > Master copies or call them directly from the library folder.
  4. Copy the matching DB instances into your program blocks; the library uses FB 1080/1081 with associated instance DBs.
Library versions matter: V1.x targets CPU firmware V2.x; V3.x targets V3.x; V4.x targets V4.0+. The block names and parameter signatures are identical, but the instance DB schema differs, so do not mix versions on the same project.

5. Calling Modbus_Comm_Load (Run Once on Startup)

Modbus_Comm_Load configures the port and must be executed exactly once per CM 1241. Place the call in OB1, a startup OB, or a cyclic OB and trigger REQ with a one-shot on cold restart.

Parameter Type Meaning Typical value
REQ BOOL Start (rising edge) FirstScan
PORT WORD Hardware identifier of CM 1241 269 (or 270 for slot 102)
BAUD DWORD Baud rate 9600
PARITY WORD 0=None, 1=Odd, 2=Even 2 (Even)
FLOW_CTRL WORD 0=None, 1=Hardware (RS-232 only) 0
RTS_ON_DLY WORD RTS on delay (ms) 0
RTS_OFF_DLY WORD RTS off delay (ms) 0
RESP_TO WORD Slave response timeout (ms) 1000 (raise for slow slaves)
DONE BOOL Configuration complete Tag: MB_Load_Done
ERROR BOOL Configuration error Tag: MB_Load_Error
STATUS WORD Error code (see Section 10) Tag: MB_Load_Status

5.1 Sample SCL call

// OB1 - port initialisation (call once on cold restart)
IF "FirstScan" THEN
    "MB_Comm_Load_DB"(REQ := TRUE,
                      PORT := 269,           // CM 1241 hardware ID
                      BAUD := 9600,
                      PARITY := 2,           // Even
                      FLOW_CTRL := 0,        // None (RS485)
                      RTS_ON_DLY := 0,
                      RTS_OFF_DLY := 0,
                      RESP_TO := 1000,
                      DONE => "MB_Load_Done",
                      ERROR => "MB_Load_Error",
                      STATUS => "MB_Load_Status");
END_IF;

5.2 Sample ladder equivalent

Network 1: rising-edge coil on FirstScan drives the REQ input of the Modbus_Comm_Load box. Outputs DONE and ERROR are wired to tags; STATUS is wired to a WORD tag and animated on the HMI for diagnostics.

6. Calling Modbus_Master (One Per Slave or One Per Register Group)

Modbus_Master issues a single Modbus request per rising edge on REQ. The instruction is edge-triggered and must not be called again until DONE or ERROR becomes true. The typical pattern is to cycle through slaves inside a cyclic OB, gating each REQ on the previous call's completion.

Parameter Type Meaning Typical value
REQ BOOL Trigger (rising edge) Polled flag
MB_ADDR USINT / WORD Modbus slave address 1-247 1
MODE WORD 0=Read, 1=Write, 2=Read/Write, 3=Write/Read 0
DATA_ADDR WORD Modbus starting address (1-based, see slave manual) 0 (function 03 holding register 40001)
DATA_LEN WORD Number of words or bits to transfer 10
DATA_PTR VARIANT Pointer to data block or tag array P#DBxx.DBX0.0 BYTE 20
DONE BOOL Request complete without error Tag
ERROR BOOL Request failed Tag
STATUS WORD Error code (see Section 10) Tag
Address conversion: DATA_ADDR uses the Modbus "register number minus one" convention. To read holding register 40001, set DATA_ADDR = 0. To read 40010, set DATA_ADDR = 9. For function code 04 (input registers) the address range starts at 30001, so register 30001 = DATA_ADDR 0.

6.1 Cyclic polling pattern (SCL)

// OB1 - poll three power meters in sequence
CASE "PollStep" OF
    0:  // meter #1: 10 holding registers from 40001
        "MB_Master_DB"(REQ := TRUE,
                      MB_ADDR := 1,
                      MODE := 0,         // Read
                      DATA_ADDR := 0,    // 40001
                      DATA_LEN := 10,
                      DATA_PTR := P#"Meter1_Reg".DBX0.0 BYTE 20,
                      DONE => "MB_Done",
                      ERROR => "MB_Error",
                      STATUS => "MB_Status");
        IF "MB_Done" OR "MB_Error" THEN
            "PollStep" := 1;
        END_IF;

    1:  // meter #2: 6 holding registers from 40020
        ...
        IF "MB_Done" OR "MB_Error" THEN
            "PollStep" := 2;
        END_IF;

    2:  // meter #3: 4 holding registers from 40100
        ...
        IF "MB_Done" OR "MB_Error" THEN
            "PollStep" := 0;
        END_IF;
END_CASE;

7. Modbus Function Codes Supported by Modbus_Master

Function code Direction DATA_ADDR base DATA_LEN units Typical use
01 - Read Coils Master → Slave 0 (coil 1) Bits (1-2000) Digital outputs / status
02 - Read Discrete Inputs Master → Slave 0 (input 10001) Bits (1-2000) Digital inputs
03 - Read Holding Registers Master → Slave 0 (reg 40001) Words (1-125) Measured values, setpoints
04 - Read Input Registers Master → Slave 0 (reg 30001) Words (1-125) Metering (V, I, kW, kWh)
05 - Write Single Coil Master → Slave 0 (coil 1) 1 bit Trip / close commands
06 - Write Single Register Master → Slave 0 (reg 40001) 1 word Setpoint write
15 (0x0F) - Write Multiple Coils Master → Slave 0 Bits (1-1968) Bulk command
16 (0x10) - Write Multiple Registers Master → Slave 0 Words (1-123) Bulk setpoint / time sync

For "Read holding registers from address 40001, length 10" use MODE = 0, DATA_ADDR = 0, DATA_LEN = 10. The DATA_PTR must point to a buffer of 2 * DATA_LEN bytes.

8. Sample Program: Read a Power Meter and Display on HMI

8.1 Data block layout

DATA_BLOCK "PowerMeterData"
  STRUCT
    Voltage_L1_N  : REAL;   // 40001 (V, scale 0.1)
    Voltage_L2_N  : REAL;   // 40003
    Voltage_L3_N  : REAL;   // 40005
    Current_L1    : REAL;   // 40007 (A, scale 0.01)
    Current_L2    : REAL;   // 40009
    Current_L3    : REAL;   // 40011
    ActivePower   : REAL;   // 40013 (W, scale 1)
    Frequency     : REAL;   // 40015 (Hz, scale 0.01)
  END_STRUCT;
END_DATA_BLOCK

8.2 Modbus read call (OB1, SCL)

// Read 8 holding registers (40001..40015 odd, 16 bytes)
"MB_Master_DB"(REQ := "MB_Trigger",
              MB_ADDR := 1,
              MODE := 0,
              DATA_ADDR := 0,    // 40001
              DATA_LEN := 8,     // 8 words = 16 bytes
              DATA_PTR := P#"PowerMeterData_Raw".DBX0.0 BYTE 16,
              DONE => "MB_Done",
              ERROR => "MB_Error",
              STATUS => "MB_Status");

8.3 Word-to-real scaling (SCL, FC "ScaleMeter")

// Convert raw INT to REAL with scaling
"PowerMeterData".Voltage_L1_N := INT_TO_REAL("PowerMeterData_Raw".Volts_L1) / 10.0;
"PowerMeterData".Current_L1   := INT_TO_REAL("PowerMeterData_Raw".Amps_L1) / 100.0;
"PowerMeterData".ActivePower  := INT_TO_REAL("PowerMeterData_Raw".Watts_Tot);
"PowerMeterData".Frequency    := INT_TO_REAL("PowerMeterData_Raw".Hz)        / 100.0;

8.4 HMI tag wiring

Create HMI tags that point at the scaled values in PowerMeterData (e.g. PowerMeterData.Voltage_L1_N). Place a numeric output on the screen with format string 999.9 " V". Add a status bar driven by MB_Error and MB_Status to surface communication faults directly on the screen.

9. Verification Procedure

  1. Validate the slave first with MODSCAN32. Connect a USB-to-RS-485 converter to the bus, set the same baud, parity, and slave address, and read the registers the PLC will request. If MODSCAN returns valid data, the slave is wired and configured correctly. This step eliminates 80% of integration time per the original Siemens reply on the same thread.
  2. Compile and download the TIA Portal project to the S7-1200. Watch MB_Load_Done go TRUE in online watch table within one second of the first scan.
  3. Go online → Watch → force MB_Trigger TRUE to issue a single read. Verify MB_Done transitions TRUE and the data block PowerMeterData_Raw is populated.
  4. Run the cyclic poller and confirm the data refreshes on the HMI at the expected rate. Power meters typically publish new data at 1 Hz; reading more frequently just repeats the last value.
  5. Bus diagnostics. Open the CM 1241 in online mode; under Diagnostics you can read Frame errors, Parity errors, and Overrun errors counters. A non-zero parity error count almost always means the slave and master parity settings disagree.

10. Troubleshooting Matrix

STATUS (hex) Meaning Root cause Fix
0x0000 No error - -
0x80C8 Response timeout Slave not answering within RESP_TO; wrong address, wrong baud, A/B swapped, no common ground, terminating resistor missing on a long bus Verify wiring polarity, lower baud, raise RESP_TO to 2000 ms for slow slaves
0x80D1 Parity or framing error from slave response Parity / data bits / stop bits mismatch Match CM 1241 port config to the slave spec sheet
0x80D2 CRC error Electrical noise, missing termination, A/B reversed, wrong baud Add 120 Ω at both ends, check shield grounding, swap A and B
0x80D4 Modbus exception from slave (function code returned with error bit set) Slave does not support the requested address or function Cross-check the slave register map; some devices split holding vs. input registers or require unlock codes
0x80E0 Read passed MB area end (DATA_ADDR + DATA_LEN > slave range) Read length exceeds available registers Reduce DATA_LEN to what the slave exposes
0x80FF Library / instance error Wrong library version, mismatched FB/UDT, instance DB not regenerated after upgrade Recompile all blocks; re-fetch the library matching CPU firmware
0x8180 / 0x8181 MB_Comm_Load parameter error Invalid PORT ID, invalid BAUD, RESP_TO out of range Confirm hardware ID from System constants; BAUD must be 300/600/1200/2400/4800/9600/19200/38400/57600/76800/115200; RESP_TO 5..65535 ms

11. Performance and Timing Guidelines

  • One transaction at a time per port. The CM 1241 cannot pipeline. If you have five slaves, sum the worst-case response times to compute the poll cycle.
  • Worst-case frame time at 9600/8/N/1 for a 10-word read is roughly:
    frame = (3.5 chars silence) + (8 bytes header) + (10 words * 2) + (CRC 2) + (3.5 chars silence)
         = 35 bits start/idle + 80 + 200 + 16 + 35
         = ~366 bits @ 9600 = ~38 ms per transaction
  • At 19200 baud, the same transaction is ~19 ms. Five slaves polled sequentially refresh every ~95-200 ms, which is well within a 100 ms HMI update rate.
  • If the bus is large (> 20 devices) or runs at 115.2 kbit/s, consider splitting the bus across two CM 1241 modules in the same S7-1200 station.

12. Cross-References and Related Tasks

  • For Modbus TCP (rather than RTU) on the S7-1200, the configuration differs: use the PROFINET port of the CPU and the MB_CLIENT / MB_SERVER blocks. Siemens documents this in the S7-1200 manual collection at TIA Portal Documentation - Modbus TCP Examples.
  • For making the S7-1200 a Modbus RTU slave (e.g. an HMI acting as master), use the Modbus_Slave instruction (FB 1082) in the same library. The CM 1241 port setup uses the same Modbus_Comm_Load call.
  • For wiring a CM 1241 RS-232 to a Modbus device that uses RS-232, switch FLOW_CTRL to 1 (hardware) and wire RTS/CTS. RS-232 cable length is limited to ~15 m.

What library do I need for S7-1200 Modbus RTU master?

Use the "SIMATIC S7-1200 Modbus Master RTU" global library shipped with TIA Portal. It contains Modbus_Comm_Load (FB 1080) for port configuration and Modbus_Master (FB 1081) for issuing requests. Library V4.0+ requires CPU firmware V4.0 or higher; older library versions work on CPU firmware V2.0+.

How do I set the Modbus register address in DATA_ADDR?

Subtract one from the Modbus register number. To read holding register 40001 set DATA_ADDR = 0; for 40010 set DATA_ADDR = 9. The same rule applies to coils (00001 = 0) and input registers (30001 = 0). Confirm the register map in the slave's user manual before coding.

STATUS 0x80C8 means what and how do I fix it?

0x80C8 is a slave response timeout. The master sent a request but received no reply within RESP_TO (default 1000 ms). Common causes: wrong slave Modbus address, A and B wires swapped, missing common ground between master and slave, no 120 Ω termination at the bus ends, or baud rate mismatch. Increase RESP_TO to 2000 ms for slow slaves and verify with MODSCAN32 first.

Can I poll multiple Modbus slaves from one CM 1241?

Yes. One CM 1241 supports multiple slaves on the same RS-485 bus, but only one transaction at a time. Run Modbus_Comm_Load once, then call Modbus_Master sequentially with a different MB_ADDR per slave. Gate each call on the previous one's DONE or ERROR bit. For very large buses split the slaves across two CM 1241 modules.

Why does my HMI show 0 even though MB_Done is TRUE?

The DATA_PTR buffer receives raw 16-bit words, not scaled REAL values. You need a separate conversion step (e.g. INT_TO_REAL divided by the meter's scaling factor) to get engineering units, and the HMI tag must point at the scaled value, not the raw word. Also confirm the byte order: some power meters transmit little-endian, some big-endian; the CM 1241 returns bytes exactly as received, so byte-swap if the manual says so.

Back to blog