Configuring S7-1200 Modbus RTU to Carlo Gavazzi EM24 via CB 1241

David Krause11 min read
ModbusSiemensTutorial / 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

Overview

This guide covers commissioning a Modbus RTU link between a Siemens SIMATIC S7-1200 CPU 1215C and a Carlo Gavazzi EM24 DIN rail energy meter using the CB 1241 RS485 communication module. The S7-1200 acts as the Modbus RTU master, the EM24 acts as a slave, and the CB 1241 supplies the isolated RS485 physical layer. Programming is performed in TIA Portal using the library instructions MB_COMM_LOAD and MB_MASTER.

Protocol rule: Modbus RTU requires identical baud rate, parity, data bits, and stop bits on every device on the bus. Mismatched parameters will produce 0x0001 or 0x0002 status words on MB_MASTER with no useful diagnostic beyond illegal function or illegal data address.

Prerequisites

  • SIMATIC S7-1200 CPU 1215C (firmware V4.0 or later recommended for stable Modbus library behavior; V4.4+ recommended for S7-1200 firmware in the V16+ TIA Portal environment)
  • CB 1241 RS485 communication module (6ES7241-1CH30-1XB0)
  • Carlo Gavazzi EM24 (variants: EM24 DIN, EM24 Ethernet, EM24-DIN.AV5, EM24-DIN.AV6, EM24-DIN.AV7, EM24-DIN.AV9 - confirm RS485 variant before wiring)
  • TIA Portal V13 SP2 or later (V15.1, V16, V17, or V18 recommended)
  • Modbus RTU library instructions from Siemens (auto-installed with TIA Portal V14+; legacy V13 requires manual import of the "Modbus_Comm_Load" and "Modbus_Master" FB blocks)
  • Shielded twisted pair RS485 cable (Belden 3106A or equivalent, characteristic impedance 120 Ω, 24 AWG)
  • 120 Ω termination resistors at each bus end
  • 24 VDC power supply for the S7-1200 and EM24

Hardware Architecture and Wiring

RS485 Bus Topology

The CB 1241 RS485 module uses a 9-pin sub-D connector or a removable terminal block (TB) on the bottom of the module. For the CB 1241, the relevant pins are:

Pin Signal Description
1 Shield / GND Cable shield termination
3 B (Data+) Non-inverting data line (10 kΩ bias to +5 V internally)
4 A (Data-) Inverting data line (10 kΩ bias to GND internally)
5 / TB Reference / Termination Reference ground; tie point for optional 120 Ω termination
T/ Termination Short to TB to enable on-board 120 Ω termination

Per the CB 1241 RS485 technical specifications:

  • Bias: 10 kΩ to +5 V on B (Pin 3); 10 kΩ to GND on A (Pin 4)
  • Optional termination: short Pin TB to Pin T/ to engage the on-board 120 Ω termination across the bus

Recommended Wiring

  1. Connect CB 1241 Pin 3 (B) to EM24 terminal B+ (or D+ on Carlo Gavazzi label).
  2. Connect CB 1241 Pin 4 (A) to EM24 terminal A- (or D- on Carlo Gavazzi label).
  3. Connect CB 1241 Pin TB to EM24 reference terminal (often marked GND or COM).
  4. Enable 120 Ω termination on the CB 1241 by placing a jumper or wire between TB and T/ on the terminal block (this engages the on-board resistor).
  5. If the EM24 is the last device on a long bus, also enable its 120 Ω termination dip switch (consult EM24 datasheet; typically the third dip switch on the side of the unit).
  6. Connect cable shield to functional earth at one end only (typically at the cabinet ground bar) to avoid ground loops.
Termination rule: Exactly two 120 Ω resistors must be present in parallel across A and B - one at each physical end of the bus. With the CB 1241's on-board termination engaged at the PLC end, only the EM24 (last device) should have its own termination enabled.

Maximum Bus Length and Devices

RS485 supports up to 32 unit loads on a single bus (the CB 1241 presents 1 unit load, the EM24 also presents 1 unit load). Maximum cable length at 19200 baud is 1200 m; at 115200 baud it is approximately 200 m. The EM24 is typically operated at 9600 or 19200 baud over cable runs under 200 m.

Carlo Gavazzi EM24 Configuration

The EM24 is configured via the front-panel push buttons or, on the AV5/AV9 Ethernet variants, via web interface. For Modbus RTU operation:

Parameter Typical Setting Notes
Slave address 1 (default; range 1-247) Must be unique on bus; PLC references this in MB_MASTER "SlaveAddress" input
Baud rate 9600 (or 19200) Match CB 1241 setting exactly
Parity None (also valid: Even) EM24 ships with 8N1; CB 1241 must match
Data bits 8 Fixed for Modbus RTU
Stop bits 1 (or 2 with parity) Match CB 1241
Termination Enabled only if last device DIP switch on side of EM24 housing

Set the slave address using the front-panel menu: SETUP → ADDRESS → n (where n is 1-247). Confirm the value is stored by power-cycling the meter.

TIA Portal Hardware Configuration

  1. Open your TIA Portal project and the device view of the S7-1200.
  2. Drag the CB 1241 RS485 (6ES7241-1CH30-1XB0) from the catalog onto slot 1 of the S7-1200 (slot 101 for the CPU's left-side communication module bay).
  3. Double-click the CB 1241 to open its properties.
  4. Under RS485 Interface → Port Configuration, set:
    - Baud rate: 9600 (or matching EM24)
    - Parity: None
    - Data bits: 8
    - Stop bits: 1
    - Flow control: None
  5. Under I/O Link / Module Parameters, set the transmission mode. For Modbus RTU master operation, no special mode is required - the CB 1241 operates in transparent point-to-point mode with user-controlled RTS.
  6. Compile and download the hardware configuration to the CPU.

Programming the Modbus Master

Block Architecture

Siemens provides two FB (Function Block) instructions for Modbus RTU master operation on the S7-1200:

  • MB_COMM_LOAD (DB 1 by default): configures the port, executes once on startup or cold restart to initialize the CB 1241.
  • MB_MASTER (DB 2 by default): sends a single Modbus request and triggers on the rising edge of the REQ input.
One MB_COMM_LOAD per port: Each CB 1241 port must have exactly one MB_COMM_LOAD call in OB1 (or OB100 for cold restart). Calling it twice with different DBs causes port initialization conflicts.

MB_COMM_LOAD Input Wiring

Example parameter assignment (drag from a global data block "ModbusConfig"):


REQ         := TRUE                       // Always TRUE in OB100 (one-shot)
PORT        := 1                          // RS485 port index on CB 1241 (0 or 1)
BAUD        := 9600                       // Must match EM24
PARITY      := 0                          // 0=None, 1=Odd, 2=Even
FLOW_CTRL   := 0                          // 0=None for Modbus RTU
RTS_ON_DLY  := 0                          // ms; 0 for Modbus RTU
RTS_OFF_DLY := 0                          // ms; 0 for Modbus RTU
RESP_TO     := 1000                       // ms response timeout; 1000-2000 typical
DONE        => mbLoadDone                // Boolean: configuration complete
ERROR       => mbLoadError                // Boolean: configuration error
STATUS      => mbLoadStatus               // Word: detailed status (see table below)

MB_MASTER Input Wiring (Read Holding Registers Example)

To read voltage, current, power, and energy from the EM24, poll Function Code 0x03 (Read Holding Registers) at the EM24's measurement register base. A typical request to read the first 10 measurement registers:


REQ         := pollTrigger                // Bool; rising edge fires request
MB_ADDR     := 1                          // EM24 slave address (set on meter)
MODE        := 0                          // 0=Read, 1=Write (single), 2=Write multiple
DATA_ADDR   := 300001                     // Modbus address; library converts to 0x0000 internally
DATA_LEN    := 10                         // Number of 16-bit words to read (max 125)
DATA_PTR    := P#DB20.DBX0.0 WORD 10      // Destination pointer; must be at least DATA_LEN words
DONE        => pollDone                  // TRUE for one cycle on success
ERROR       => pollError                 // TRUE for one cycle on failure
STATUS      => pollStatus                 // Word: see error code table
Address conversion: The TIA Portal MB_MASTER instruction takes a "Modbus address" in the range 1-65536 and automatically subtracts 1 before transmission. To read EM24 register 0x0000 (the first holding register), supply DATA_ADDR = 1. To read register 0x0100 (256), supply DATA_ADDR = 257.

Reading the EM24 Register Map

The Carlo Gavazzi EM24 has a documented Modbus register map. Key registers (Function Code 0x03, Read Holding Registers):

Address (Hex) Address (Decimal) Parameter Unit / Scale Type
0x0000 1 Voltage L1 V × 10 (0.1 V) UINT16
0x0002 3 Voltage L2 V × 10 UINT16
0x0004 5 Voltage L3 V × 10 UINT16
0x0006 7 Current L1 A × 100 UINT16
0x0008 9 Current L2 A × 100 UINT16
0x000A 11 Current L3 A × 100 UINT16
0x000C 13 Power L1 W × 10 INT16 (signed)
0x000E 15 Power L2 W × 10 INT16
0x0010 17 Power L3 W × 10 INT16
0x0012 19 Total Active Power W × 10 INT16
0x0034 53 Total Active Energy kWh × 10 UINT16
0x0036 55 Partial Active Energy kWh × 10 UINT16

Note: register scaling and addresses vary by EM24 firmware revision. Always consult the official Carlo Gavazzi EM24 Modbus protocol guide for your firmware level (typically downloaded from the product support page of gavazziautomation.com) before commissioning.

STEP 7 / TIA Portal Sample Code

Below is a minimal OB1 ladder excerpt for reading 10 holding registers from EM24 address 1, on a 200 ms cycle, storing into DB20:


Network 1: Trigger poll every 200 ms
      "Clock_200ms"   "pollTrigger"
     ─┤ ├──────(P)─────

Network 2: Call MB_MASTER (FC rising edge only)
      "pollTrigger"    MB_MASTER.DB2
     ─┤↑ ├──────────┬── EN
                     ├  REQ     := "pollTrigger"
                     ├  MB_ADDR := 1
                     ├  MODE    := 0      // Read
                     ├  DATA_ADDR:= 1
                     ├  DATA_LEN := 10
                     ├  DATA_PTR := P#DB20.DBX0.0 WORD 10
                     └  ...

Network 3: Error handling
      "pollError"     "Alarm_Comm"
     ─┤ ├──────────( S )─
      "pollStatus"    "MB_Error_Code"
     ─┤MW├──────────(MW)─

Verification

  1. Online watch table: Open a watch table on DB20 and force a single poll. Confirm DONE goes TRUE and STATUS = 0 within RESP_TO milliseconds.
  2. Read individual words: Word 0 of DB20 (EM24 register 0x0000) should display a value corresponding to L1-N voltage × 10. If your line-to-neutral voltage is 230.4 V, expect a value of 2304.
  3. Cross-check on the meter: The EM24 front display and the value scaled from the register must match within ±1 LSB.
  4. LED indication on CB 1241: The green "TxD" LED should blink on each master transmission; the yellow "RxD" LED should blink on each slave response. If only TxD blinks and RxD never activates, the wiring or slave address is wrong.
  5. Traffic capture (optional): A USB-RS485 sniffer (e.g., FTDI USB-RS485-WE-1800-BT) running Modbus Poll or modbus-cli confirms the request frame: 01 03 00 00 00 0A C5 CD (address 1, function 03, start 0, count 10, CRC).

Troubleshooting Matrix

Symptom STATUS Code Likely Cause Action
DONE never TRUE, STATUS = 0 0x0000 REQ not pulsing, or MB_MASTER not called Verify cycle flag and call enable
DONE never TRUE, STATUS = 0x80C8 0x80C8 Slave did not respond within RESP_TO Check slave address, baud, wiring, termination
ERROR TRUE, STATUS = 0x80C8 0x80C8 Timeout - bus short, missing pull-up, reversed A/B Swap A and B; check termination; verify shield
ERROR TRUE, STATUS = 0x8188 0x8188 Modbus exception "Illegal Function" EM24 firmware may not support the function code; consult EM24 manual
ERROR TRUE, STATUS = 0x8288 0x8288 Modbus exception "Illegal Data Address" DATA_ADDR out of range for EM24
ERROR TRUE, STATUS = 0x8388 0x8388 Modbus exception "Illegal Data Value" DATA_LEN invalid for this register
ERROR TRUE, STATUS = 0x80D1 0x80D1 Port not configured - MB_COMM_LOAD not run Call MB_COMM_LOAD in OB100 first
CRC errors in capture n/a Electrical noise, missing termination, long unshielded run Re-route cable, enable both terminations, ground shield
Intermittent comms, STATUS = 0x80C8 0x80C8 More than 32 unit loads, or baud too high for cable Lower baud to 9600, shorten bus, count devices

Best Practices and Field Tips

  • Always cold-start the S7-1200 after editing hardware configuration so MB_COMM_LOAD reinitializes the CB 1241 in OB100 before the first MB_MASTER call in OB1.
  • Place MB_MASTER in a periodic OB (e.g., OB30 cyclic interrupt at 100 ms) to avoid jitter from OB1 scan time.
  • Limit the number of registers per MB_MASTER call to 16-32 for fast polling; use multiple MB_MASTER instances with staggered REQ pulses for larger datasets.
  • Compute CRC in advance only when benchmarking; trust the library CRC unless you have a confirmed silent-corruption issue.
  • Use the EM24's "reset partial energy" writable register (Function Code 0x06, Write Single Register) to zero the partial counter at shift changes - place the write in a single-shot trigger to avoid bus flooding.
  • Set CB 1241 termination only when the module is at a physical bus end; otherwise, leave the TB/T jumper open and place 120 Ω at the two end devices only.
  • Document the MB_ADDR, baud, parity, and DATA_ADDR for each slave in the HMI tag comment - this saves hours of commissioning time when scaling to multi-meter panels.

Frequently Asked Questions

What baud rate should I use between the S7-1200 and the EM24?

9600 baud is the safest default for cable runs up to 200 m with the EM24. Use 19200 baud only on short, well-shielded runs. Always match the CB 1241 hardware configuration and the EM24 menu setting exactly.

Why does STATUS return 0x80C8 with no DONE flag?

0x80C8 is the timeout status - the master transmitted but did not receive a valid response within RESP_TO. Verify the EM24 slave address, A/B polarity, bus termination, and that the EM24 is powered and configured for Modbus RTU (not Modbus TCP).

Can I run multiple EM24 meters on one CB 1241 port?

Yes. RS485 supports up to 32 unit loads. Use a separate MB_MASTER call for each meter with a unique MB_ADDR (1-247). Stagger the REQ inputs to avoid overlapping requests on the bus.

What does it mean when MB_MASTER returns 0x8188?

0x8188 is a Modbus exception code indicating "Illegal Function" - the EM24 does not recognize the function code. Confirm your MODE setting (0=Read Holding, 1=Write Single, 2=Write Multiple) matches what the EM24 supports for the targeted register.

Do I need to call MB_COMM_LOAD every scan cycle?

No. Call MB_COMM_LOAD once in OB100 (cold restart) with REQ = TRUE. Re-invoking it from OB1 in every cycle causes the port to reinitialize and disrupts active MB_MASTER requests.

How do I scale the EM24 register value to engineering units?

Most EM24 holding registers are scaled by a factor of 10 or 100. For example, register 0x0000 (Voltage L1) returns 2304 for 230.4 V. Divide the raw UINT16 by the documented scale factor (10, 100, or 1000) per the EM24 Modbus protocol guide for your firmware version.

Back to blog