S7-1200 Modbus RTU: Reading Non-Consecutive WEG CFW500 Registers

David Krause15 min read
ModbusSiemensTroubleshooting
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

Problem Overview

An S7-1200 CPU (firmware V4.x or later) communicating over Modbus RTU through a CM 1241 or CB 1241 RS-485 communication module often hits a hard wall when a downstream device such as the WEG CFW500 Variable Frequency Drive (VFD) exposes non-consecutive parameter numbers. The PLC's MB_MASTER instruction is the documented Modbus RTU master block, and although it advertises a maximum payload of 125 holding registers, the read collapses entirely when the slave leaves even a single hole in the requested address range. The symptom is unmistakable: every destination word in the buffer is left untouched and MB_MASTER.DONE returns TRUE without raising an ERROR. A 45 ms block read turns into a 500 ms parameter-by-parameter poll, and operators waiting on drive feedback notice the delay.

This article dissects the root cause, lays out three production-ready remedies (multiple parallel MB_MASTER instances, optimised single-register polling, and migration to Modbus TCP), and shows how to verify each fix on the bench. Code samples are written in Structured Text (SCL) for TIA Portal V17 and later, and ladder snippets are included where helpful.

System Architecture and Reference Hardware

Component Model / Version Role
CPU SIMATIC S7-1214C DC/DC/DC, firmware V4.6 (6ES7214-1AG40-0XB0) Modbus RTU master, executes user program and MB_MASTER
Communication module CB 1241 (6ES7241-1CH30-1XB0), RS-485 half-duplex Physical layer for Modbus RTU; configured at 38400 8N2 to match CFW500 default
Drive WEG CFW500 series, firmware 3.0X, Modbus RTU slave address 1 Holds drive parameters P0000 through P1023 accessible as Holding Registers 0-1023 (function code 03) and Input Registers (function code 04)
Engineering TIA Portal V17 with S7-1200 HSP Project, library references, and SCL source editing

The CB 1241 plugs into the left bus of the S7-1200 and is auto-discovered after power-up. The RS-485 port is wired A-to-A, B-to-B, and shield to PE at one end only. A 120 Ω termination is enabled on the last device; on the CB 1241 this is a DIP switch (position ON) inside the module door. The CFW500 is configured through parameter P0308 (slave address), P0310 (baud), and P0311 (parity/stop bits).

Modbus RTU Fundamentals on the S7-1200

Modbus RTU is a request/response protocol carried over a single multi-drop RS-485 bus. The master issues a function code, a starting address, and a quantity; the slave replies with the same function code echoed and the requested payload. The crucial constraint is that the address range is always contiguous. Function code 03 (Read Holding Registers) and function code 04 (Read Input Registers) both expect the slave to return Q consecutive 16-bit words starting at A. There is no built-in mechanism to skip holes in the range.

The Siemens Modbus RTU overview for S7-1200 / S7-1500 documents that the MB_MASTER instruction accepts a DATA_LEN of 1 to 125 words for function codes 03/04 and 1 to 123 words for function code 23 (read/write multiple registers). Larger quantities are silently clipped by the instruction's internal buffer. The official Siemens support entry on input register reading also confirms that function code 04 is limited to addresses 0-9998 on the S7-1200; if the drive maps a parameter above 9998, the master must use function code 03 against the holding register range or split the read into multiple function code 04 transactions.

Root Cause: Why a Single Hole Kills the Whole Read

The CFW500 user manual (section 8.2, page 23 of the Modbus RTU supplement) states that a valid request and response telegram cannot exceed 64 bytes. Function code 03 replies are framed as [1 byte addr][1 byte FC][1 byte byte count][2N bytes data][2 bytes CRC]. For 32 words this is exactly 68 bytes, which is already over the 64-byte ceiling, so the practical upper limit is 30 words per request when the slave is a CFW500. Inside the requested range, the drive replies with whatever 16-bit values it has stored at each address. Parameters that the manufacturer reserved but never implemented (P0008 in the example, or any "not used" parameter between two populated ones) return 0x0000 on most CFW500 firmware revisions. The driver does not crash, but the field engineer who tried to read P0007 + P0008 + P0009 in a single block was looking at a slave that simply returned 0x0000 for the missing word while P0007 and P0009 still populated correctly.

Why does the PLC see the whole buffer empty? Two failure modes are commonly confused. The first is a genuine slave error: the CFW500 firmware rejects the request when the requested address goes beyond the highest populated register, and never replies, so the master times out at the configured MB_MASTER timeout (default 1000 ms) and leaves the destination untouched. The second is an alignment error: the user accidentally typed DATA_PTR to a non-optimised DB that was too small, and the MB_MASTER then refuses to write because the length does not fit. Always inspect MB_MASTER.STATUS (word output) to distinguish 0x80C8 (data area too small) from 0x80D0/0x80D1 (timeout) from 0x0000 (clean success with zero data).

If the parameter hole is small and well-defined (for example only P0008 is missing), the cleaner remedy is to ask the vendor whether the drive can be re-mapped. WEG exposes a "modbus mapping" table in parameter group P0680-P0689 (function 06 writes). Reserving a placeholder value in those words forces the slave to reply with a non-zero value for the missing address, which in turn lets the master read P0007-P0009 in one transaction again. Refer to the CFW500 Modbus RTU communication manual section on parameter remapping before assuming the polling workaround is unavoidable.

Strategy 1: Multiple Parallel MB_MASTER Instances

The simplest performance fix is to use several MB_MASTER blocks, each issuing a smaller request against an isolated destination buffer. The S7-1200 CB 1241 can queue up to 4 simultaneous MB_MASTER calls on a single physical port; the underlying driver serialises them in transmit order, but the application can prepare the next request while the previous one is outstanding. This means an eight-instance approach reduces a 12-parameter scan from ~500 ms to ~120 ms without any new hardware.

Steps in TIA Portal V17:

  1. Create a global DB named "DriveData" with one array per parameter: MotorSpeed : ARRAY[0..0] OF WORD;, MotorCurrent : ARRAY[0..0] OF WORD;, and so on. Each array must be a multiple of two bytes so the DATA_PTR of MB_MASTER can address it byte-accurately.
  2. Drop eight MB_MASTER instances: MB_MASTER_1 through MB_MASTER_8. Wire each REQ input to a unique clock-bit from the cyclic OB (for example "Clock_50ms".ET_Pulse[0] through "Clock_50ms".ET_Pulse[7]).
  3. Configure MB_ADDR = 1, MODE = 0 (RTU), DATA_ADDR = the drive's holding-register offset for the parameter, and DATA_LEN = 1. The single-word length guarantees the read will never span a hole.
  4. Wire DATA_PTR to the matching array in DriveData. Stagger the REQ pulses by at least 10 ms to avoid back-to-back collisions on the bus.
  5. Map DONE to a "data valid" boolean consumed by your HMI; map ERROR to a centralised fault routine. STATUS should be logged to a 16-word ring buffer for diagnostics.

For SCL implementers, the following fragment shows a typical poll body. It assumes a hardware interrupt OB (OB40) generates a 50 ms tick.

// FB_DrivePoll — single-parameter Modbus RTU poll scheduler
// Each call advances one outstanding request and consumes the result.

IF #schedulerTick THEN
    CASE #activeSlot OF
        0: #mbMaster.REQ := #trigger0;
        1: #mbMaster.REQ := #trigger1;
        2: #mbMaster.REQ := #trigger2;
        ...
        7: #mbMaster.REQ := #trigger7;
    END_CASE;
END_IF;

IF #mbMaster.DONE THEN
    #activeSlot := (#activeSlot + 1) MOD 8;
END_IF;

Strategy 2: Single-Register Polling with Priority Scheduling

Where the application only needs a handful of fast values and a larger number of slow values, the cleanest pattern is priority scheduling. A critical parameter (motor current at P0003) is polled every 20 ms; a secondary parameter (heatsink temperature at P0031) is polled every 200 ms; a diagnostic parameter (P0090 power-on hours) is polled every 5 s. This decouples scan time from parameter count and avoids running 12 simultaneous MB_MASTER blocks.

Implement the schedule in an FB that owns an array of PollDescriptor UDTs:

TYPE PollDescriptor :
STRUCT
    dataAddr    : UINT;   // Modbus holding register address (zero-based)
    interval    : TIME;   // e.g. T#20ms, T#200ms, T#5s
    lastCall    : TIME;   // timestamp of last REQ edge
    destPtr     ^WORD;    // AT-view into DriveData
END_STRUCT
END_TYPE

The scheduler scans the array, issues REQ := TRUE on entries whose (currentTime - lastCall) >= interval, and clears the REQ on the next DONE. A single MB_MASTER instance services all slots round-robin, and because no more than one transaction is in flight at a time, the bus is deterministic. Total scan time for the 12-parameter example drops from 500 ms to roughly 280 ms even with the round-robin overhead.

Strategy 3: Migration to Modbus TCP

If the application can tolerate a small hardware change, the cleanest path is the WEG CFW500 Ethernet/IP & Modbus TCP module (plug-in accessory, part number 15069021 or equivalent for the matching CFW500 frame). The S7-1200 supports MB_CLIENT from firmware V4.1 onward, and the PROFINET interface of the CPU can open up to 8 TCP connections concurrently to one or more slaves.

Key advantages of TCP over RTU for this problem:

  • Independent transactions can be issued in parallel without bus arbitration. The 12-parameter scan finishes in < 80 ms because the OS-level socket layer pipelines them.
  • The 64-byte CFW500 telegram limit still applies, but the driver can pre-allocate a TCP segment larger than 64 bytes and the slave still answers within the constraint.
  • Diagnostics are richer: MB_CLIENT exposes STATUS codes that map directly to the Modbus exception response (illegal data address = 02, illegal data value = 03, slave device failure = 04).

Disadvantages to weigh: the TCP module on the CFW500 is still a serial-to-TCP gateway in some firmware revisions, so the 64-byte cap and one-master-at-a-time constraints are inherited from the RS-485 side. Always confirm with the accessory's user manual that the firmware supports a true Modbus TCP server, not just a transparent bridge.

Performance Comparison

Approach Bus load 12-param scan time PLC work memory Code complexity Hardware change
Single 8-word block read (current behaviour, fails when hole exists) 1 transaction per scan 45 ms (only when all 8 exist) Low Low None
Single-parameter poll, no scheduler 12 transactions per scan ~500 ms Low Low None
Eight parallel MB_MASTER instances 4 concurrent on CB 1241, rest queued ~120 ms Medium (~1.2 KB for 8 DBs) Medium None
Priority-scheduled round-robin 1 transaction at a time ~280 ms (12 params, mixed intervals) Low Medium None
Modbus TCP via CFW500 accessory Up to 8 TCP sockets, 64-byte cap retained on serial side ~80 ms Low Medium-High Ethernet plug-in module

WEG CFW500 Parameter Map Reference

The CFW500 exposes its parameters as standard Modbus holding registers at address = parameter number. The default communication settings assume address 1, 38400 baud, 8 data bits, no parity, 2 stop bits (8N2). Adjust the CB 1241 port configuration under Device configuration > CB 1241 > Properties > Port configuration to match.

Parameter Description Modbus FC Register address Data type
P0001 Speed reference (%) 03 0 INT 0-10000 (×0.01 %)
P0002 Motor speed (rpm) 03 1 INT signed
P0003 Motor current (A ×10) 03 2 UINT
P0007 Output voltage (V) 03 6 UINT
P0009 Output power (kW ×10) 03 8 UINT
P0031 IGBT heatsink temperature (°C) 03 30 INT signed
P0090 Power-on hours counter 03 89 UINT
P0220-P0229 User-mappable area (function 06 writes) 06/03 219-228 UINT

Holes in the parameter map (e.g. between P0007 and P0009) are factory-reserved. Each "not used" word is reachable on the bus but returns 0x0000 on firmware V3.0X. WEG can supply a per-firmware Parameter List spreadsheet that highlights which numbers are populated; pair this with the official CFW500 Modbus manual so that the S7-1200 engineer knows the exact request range.

Programming the MB_MASTER Block in TIA Portal

  1. Insert a new MB_MASTER instance from Libraries > Communication > MODBUS (RTU).
  2. On the instance DB, expose REQ, MB_ADDR, MODE, DATA_ADDR, DATA_LEN, DATA_PTR, DONE, ERROR, and STATUS.
  3. Create a non-optimised global DB "ModbusBuffers" with one byte array per slot. DATA_PTR must reference a non-optimised area; this is the single most common reason the read "returns nothing" on S7-1200 V4.x. If you are using an optimised DB, switch it off under DB properties > Attributes > Optimised block access.
  4. Set MB_ADDR = 1, MODE = 0, DATA_ADDR = the parameter's register offset, and DATA_LEN = 1.
  5. Drive REQ from a rising-edge trigger; never tie it to the cyclic OB unconditionally, or the instruction will issue a fresh transaction every scan and starve the bus.

Ladder equivalent of the trigger logic:

|   Clock_50ms   Cycle_OK   |
+-----[P]----+--------( )----(MB_MASTER_1.REQ)
|                                    |
+---[MB_MASTER_1.DONE]---[RESET]---/

Verification Procedure

  1. Compile and download the project to the S7-1214. Ensure the CB 1241 is plugged in and powered before download; otherwise TIA Portal will refuse to bind the port configuration.
  2. Go online and open the instance DB for MB_MASTER_1. Force REQ to TRUE for one scan. Verify DONE transitions to TRUE within 50 ms and STATUS = 0x0000.
  3. Watch the destination array in DriveData. The read should populate the matching slot within one or two 50 ms ticks.
  4. Repeat for each MB_MASTER instance in turn. Confirm that no two instances raise REQ simultaneously; the CB 1241 driver will respond with STATUS = 0x80C8 (data area conflict) if the buffer is reused incorrectly.
  5. Disconnect the RS-485 cable from the CFW500 to simulate a slave timeout. MB_MASTER.ERROR should rise, STATUS should read 0x80D1 (timeout), and the destination buffer should remain unchanged from its previous value.
  6. Reconnect and confirm the next valid REQ edge recovers the link without cycling the CPU.

Troubleshooting Matrix

Symptom Likely cause STATUS code Corrective action
Block read returns 0 for all words Hole in slave parameter map; or non-optimised DB mis-sized 0x0000 with empty data, or 0x80C8 Split the read into single-word transactions or remap the hole through CFW500 user area P0220-P0229
MB_MASTER.DONE never asserts RS-485 wiring swap (A-B reversed) or termination missing 0x80D0 / 0x80D1 (timeout) Verify A-A, B-B wiring; enable 120 Ω on last device; check shield
DONE asserts with garbage data Baud/parity mismatch between CB 1241 and CFW500 0x0000 (no error, wrong data) Set CB 1241 to 38400 8N2 to match CFW500 P0310/P0311
First read OK, subsequent reads fail Destination buffer overlaps next slot; DATA_PTR misaligned 0x80C8 Use separate DB arrays for each parameter and verify byte offsets
All eight MB_MASTER instances time out Bus contention from too many simultaneous REQ edges 0x80D1 Stagger REQ pulses by at least 10 ms; cap concurrent instances at 4 on CB 1241
Slave returns Modbus exception 02 (illegal data address) Request asks for register above CFW500 maximum (P1023) or above 9998 input register on S7-1200 0x8380/0x8381 (exception from slave) Clamp DATA_ADDR + DATA_LEN to the populated range; switch from FC04 to FC03 for holding registers
Performance slow on 12 parameters Single-register poll without scheduler 0x0000 (no error, slow) Implement priority scheduler or migrate to Modbus TCP
MB_MASTER instance disabled in CPU CB 1241 not configured or port disabled by user 0x0000 (instruction not executed) Open Device configuration > CB 1241 > Properties > Port configuration and enable Modbus RTU master

Diagnostic Capture Snippet

Use the following SCL block to log every Modbus transaction into a ring buffer for the next day's review. It catches both errors and the data so a post-mortem on a missed poll is fast.

// FB_ModbusDiag — diagnostic ring buffer (64 entries)
IF #mbMaster.ERROR THEN
    #logIndex := (#logIndex + 1) MOD 64;
    #logTime[#logIndex]      := RT_CLK_RD(T#0s, _clk);
    #logStatus[#logIndex]    := #mbMaster.STATUS;
    #logDataAddr[#logIndex]  := #mbMaster.DATA_ADDR;
    #logDataLen[#logIndex]   := #mbMaster.DATA_LEN;
END_IF;

Export logTime, logStatus, logDataAddr, and logDataLen to a watch table and save as CSV for trend analysis. This is the fastest way to confirm whether a given poll ever actually completed, and whether the slave ever returned an exception code that the S7-1200 silently ignored.

Field-Proven Caveats

  • The 64-byte CFW500 telegram cap is a hard physical limit. If the user is reading more than 30 holding registers in one transaction, the slave will not respond at all and the master will time out, not raise an exception.
  • Some early CFW500 firmware revisions (V2.4X) returned 0xFFFF instead of 0x0000 for unused parameters. Treat any read that yields 0xFFFF as a "hole not yet mapped" rather than a real 65535 value.
  • CB 1241 RS-485 termination is shared with the next module; if the next device in the line is also a CB 1241 with termination enabled, the bus is over-terminated and reads become intermittent. Enable termination on exactly one device.
  • MB_MASTER on the S7-1200 cannot be called from more than one priority class at the same time. If a fast OB35 also issues a request while OB1 is mid-transaction, the second call is dropped and returns STATUS = 0x80C8. Always serialise Modbus traffic in OB1 (or in a single fast OB that owns the instruction).

FAQ

Why does my S7-1200 MB_MASTER read of 8 WEG CFW500 parameters return all zeros when one parameter is missing?

The WEG CFW500 Modbus map reserves but does not populate some parameter numbers (for example, P0008). When MB_MASTER requests a contiguous range that crosses a reserved address, the slave either ignores the request entirely or returns zeros for the missing word. With function code 03 and a block length of 1, the master always reads a valid populated address and the symptom disappears.

What is the maximum number of holding registers the CFW500 supports per Modbus RTU transaction?

The CFW500 Modbus RTU manual, page 23, specifies a maximum telegram length of 64 bytes for both request and response. For function code 03, this limits the practical read to about 30 words per transaction. Stay below 30 words or split into multiple MB_MASTER calls to avoid slave timeouts.

Can I run more than one MB_MASTER call at the same time on a CB 1241?

Yes, the CB 1241 driver allows up to 4 concurrent MB_MASTER instances. The driver serialises their transmit phases, so from the bus side it still looks like one transaction at a time, but the application can prepare the next request while waiting on DONE. Stagger REQ edges by at least 10 ms to prevent STATUS = 0x80C8 collisions.

Does the S7-1200 support reading input registers above address 9998?

No. The S7-1200 MB_MASTER instruction with function code 04 (Read Input Registers) is limited to Modbus addresses 0-9998. For drives or power meters that map parameters above 9998, use function code 03 (Read Holding Registers) against the holding-register range, or split the read into multiple FC04 transactions below the 9998 ceiling.

Will switching to Modbus TCP fix the non-consecutive register problem?

Modbus TCP removes the RS-485 bus contention but does not relax the protocol rule that a single read must span consecutive registers. The real win from TCP is parallel socket transactions: with up to 8 simultaneous MB_CLIENT connections, a 12-parameter scan finishes in roughly 80 ms instead of 120 ms or 500 ms, even though each socket is still requesting one contiguous range.

Back to blog