CP 341 Modbus Master: Configuring Two Slaves for 64 Feeder Control
The CP 341 communications processor is one of the most widely deployed serial point-to-point modules for SIMATIC S7-300 systems. When used as a Modbus RTU master, it can poll and command multiple slave controllers on a shared RS-485 multi-drop bus. This article consolidates the field-engineering procedure for a representative project: a single CP 341 master polling two Xcell controllers that front-end 64 motor vision relays (one Xcell per 32-feeder group), reading status bits and writing start/stop control bits. It maps the required Modbus function codes (FC5, FC6, FC15, FC16) to the S7 program, addresses each slave uniquely on the bus, and provides a verification and troubleshooting matrix.
1. Overview of the System Topology
The reference topology has four physical layers:
- SIMATIC S7-300 CPU (e.g., 6ES7 315-2EH14) running the user program that issues Modbus requests.
- CP 341 module (e.g., 6ES7 341-1AH02-0AE0) inserted in the S7-300 rack and configured as the Modbus RTU master with the licensed Modbus Master RTU driver (order number 6ES7870-1AB01-0YA0).
- RS-485 multi-drop bus terminated at both ends with 120 Ω resistors. Maximum bus length is 1200 m at 9600 baud without repeaters, per the Modbus over serial line specification.
- Two Xcell slave controllers, each with a unique Modbus slave address (1 and 2) and a logical data block that exposes 32 motor-feeder status coils and 32 motor-feeder control coils.
The two Xcell controllers are connected to each other through their backplane bus for inter-controller data exchange. That backplane link is irrelevant to the Modbus master in the S7-300: from the CP 341 perspective, each Xcell is a stand-alone Modbus slave with its own station address. Do not assign the same slave ID to both units.
Figure 1 — CP 341 RS-485 multi-drop topology with two Xcell slaves.
2. Prerequisites
Before starting the configuration, confirm the following items are available and compatible.
| Item | Requirement | Notes |
|---|---|---|
| CP 341 module | 6ES7 341-1AH02-0AE0 (RS-485/422) or 6ES7 341-1BH02-0AE0 (RS-232) | RS-485 variant recommended for multi-drop. See the Siemens CP 341 product page. |
| Modbus Master RTU driver | 6ES7870-1AB01-0YA0 on a license disk | Loads onto the CP 341 flash; required for FB80 MODB_341 usage. |
| STEP 7 (SIMATIC Manager) | V5.5 + SP4 or later | CP 341 is configured in HW Config and via the PtP Param tool. |
| CP 341 PtP Parameter Assignment tool | Installs with STEP 7 | Generates the DB for FB80 and the protocol selection block FB7/FB8. |
| Cabling | Shielded twisted pair, 120 Ω termination at both ends | Use 2-wire RS-485 (D+, D-, SGND) on the CP 341 X27 connector. |
| Slave documentation | Modbus register map for each Xcell | Status coils, control coils, holding registers, slave ID. |
3. Modbus Protocol Fundamentals
Modbus is an application-layer messaging protocol developed by Modicon in 1979 for communication between programmable controllers. It follows a request/reply model in which one master initiates transactions with one or more slaves identified by addresses 1 to 247. Each transaction carries a function code that defines the operation, followed by a data field and a CRC for error detection on serial lines. Source: Wikipedia: Modbus and Modbus Tools protocol reference.
Four data primitives are exposed by every Modbus slave:
| Primitive | Size | Access | Read FC | Write FC | Typical Use |
|---|---|---|---|---|---|
| Coil | 1 bit | R/W | FC1 | FC5 (single), FC15 (multiple) | Digital outputs, start/stop commands |
| Discrete Input | 1 bit | RO | FC2 | — | Digital inputs, status flags |
| Input Register | 16 bit | RO | FC4 | — | Analogue measurements |
| Holding Register | 16 bit | R/W | FC3 | FC6 (single), FC16 (multiple) | Setpoints, packed bits, analogue out |
For the 64-feeder project the relevant function codes are:
- FC1 / FC2 — read status bits (coils or discrete inputs) from the Xcell. Use FC1 if the Xcell exposes motor status as coils; use FC2 if it exposes them as read-only discrete inputs.
- FC5 — write a single coil (one feeder start/stop). Useful for individual commands; FC15 is preferred when updating several feeders in one transaction.
- FC15 — write multiple coils. One Modbus request can update 1-1968 contiguous coils. No bit packing required at the slave because the protocol handles it.
- FC6 — write a single holding register. Used for analogue setpoints (e.g., soft-start ramp) or for one 16-bit packed control word.
- FC16 — write multiple holding registers. Used for bulk analogue writes or for transferring packed status/control words to the Xcell. Bit unpacking at the slave is then mandatory.
FC6 and FC16 are technically sufficient for the bit traffic if the Xcell stores its control/status in registers, but they force the slave to do bit-to-word unpacking. FC5/FC15 for digital and FC6/FC16 for analogue is the cleanest split and is the mapping used in the rest of this article.
4. Two-Slave Addressing Strategy
Each Modbus slave on the bus must have a unique 8-bit station ID in the range 1-247. The address is set on the Xcell through its configuration tool (typically a DIP switch, rotary switch, or its own setup page). The backplane connection between the two Xcell units is invisible to the S7-300 and is not a substitute for separate Modbus IDs.
| Slave | Modbus ID | Feeder Range | Status Coil Base | Control Coil Base |
|---|---|---|---|---|
| Xcell #1 | 1 | 1-32 | 0x0000 (0) | 0x0100 (256) |
| Xcell #2 | 2 | 33-64 | 0x0000 (0) | 0x0100 (256) |
| (reserved spare) | 3 | — | — | — |
The base addresses above are the typical convention when the Xcell uses one contiguous block of 32 coils for status and another for control. Replace them with the values documented in the Xcell register map. The CP 341 transmits the slave ID in every Modbus ADU, so the same Modbus address offset on two different slaves refers to two different physical points.
5. CP 341 Hardware Configuration
Open the SIMATIC Manager project for the S7-300 station and perform the following steps in HW Config.
- Insert the CP 341 from the catalog under SIMATIC 300 > CP-300 > Point-to-Point > CP 341. Select the order number 6ES7341-1AH02-0AE0 (RS-485/422) for multi-drop.
- Open the CP 341 properties dialog and assign it to a transmission speed and protocol. The defaults are ASCII / 9600 8N1. These will be overwritten in the PtP parameter assignment tool.
- Open the PtP Param tool from Start > SIMATIC > STEP 7 > PtP Param or directly from the CP 341 object in HW Config.
- In PtP Param, set:
- Protocol: Modbus Master RTU
- Baud rate: 9600 (or 19200 if the Xcell supports it; the entire bus must match)
- Parity: even, no parity, or odd — match the Xcell setting exactly
- Data bits: 8, Stop bits: 1 (Modbus RTU standard: 8E1 or 8N1)
- Response timeout: 2000 ms (default; raise to 5000 ms for slow radio modems or long cables)
- Generate the protocol-specific blocks. The tool produces a Universal protocol DB plus the option of using FB7/FB8 (P_RCV_RK / P_SND_RK) for manual protocol handling, or FB80 (MODB_341) if the Modbus master driver is licensed on the module.
- Download the HW Config and the protocol DB to the S7-300. The CP 341 will reset.
6. Job and Function-Code Mapping for 64 Feeders
Each Modbus transaction on FB80 is a job identified by a job number. The job table is built in the FB80 instance DB. The recommended allocation for this project is six jobs (three read, three write), keeping each job's payload small enough to avoid bus monopolization.
| Job # | Direction | FC | Slave ID | Start Addr (Modbus) | Quantity | Source/Dest DB Range | Purpose |
|---|---|---|---|---|---|---|---|
| 1 | Read | FC1 (Read Coils) | 1 | 0 | 32 | DB100.DBX0.0 - DB100.DBX3.7 | Status of feeders 1-32 (Xcell #1) |
| 2 | Read | FC1 (Read Coils) | 2 | 0 | 32 | DB100.DBX4.0 - DB100.DBX7.7 | Status of feeders 33-64 (Xcell #2) |
| 3 | Read | FC4 (Input Registers) | 1 | 0 | 8 | DB101.DBW0 - DB101.DBW14 | Analogue values 1-4 from Xcell #1 (e.g., currents) |
| 4 | Write | FC15 (Write Multiple Coils) | 1 | 256 | 32 | DB200.DBX0.0 - DB200.DBX3.7 | Start/stop feeders 1-32 |
| 5 | Write | FC15 (Write Multiple Coils) | 2 | 256 | 32 | DB200.DBX4.0 - DB200.DBX7.7 | Start/stop feeders 33-64 |
| 6 | Write | FC16 (Write Multiple Reg.) | 1 | 0 | 4 | DB201.DBW0 - DB201.DBW6 | Analogue setpoints to Xcell #1 |
| 7 | Write | FC5 (Write Single Coil) | 1 | 256 | 1 | DB202.DBX0.0 | Single-feeder pulse, e.g. reset |
Notes on the table:
- Job 3 and 6 use FC4 / FC16 because they carry 16-bit analogue values. The coils never share a job with registers because Modbus function codes are address-space-specific.
- Job 7 uses FC5 instead of FC15 because the application logic can only mark a single coil at a time (e.g., reset pulse). Issuing FC15 with 32 coils for a single-bit change is wasteful but legal; use FC5 to minimize bus traffic for rare single-bit events.
- The two read jobs (1 and 2) can be issued in parallel only if the CP 341 is configured for half-duplex RS-485 with a single driver. With the CP 341, FB80 internally serializes jobs, so polling cycle time is sum of job durations.
7. STEP 7 Program Skeleton
OB1 calls FB80 (MODB_341) once per scan. FB80's REQ input is edge-triggered to launch one job per call. A job sequencer rotates the JOB input 1 → 2 → 3 → 4 → 5 → 6 → 1 to give every job a chance to execute.
7.1 FB80 call (ST)
// OB1 - cyclic poll
// Inputs : iJobNo : INT - 1..7 selected job number
// iTrigger: BOOL - rising edge to launch
// InOut : done : BOOL - job finished, no error
// busy : BOOL - job in progress
// error : BOOL - error flag
// status : WORD - FB80 status code
// job : INT - last executed job
IF iTrigger THEN
FB80_DB.REQ := TRUE;
FB80_DB.JOB := iJobNo;
FB80_DB.DB_NO := 100; // read DB
FB80_DB.DBB_NO := 0; // offset for FC1/FC2/FC15
FB80_DB.LEN := 4; // 32 bits = 4 bytes
FB80_DB.WAIT_TM := 100; // 100 ms inter-character timeout
END_IF;
FB80_DB.REQ := iTrigger;
FB80_DB(REQ := FB80_DB.REQ,
JOB := iJobNo,
DB_NO := 100,
DBB_NO := 0,
LEN := 4,
WAIT_TM := 100,
DONE => done,
BUSY => busy,
ERROR => error,
STATUS => status,
JOB_DONE => job);
7.2 Job sequencer (Ladder excerpt)
U M 0.0 // sequencer enable
SPBNB _001
L MW 10 // current job
+ 1
T MW 10
L 7
>I // if current > 7 then reset
SPB _rst
BEA
_rst: L 0
T MW 10
_001: NOP 0
The sequencer produces a one-shot pulse per OB1 cycle. FB80 latches the job on the rising edge of REQ and runs it to completion asynchronously. The application monitors DONE and ERROR per job. Total poll time with seven jobs at 9600 baud is typically 60-150 ms, dominated by the FC4 and FC16 jobs (10 bytes/16-bit word at 8E1 ≈ 10.4 ms/word).
8. Verification Procedure
After download, verify correct operation in this order.
- Bus health. Open the CP 341 online diagnostics in STEP 7 (CP 341 > Diagnostics > Modbus Master). The transmitted/received frame counter should advance at the configured poll rate. A frozen counter indicates no successful exchanges.
- Slave response. Read the CP 341 diagnostic buffer. Look for W#16#0A0A (modbus exception from slave) versus W#16#0A01 (no response). An exception code 02 (illegal data address) means the Modbus address on the master does not exist in the slave; code 03 (illegal data value) usually means the quantity field is wrong.
- Data validation. In VAT or a watch table, force a known coil in DB200 (e.g., bit 0.0 = 1) and observe the corresponding feeder start in the field. Toggle the feeder hand switch and confirm DB100 bit flips in the watch table.
- Latency check. Time the interval between a feeder trip in the field and the corresponding status bit update in DB100. For 64 feeders at 9600 baud, end-to-end latency should be < 500 ms. If it exceeds 1 s, raise the baud rate to 19200 or 38400 if the cable run allows.
- CRC integrity. Run the bus for 24 hours and check the CP 341 CRC error counter. A non-zero count is acceptable up to about 1 in 10^6 frames. Above that, check shield grounding, termination, and cable routing away from VFD power cables.
9. Troubleshooting Matrix
| Symptom | FB80 STATUS | Likely Cause | Corrective Action |
|---|---|---|---|
| No response from any slave | W#16#0A01 | Wiring, termination, or slave power | Verify X27 pinout (D+ = pin 3, D- = pin 8, SGND = pin 5 on CP 341 RS-485). Confirm 120 Ω at both ends only. Power-cycle the Xcell. |
| No response from one slave | W#16#0A01 | Duplicate slave ID or wrong parity | Check the slave ID on the Xcell (must be unique). Match parity to the master (8E1 vs 8N1 mismatch is the most common). |
| Modbus exception 02 | W#16#0A0A, exception byte = 02 | Start address or quantity out of range | Compare the Modbus start address to the Xcell register map. Apply the -1 offset if the slave uses 1-based addressing. |
| Modbus exception 03 | W#16#0A0A, exception byte = 03 | Quantity field too large for the address space | Reduce LEN or split the request into two jobs. |
| CRC errors intermittent | W#16#0A02 | EMI, bad termination, long stub | Use a single daisy-chain, not a star. Add 120 Ω at both ends. Move cable away from VFD outputs. |
| First transaction works, second fails | W#16#0A01 | Missing inter-frame silence | Some Xcell firmware requires 3.5 character times between frames. Lower baud or use FC15 in place of repeated FC5 calls. |
| Status reads work, writes ignored | W#16#0A0A, exception = 04 | Slave is in read-only mode or coil is forced | Check the Xcell write-protection bit. Some Xcell variants only accept writes after a 'write enable' FC6 command. |
| All reads return 0xFFFF | W#16#0000 (no error) | Wrong Modbus primitive (coil vs register) selected | If the Xcell exposes status as a holding register, use FC3, not FC1. Check the Xcell register type column. |
10. Performance and Sizing Notes
For a 64-feeder system the Modbus traffic load is light, but the formulas are useful when scaling to additional Xcells.
For each FC1/FC15 transaction on RS-485 at 9600 baud, 8E1:
frame_time_per_byte = 1 / (9600 * (1 + 8 + 1 + 1)) // 8N1 worst case = 1/960 s
frame_bytes_FC15_n = 9 + ceil(n/8) // address(1)+FC(1)+addr(2)+qty(2)+byte_count(1)+coil_bytes+CRC(2)
frame_time_FC15_n = frame_bytes_FC15_n * frame_time_per_byte
≈ (11 + n/8) * 0.00115 s
For FC16 with m 16-bit registers:
frame_bytes_FC16_m = 13 + 2*m
frame_time_FC16_m = (13 + 2*m) * 0.00115 s
Examples at 9600 baud, 8E1:
| FC | Payload | Frame bytes | On-wire time |
|---|---|---|---|
| FC1, 32 coils | 32 status bits | 9 | ~10.4 ms |
| FC15, 32 coils | 32 control bits | 13 | ~14.9 ms |
| FC4, 8 registers | 8 analogue values | 21 | ~24.1 ms |
| FC16, 4 registers | 4 setpoints | 21 | ~24.1 ms |
Total seven-job poll cycle: roughly 110-150 ms. End-to-end response (excluding the Xcell's internal scan time of 50-200 ms) is therefore 160-350 ms, well below the typical 1 s operator expectation.
11. Safety and Commissioning Caveats
- Always confirm motor start/stop wiring is fail-safe. A write coil of 0 should be the de-energized state in the Xcell map, never the run state. Many Xcell platforms invert the convention.
- Isolate the Modbus bus from the field during loop checks. A spurious FC15 frame can start a motor if the wiring is energized.
- Document the Modbus register map in a controlled sheet (function code, address, type, scale, units). This is the single most valuable handover artifact.
- Log the CP 341 diagnostic buffer weekly until the site is stable. The 0x0A0x events are predictive of cable degradation long before the bus fails outright.
- Respect the maximum number of devices (32 electrical loads / 247 logical slaves) per RS-485 segment. Add an RS-485 repeater (e.g., 6ES7972-0AA01-0XA0) if you exceed either limit.
12. Frequently Asked Questions
Do the two Xcell slaves need different Modbus addresses if they share a backplane?
Yes. The backplane is a separate bus from the Modbus serial link. From the CP 341, each Xcell is a stand-alone Modbus slave and must have a unique 8-bit ID in the 1-247 range. Assign ID 1 to the first Xcell (feeders 1-32) and ID 2 to the second (feeders 33-64).
Should I use FC1/FC15 (coils) or FC3/FC16 (registers) for digital status and start/stop bits?
Prefer FC1/FC15 for digital I/O. The Modbus protocol handles bit packing for you and the slave logic stays simple. Use FC3/FC16 only when the Xcell stores its I/O in 16-bit holding registers or when you need to transfer analogue values in the same job.
How many jobs do I need for 64 feeders with both digital and analogue traffic?
Six to seven jobs is typical: two FC1 reads (one per slave), one or two FC4 reads for analogue, two FC15 writes for control bits, and one FC16 for analogue setpoints. Add a single-coil FC5 job if you need a dedicated reset pulse.
Why does FB80 return W#16#0A01 (no response) only on the second slave?
Either the second slave has the same Modbus address as the first (duplicate ID), its parity does not match the master, or its RS-485 fail-safe bias is misconfigured. Verify the slave ID is unique, set parity to match (8E1 or 8N1), and enable fail-safe bias on the Xcell if the bus is idle-low.
Can I poll both slaves in parallel from the CP 341?
No. FB80 MODB_341 serializes jobs internally over the single RS-485 port. The CP 341 will only drive one transaction at a time. If you need true simultaneous polling, move to an Ethernet-based Modbus TCP solution with a CP 343-1 or a Modbus TCP-capable S7-1200/1500 CPU.
What is the right baud rate for 64 feeders over RS-485?
9600 baud is sufficient for the read/write traffic described. Raise to 19200 or 38400 if your total poll cycle exceeds 500 ms or if you add additional Xcells. Match the baud on every device and keep the cable run under 1200 m at 9600, or under 200 m at 115200, per the Modbus over serial line specification.