CP341 Modbus Master RTU FB7 FB8 Multi-Slave Polling in PCS7 V9.0

David Krause20 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

1. Overview

The CP 341 communication processor is a serial point-to-point module for SIMATIC S7-300 (and ET 200M in PCS 7) that hosts the licensed Modbus Master RTU driver. The driver is implemented as a loadable firmware on the CP 341 and exposes two standard function blocks on the CPU side: FB 8 "P_SND_RK" for sending Modbus request frames and FB 7 "P_RCV_RK" for receiving response frames. Together they form the deterministic, half-duplex master layer for polling up to 247 Modbus RTU slaves on RS-232 or RS-485.

This reference documents a working PCS 7 V9.0 implementation that polls five Modbus RTU slaves using OB 32 as the cyclic dispatcher, DB 10 as the rotating parameter set, and DB 11 as the rolling receive buffer. It also clarifies how the NDR output of FB 7 behaves when a slave fails to respond, and how to detect that condition without losing the master state machine.

Note: FB 7 and FB 8 are part of the standard SIMATIC library and do not require a separate runtime license. The licensed element is the Modbus Master RTU driver flashed onto the CP 341.

2. Hardware Selection and Wiring

For PCS 7 V9.0 with five slaves on a single bus, the practical hardware choice is the RS-485 variant of the CP 341. RS-485 supports multi-drop, longer cable runs, and proper bus termination that RS-232 cannot provide.

MLFB Interface Max Distance Use Case
6ES7341-1AH02-0AE0 RS-232C (V.24) 15 m Single-drop, point-to-point
6ES7341-1CH02-0AE0 RS-422 / RS-485 (X27) 1200 m @ 9600 bps Multi-drop Modbus RTU bus

For an RS-485 bus, observe the following physical rules:

  1. Terminate both ends of the trunk with 120 Ω resistors between the data lines (P and N). The CP 341 RS-485 variant includes a slide switch on the front connector to enable the internal termination.
  2. Never put termination in the middle of the bus; only at the physical extremes.
  3. Use twisted-pair cable with shield grounded at one end only (typically the cabinet ground).
  4. Set the cable shield to FE on the CP end; do not loop it back to multiple grounds.
  5. Limit stubs (drop cables) to less than 30 cm. Daisy-chain from CP → slave 1 → slave 2 → slave 3 → slave 4 → slave 5 → termination.
Safety: When installing in PCS 7, route the bus cable in a separate duct from 230/400 V power. Maintain at least 100 mm clearance or use a grounded separator. The CP 341 must be installed in a SIMATIC S7-300 standard rack or in an ET 200M (PROFIBUS DP slave) when used as a distributed I/O station.

3. Software Stack and Licensing

The Modbus Master RTU driver is loaded onto the CP 341 once, using the SIMATIC Manager / PCS 7 Engineering "Modbus Master CP341" parameterization tool. The license is bound to the CP's serial number and survives firmware updates as long as the hardware is not replaced.

Component Version Purpose
STEP 7 / PCS 7 Engineering V9.0 (or compatible V9.0 SPx) Hardware config, FB library, DB generation
CP 341 Modbus Master RTU driver V3.x (driver CD shipped with module or download) Loads Modbus protocol stack on CP firmware
Modbus Master license Per-CP, model 6ES7341-1CH02-0AE0 Unlocks the RTU master firmware
CP 341 firmware FW 2.x (depending on driver rev.) CP base firmware, required by driver

After loading the driver, the CP 341's online diagnostics ("Diagnostic buffer of the CP") will report "Modbus Master RTU active". Until the driver is loaded, FB 7/FB 8 calls will return STATUS = W#16#818C ("CP not ready").

4. CP 341 Configuration in HW Config

Insert the CP 341 in the S7-300 rack at the slot planned for it (typically slot 4 through 11, depending on the CPU and existing modules). In the object properties, set:

Parameter Recommended Value Notes
Protocol Modbus Master RTU Selectable only if driver is licensed
Baud rate 9600 bps (start) → 19200 bps typical Must match all slaves
Data bits 8 RTU fixed
Parity Even (preferred for legacy RTU) or None Match slave configuration exactly
Stop bits 1 (with Even/None parity) or 2 Match slave configuration exactly
Flow control None RTU does not use RTS/CTS for slave polls
Reply monitoring time 2000 ms (adjust per baud) 3.5 char minimum silence, driver uses calculated time
Character delay time 4 ms typical Inter-character timeout (1.5 char time at given baud)
Parameter discipline: A common PCS 7 commissioning mistake is using 8N1 on the CPU side and 8E1 on the slave. The CP will report parity error (W#16#8188) and the entire bus appears dead. Lock the parameter set in a project standard so commissioning always starts from the same baseline.

5. Modbus Master Driver Configuration

Open the CP 341's "Protocol" object. The dialog lets you assign a Modbus Master configuration block. This is a DB that the driver parses on power-up to know which slave polling pattern to run automatically. In PCS 7 V9.0, the typical approach is to leave the CP in "Driver-controlled" mode and dispatch from the CPU via FB 7/FB 8 instead, giving the application full control of which slave is queried when.

The application-controlled pattern works as follows:

  1. The CPU writes the next Modbus request (slave address, function code, register offset, register count) into a shared parameter DB (here DB 10).
  2. The CPU calls FB 8 (P_SND_RK) with the parameter DB reference. The CP transmits the request on the wire.
  3. The CPU calls FB 7 (P_RCV_RK) on the same LADDR. When the CP has assembled a complete response, FB 7 returns NDR = TRUE and writes the response into a receive DB (here DB 11) at the offset supplied via DBB_NO.
  4. The application interprets the response, advances state, and after a defined inter-frame delay repeats for the next slave.

6. Function Block Architecture (FB 7 / FB 8)

FB 8 (P_SND_RK) and FB 7 (P_RCV_RK) live in the standard SIMATIC library under "Communication Blocks". They are instance-free (use the standard instance DBs that the library assigns automatically) and are called from OB 1 in this implementation:

  1. FB 8 — P_SND_RK: Sends a Modbus request buffer to the CP. Triggers the CP to transmit the request on the bus.
  2. FB 7 — P_RCV_RK: Reads the response buffer assembled by the CP. Returns NDR when a new response has been received since the last call.

Both blocks share the same LADDR input (the I/O base address of the CP 341 in HW Config). Calling FB 7/FB 8 with a different LADDR than the CP's logical base address will silently fail with STATUS = W#16#8183 or W#16#818C.

7. FB 8 P_SND_RK Parameterization

Wire FB 8 as follows. Inputs marked constant should be declared as local constants in the calling FC 10 to keep OB 1 clean.

Input Type Value Description
SF BOOL M10.0 Send trigger. Edge from 0→1 starts a send job.
LADDR INT 256 (example) CP 341 logical base address from HW Config.
DB_NO INT 10 DB containing the Modbus request payload (slave ID, FC, offset, count).
DBB_NO INT 0 Byte offset in DB 10 where the request starts.
LEN INT 8 Length of the request buffer (typically 8 bytes for a single read/write). Range 1–4096.
R BOOL FALSE Reset/abort the job. Not used in steady-state operation.

The output DONE (here M10.1) signals successful transmission. A negative edge on DONE is the natural moment to clear the SF trigger.

Trigger discipline: Always drive SF with a one-shot (rising-edge bit) generated in the calling FC. Re-triggering SF while the CP is busy returns STATUS = W#16#8183 without harming the bus, but it can corrupt the state machine if not debounced. The original implementation resets M10.0 on the falling edge of M10.1 — that is the correct Siemens-recommended pattern.

8. FB 7 P_RCV_RK Parameterization

FB 7 reads the response that the CP 341 has buffered since the last successful send.

Input Type Value Description
EN_R BOOL TRUE Enable receiver — must stay TRUE for the block to fetch data.
R BOOL FALSE Receiver reset (rarely used; clears the internal NDR latch).
LADDR INT 256 (same as FB 8) CP 341 logical base address.
DB_NO INT 11 Receive data DB.
DBB_NO INT 0 / 32 / 64 / … Offset in DB 11. Increment per slave to keep a rolling buffer.
LEN INT Variable Max receive length. Must be ≥ actual response length.

The two outputs you monitor are:

  • NDR (New Data Ready) — pulses TRUE for one cycle when a complete response has been fetched. This is the application-level "slave answered" signal.
  • ERROR + STATUS — surfaces Modbus errors, frame errors, timeouts, and CP errors.
Important: NDR does not pulse if the slave does not respond. The application sees no NDR transition and FB 7's STATUS stays at W#16#7000 (idle). After the driver's internal reply-monitoring time expires, the CP raises a timeout condition internally; FB 7 surfaces that as STATUS = W#16#8185 on a subsequent call if the implementation uses the application-triggered receive. The reliable way to detect a non-responsive slave is therefore to start a watchdog timer in the FC and to flag "slave N failed" if NDR does not occur within the configured timeout window.

9. OB 32 Cyclic Polling Implementation

OB 32 in PCS 7 runs at a configurable base time. The recommended base for Modbus RTU at 9600 baud with 5 slaves is 1 s; the implementation in question uses a 5 s phase to be conservative on slow slaves. The OB 32 logic is the rotating index over the five slaves.

Pseudo-code for OB 32 (SCL-style for readability, equivalent ladder exists):


// State variable in a global DB
iSlaveIdx := (iSlaveIdx + 1) MOD 5;

// Populate DB 10 from a static array of 5 slave descriptors
DB10.SlaveAddr    := SlaveDesc[iSlaveIdx].Addr;     // e.g. 1..5
DB10.FunctionCode := SlaveDesc[iSlaveIdx].FC;       // e.g. 03 = Read Holding
DB10.StartAddr    := SWAP_WORD(SlaveDesc[iSlaveIdx].Reg); // Modbus is big-endian
DB10.Quantity     := SWAP_WORD(SlaveDesc[iSlaveIdx].Qty);
DB10.ByteCount    := SlaveDesc[iSlaveIdx].Qty * 2;
DB10.RequestLen   := 8;
DB10.ReceiveOffset := iSlaveIdx * 64;               // 64 bytes per slot in DB 11

// Arm the send trigger for OB 1
M10.0 := TRUE;

// Latch the OB 32 "ready" flag so OB 1 knows DB 10 has been refreshed
M11.0 := TRUE;

OB 1 calls FC 10, which in turn calls FB 8 and FB 7 in the sequence:


// FC 10 (called from OB 1)
IF M11.0 THEN                       // OB 32 just refreshed DB 10
  FB8.DB_NO  := 10;
  FB8.DBB_NO := 0;
  FB8.LEN    := DB10.RequestLen;
  FB8.SF     := M10.0;             // rising edge starts send
  FB8.LADDR  := 256;

  IF M10.1 THEN                    // send done (DONE flag)
    M10.0 := FALSE;                // clear trigger (negative-edge clear in OB 1)
    FB7.EN_R  := TRUE;
    FB7.DB_NO := 11;
    FB7.DBB_NO := DB10.ReceiveOffset;
    FB7.LEN    := 256;             // receive buffer max
  END_IF;

  IF FB7.NDR THEN                  // response received
    // parse DB11 starting at DB10.ReceiveOffset
    M11.0 := FALSE;                // clear "OB 32 ready" flag
  END_IF;
END_IF;
Critical: Do not write to DB 10 inside OB 32 while OB 1 is mid-send. The 5 s OB 32 phase is far slower than a typical 10–50 ms Modbus cycle, so the design is inherently safe — but if you shrink OB 32 below the Modbus turnaround time you must gate OB 32 with M11.0 and only let it advance when M11.0 is FALSE (i.e., OB 1 has consumed the previous request).

10. Multi-Slave Data Structure

The recommended layout is a single DB 10 holding the active request (8 bytes + 1 length byte) and DB 11 holding the rolling response buffer with one fixed slot per slave. This keeps OB 32 trivial and makes commissioning differences between slaves easy to diagnose.

10.1 DB 10 — Active Request

Offset Symbol Type Description
0.0 SlaveAddr BYTE 1..247 (Modbus RTU address)
1.0 FunctionCode BYTE 01/02/03/04/05/06/15/16
2.0 StartAddr WORD Register offset, high-byte first (big-endian)
4.0 Quantity WORD Number of registers or coils
6.0 ByteCount BYTE Quantity × 2 (read holding/input) or quantity ÷ 8 (read coils)
7.0 RequestLen BYTE Length of the request frame on the wire
8.0 ReceiveOffset INT Slot in DB 11 to write the response

10.2 DB 11 — Rolling Response Buffer

Each slave occupies a 64-byte slot. Five slaves = 320 bytes. Reserve at least 8 bytes of header inside each slot for the parsed fields (slave address echo, FC echo, byte count, CRC status, timestamp).

Slot Offset Contents
Slave 1 0..63 Parsed response 1, timestamp, status
Slave 2 64..127 Parsed response 2, timestamp, status
Slave 3 128..191 Parsed response 3, timestamp, status
Slave 4 192..255 Parsed response 4, timestamp, status
Slave 5 256..319 Parsed response 5, timestamp, status

11. Slave Failure Detection via NDR

There are three failure modes to handle explicitly. The NDR signal alone is insufficient — it must be paired with a watchdog and an explicit "expecting response" flag.

11.1 Slave does not respond (timeout)

Symptom: SF rises → DONE rises (request transmitted) → NDR never rises → STATUS stays at W#16#7000.

Detection: Start a TON timer (e.g., 500 ms above the CP's configured reply monitoring). If the timer elapses without NDR, set a "slave N comm fault" flag.

11.2 Slave responds with Modbus exception

Symptom: NDR rises, but the FC byte in the response has bit 7 set (e.g., 0x83 instead of 0x03). The exception code in the next byte indicates ILLEGAL FUNCTION (01), ILLEGAL DATA ADDRESS (02), ILLEGAL DATA VALUE (03), etc.

Detection: After NDR, inspect the FC byte. If FC >= 0x80, branch into the exception handler and surface the exception code in a global alarm DB.

11.3 Slave responds with corrupt frame (CRC error)

Symptom: CP rejects the frame internally; FB 7 raises STATUS = W#16#8187 (frame error) instead of NDR.

Detection: Treat STATUS > W#16#8180 as a transport-level fault, do not advance the state machine, and log the slave ID + STATUS value.

Suggested watchdog implementation in FC 10:


// Run only while a response is expected
IF M10.1 AND NOT M10.6 THEN        // sent but not yet received
  iWatchdog := iWatchdog + 1;
  IF iWatchdog > 50 THEN           // 50 × 100 ms = 5 s
    bSlaveFault[DB10.SlaveAddr] := TRUE;
    M11.0 := FALSE;                // advance to next slave anyway
    M10.0 := TRUE;                 // arm next poll cycle
    iWatchdog := 0;
  END_IF;
ELSE
  iWatchdog := 0;
END_IF;
Engineering tip: Do not let a single slave timeout stall the bus. Even when slave N is offline, OB 32 must continue advancing so that slaves N+1, N+2 still get polled. The original implementation triggers the next FB 8 send via the OB 32 "data changed" flag regardless of the receive outcome — that is the correct pattern. Add a debounce of at least one full frame turnaround (3.5 character times) before the next send to satisfy the Modbus RTU silent interval.

12. Modbus Exception Code Mapping

When a Modbus slave answers with an exception, the response FC byte has the high bit set (0x80 OR'd with the original FC) and a one-byte exception code follows. The application must decode this and surface it to the operator.

Code Name Typical Cause in PCS 7 Polling
01 ILLEGAL FUNCTION Slave does not support the FC; e.g. attempting FC 06 write single register on a read-only meter.
02 ILLEGAL DATA ADDRESS StartAddr in DB 10 is outside the slave's address map; offset the request by the slave's Modbus register base.
03 ILLEGAL DATA VALUE Quantity > allowed max, or write value outside valid range.
04 SLAVE DEVICE FAILURE Internal slave error while processing; retry once with backoff before raising an alarm.
05 ACKNOWLEDGE Long-running command accepted but not complete; poll again after a delay.
06 SLAVE DEVICE BUSY Retry with exponential backoff.
08 MEMORY PARITY ERROR Slave internal memory fault — escalate to maintenance.
0A GATEWAY PATH UNAVAILABLE Router / gateway behind the slave is offline.
0B GATEWAY TARGET NO RESPONSE Downstream device behind the gateway did not respond.

13. Status and Error Code Reference

The following STATUS codes are surfaced on FB 7 and FB 8 when the Modbus Master RTU driver is loaded. They are returned in W#16# notation and should be mapped 1:1 into an operator-visible diagnostic block.

STATUS Block Meaning Recommended Action
0000 Both Job completed without error None
7000 Both No job active / receiver idle Normal idle state
8181 SND/RCV Length mismatch between SD and LEN Correct LEN parameter
8182 SND/RCV DB too short or DB number 0 Increase DB length; verify DB_NO
8183 SND/RCV Parameter assignment error (e.g. wrong LADDR) Re-check CP slot and LADDR
8184 RCV Modbus exception in response Inspect exception code in DB 11
8185 RCV Reply timeout — slave did not respond Check slave power, address, baud
8186 RCV Negative acknowledgment from CP Re-initialize CP
8187 RCV Frame error (invalid stop bits, framing) Match baud/parity/stop bits to slave
8188 RCV Parity error Match parity; check cable
8189 RCV Overrun error Reduce baud rate or inter-frame spacing
818A RCV Receive buffer overflow Increase LEN or reduce slave response size
818B SND CP internal parameter error Reload driver firmware
818C Both CP not ready / driver not loaded Load Modbus Master RTU driver
818D SND L_TW mismatch Match LEN to actual buffer length

14. OB 32 / OB 1 Timing

The following diagram illustrates the interlock between OB 32 (slow dispatcher) and OB 1 (fast driver caller). The 5 s phase is the OB 32 base time; the actual Modbus cycle is on the order of 50–200 ms at 9600 baud.

OB32 FB8 FB7 Refresh DB10 (slave 1) Refresh DB10 (slave 2) Refresh DB10 (slave 3) Refresh DB10 (slave 4) Send request (SF↑ → DONE↑) Send request (slave 2) Receive (NDR↑) or timeout Receive (slave 2)

15. Troubleshooting Matrix

Observed Symptom Likely Cause Diagnostic Step Fix
Every send returns W#16#818C Modbus Master driver not loaded CP online diagnostics → Operating Mode Re-load driver, verify license
DONE rises but NDR never rises, STATUS = 7000 Slave power off / wrong address / wrong baud Modbus scanner tool on the bus Confirm slave power, address DIP, baud match
NDR rises with FC byte ≥ 0x80 Modbus exception Read exception code byte Correct StartAddr, Quantity, or FC choice
STATUS = W#16#8187 (frame error) on every poll Baud / parity mismatch Verify slave configuration register Adjust CP protocol parameters in HW Config
STATUS = W#16#8188 (parity error) sporadic Electrical noise / long cable / no termination Oscilloscope on bus Enable termination, check shield, shorten stubs
STATUS = W#16#8185 (timeout) on slave 3 only Slave 3 address conflict or removed from bus Disconnect slaves one by one Fix addressing or restore slave
OB 32 fires but DB 10 unchanged Index not advancing, MOD operation broken Online watch iSlaveIdx in VAT Check MOD boundary; ensure integer variable is reset on restart
CPU scan time increase after enabling CP FB 7 / FB 8 executed every cycle OB 1 time stamp delta Gate FB calls behind M11.0 to save CPU
Receive data scrambled between slaves DBB_NO not updated per slave Watch DB 11 in VAT Recompute ReceiveOffset = iSlaveIdx × 64 in OB 32

16. Verification and Commissioning Procedure

  1. Driver load verification: In HW Config, open the CP 341 → "Operating Mode" → confirm "Modbus Master RTU driver loaded". Without this, every send returns W#16#818C.
  2. Loopback test: Connect the CP 341 RS-485 ports together (T/R+ ↔ T/R- on both ends) with a short jumper. Run the master against slave address 1 with FC 03 reading 1 register from offset 0. The CP will echo its own request; the CRC will fail and STATUS = W#16#8187. This confirms wiring and baud, isolating it from the slaves.
  3. Single-slave test: Connect one known-good slave (e.g., a Modbus simulator or a Schneider electric meter). Confirm NDR pulses and STATUS = W#16#0000 on the first request.
  4. Multi-slave sequential test: With OB 32 stepping through five slaves at 5 s, observe the slave LED activity on each physical device. Each slave should see one request per cycle of five phases.
  5. Negative test: Power down slave 3. Confirm that the master continues polling slaves 1, 2, 4, 5 and that the slave 3 fault flag sets within the configured watchdog window.
  6. Watchdog boundary test: Reduce the slave reply time below the CP's configured reply monitoring to force STATUS = W#16#8185. Verify the application flags the correct slave and recovers automatically when the slave reappears.
  7. Long-run stability: Run for 24 h, log all STATUS values to a circular buffer, and verify zero unexpected codes.
  8. CPU scan budget: Profile OB 1 with FB 7 + FB 8 active. The blocks add roughly 1–3 ms per call to the scan. At 5 s OB 32 phase this is negligible; at 100 ms phase it becomes visible and should be re-measured.
  9. WinCC faceplate check: If the Modbus data drives a WinCC faceplate, verify the scaling block (engineering units → raw 0–27648 or floating point) is correct on each faceplate instance, and that the value is being read from the right DB 11 slot.

For reference, the SIMATIC Modbus documentation set shipped with the driver and the TIA Portal documentation portal cover the same FBs from a different angle. The MODB_341 instruction, for example, is the modern equivalent used when the CP is configured via TIA Portal V20 instead of STEP 7 V5 / PCS 7:

The PCS 7 V9.0 / STEP 7 V5.6 path uses FB 7 / FB 8 (P_SND_RK / P_RCV_RK) and is documented in the Modbus Master CP 341 manual that ships on the driver CD (Siemens/Documentation shortcut after install).

18. Frequently Asked Questions

Can FB 8 and FB 7 be called from OB 1 directly, or do they need an instance FC?

Yes — calling them from OB 1 directly is the standard pattern. The "instance" in this case is the standard instance DB the library assigns to each block. Using an intermediate FC 10 only helps keep OB 1 readable and provides one place to put the negative-edge logic for clearing M10.0.

Is the NDR bit on FB 7 sufficient to detect a failed slave?

No. NDR only pulses when the CP successfully receives and validates a frame. A non-responsive slave never causes NDR to rise. You must pair FB 7 with a watchdog timer started when the send completes (DONE = TRUE) and not reset until NDR arrives. If the watchdog expires before NDR, that is your slave-failed condition.

Why does STATUS stay at W#16#7000 even though the slave is wired and powered?

W#16#7000 on FB 7 means the receiver is idle — no new data has been assembled since the last read. This is normal between Modbus cycles. If it stays 7000 forever and NDR never rises, the most likely cause is that FB 8 never actually transmitted: check that SF produced a real rising edge, that LADDR matches the CP slot, and that the CP's driver is loaded (otherwise STATUS on FB 8 would be W#16#818C).

Do I need the Modbus Master RTU driver license?

Yes. The Modbus Master RTU driver is a separately licensed firmware that must be loaded onto the CP 341. The CPU-side FB 7 / FB 8 blocks are part of the standard library and do not require a runtime license; the license is bound to the CP's serial number.

What is the maximum number of slaves I can poll with a single CP 341?

The Modbus RTU standard supports up to 247 slaves per bus. Practical limits on a CP 341 are: baud rate (higher baud = faster cycle but shorter cable), slave response size, and CPU scan budget. With five slaves and a 5 s OB 32 phase the bus is essentially idle 99 % of the time, so a single CP 341 can comfortably poll 20–30 slaves at 9600 baud with sub-second effective cycle.

Can the same CP 341 run Modbus Master RTU and Modbus Slave RTU simultaneously?

No. A CP 341 loaded with the Modbus Master RTU driver is a master only. To run as a slave, reload the CP with the Modbus Slave RTU driver, which exposes the MODB_341 instruction on the CPU side instead of FB 7 / FB 8.

Back to blog