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.
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:
- 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 theDATA_PTRofMB_MASTERcan address it byte-accurately. - Drop eight
MB_MASTERinstances:MB_MASTER_1throughMB_MASTER_8. Wire eachREQinput to a unique clock-bit from the cyclic OB (for example"Clock_50ms".ET_Pulse[0]through"Clock_50ms".ET_Pulse[7]). - Configure
MB_ADDR= 1,MODE= 0 (RTU),DATA_ADDR= the drive's holding-register offset for the parameter, andDATA_LEN= 1. The single-word length guarantees the read will never span a hole. - Wire
DATA_PTRto the matching array inDriveData. Stagger theREQpulses by at least 10 ms to avoid back-to-back collisions on the bus. - Map
DONEto a "data valid" boolean consumed by your HMI; mapERRORto a centralised fault routine.STATUSshould 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_CLIENTexposesSTATUScodes 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
- Insert a new
MB_MASTERinstance from Libraries > Communication > MODBUS (RTU). - On the instance DB, expose
REQ,MB_ADDR,MODE,DATA_ADDR,DATA_LEN,DATA_PTR,DONE,ERROR, andSTATUS. - Create a non-optimised global DB
"ModbusBuffers"with one byte array per slot.DATA_PTRmust 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. - Set
MB_ADDR= 1,MODE= 0,DATA_ADDR= the parameter's register offset, andDATA_LEN= 1. - Drive
REQfrom 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
- 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.
- Go online and open the instance DB for
MB_MASTER_1. ForceREQtoTRUEfor one scan. VerifyDONEtransitions toTRUEwithin 50 ms andSTATUS= 0x0000. - Watch the destination array in
DriveData. The read should populate the matching slot within one or two 50 ms ticks. - Repeat for each
MB_MASTERinstance in turn. Confirm that no two instances raiseREQsimultaneously; the CB 1241 driver will respond withSTATUS= 0x80C8 (data area conflict) if the buffer is reused incorrectly. - Disconnect the RS-485 cable from the CFW500 to simulate a slave timeout.
MB_MASTER.ERRORshould rise,STATUSshould read 0x80D1 (timeout), and the destination buffer should remain unchanged from its previous value. - Reconnect and confirm the next valid
REQedge 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_MASTERon 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 returnsSTATUS= 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.