Troubleshooting CP341 Serial Latency on S7-300: RXD Buffer Fix

David Krause17 min read
Serial CommunicationSiemensTroubleshooting
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

Troubleshooting CP341 Serial Latency on S7-300: RXD Buffer Fix

1. Problem Overview

The Siemens CP 341 point-to-point communication processor is one of the most-deployed serial modules on the S7-300 platform, used for ASCII, 3964(R), and Modbus RTU traffic against instruments, bar-code readers, scales, length meters, and drives. In field commissioning it is not uncommon for the same module that worked in the test bench to behave poorly once installed in the cabinet: the RXD LED latches on for several seconds, the receive "done" bit fires only every few OB1 cycles, the application timeout trips, and the operator complains that the value on the HMI lags the partner device by several seconds.

This article documents a real failure mode observed on a carpet-line length meter connected to a CP 341 (S7-300, S7-400) RS-422 variant (order number 6ES7 341-1BH02-0AE0). The RXD LED stayed continuously lit for 2–6 seconds at a time, the receive block in OB1 returned NDR = 0 repeatedly, and the "COID\r\n" reset command was queued behind several telegrams in the FIFO. The wiring, the partner device, the cable length, and the protocol parameters were all identical to the test bench where the link worked perfectly. The root cause was neither the cable nor the partner — it was a mismatch between the CP341 receive FIFO depth, the OB1 cycle time of the CPU, and the number of times the receive FB was called per cycle.

Key insight: The CP341 ASCII driver is a transparent byte-stream service. It does not push data to the PLC; OB1 must pull it. If the pull rate is slower than the push rate of the partner, bytes accumulate in the FIFO, the RXD LED appears "stuck on", and the application sees a long latency that looks like a hardware problem but is purely a polling problem.

2. CP341 Hardware and Firmware Reference

The CP341 is a single-channel point-to-point module that occupies one slot in an S7-300 rack. Three hardware variants are released for the production-grade (non-simulation) module:

Order Number Electrical Interface Front Connector Max Baud Rate (loadable driver) Supported Protocols
6ES7 341-1AH01-0AE0 / 1AH02-0AE0 RS-232C (V.24) 15-pin Sub-D, male 38.4 kbps (FW 2.0+ supports 115.2 kbps) ASCII, 3964(R), Modbus RTU master/slave
6ES7 341-1BH01-0AE0 / 1BH02-0AE0 RS-422 / RS-485 (X27) 15-pin Sub-D, male 38.4 / 115.2 kbps ASCII, 3964(R), Modbus RTU master/slave
6ES7 341-1CH01-0AE0 / 1CH02-0AE0 TTY (20 mA current loop) 9-pin Sub-D, female 19.2 kbps ASCII, 3964(R)

The communication firmware ("loadable driver") is downloaded from the CP341's flash into the module on hardware configuration. Supported driver files include:

  • PtP_ASCII_Vxx.hex — transparent ASCII byte stream
  • PtP_3964R_Vxx.hex — Siemens 3964(R) protocol
  • PtP_MBUS_Vxx.hex — Modbus RTU master (CP341 initiates)
  • PtP_MBUS_S_Vxx.hex — Modbus RTU slave (CP341 responds)

Per the Siemens configuration manual for point-to-point links, the ASCII driver exposes a 1024-byte receive FIFO and a 1024-byte send FIFO. There is no on-module protocol stack and no automatic message-bounding — the driver just shovels bytes in and out of the FIFO. Telegram reconstruction (split, reassemble, strip delimiter) is the responsibility of the user program. Modbus RTU mode offloads that reconstruction to the on-module stack and is the recommended path if the partner supports Modbus.

3. Symptoms Reported in the Field

The following was observed on the carpet-line installation with the CP 341-1BH02-0AE0 RS-422 variant configured for 38.4 kbps, 8 data bits, no parity, 1 stop bit, ASCII driver:

  • CP341 RXD LED stays continuously lit for 2–6 seconds, then briefly blinks off, then latches on again.
  • Receive FB (P_RCV, FB2) returns DONE / NDR = 0 for 3–6 consecutive OB1 cycles, then returns NDR = 1 with the full backlog of bytes.
  • Operator reset command ("COID\r\n" sent via P_SEND / FB3) is queued behind the receive backlog; the HMI counter does not reset within the expected 200 ms.
  • Carpet line keeps producing while the meter still displays the previous length — measured HMI lag was 3.2 s at 18 m/min line speed, 14.4 m at 80 m/min.
  • In the test bench with a 0.5 m cable and a faster CPU, the same code reads every character within one OB1 scan. No code or hardware change was made between test and field installation.

4. Root Cause: FIFO Polling Rate vs. OB1 Cycle Time

The CP341's receive FIFO holds incoming bytes until the application reads them through P_RCV. The driver does not push data to the PLC; OB1 has to pull it. Each P_RCV call on a successful telegram copies a single completed telegram (terminated by the configured end delimiter in ASCII mode — CR, LF, CR+LF, or user-defined) out of the FIFO and into the user data area.

The carpet-meter partner device transmits length telegrams every 100 ms without request, i.e. it is a pure broadcaster. At 38.4 kbps, 8N1, a 14-character telegram "L=00012345\r\n" (14 bytes) takes about 3.65 ms wire time. The CPU in this installation runs OB1 at approximately 18 ms in the test bench and approximately 65 ms in the field after the larger program (3 FBs of motion control and 4 FBs of recipe handling) was downloaded.

Environment OB1 cycle P_RCV calls per second Telegrams per second Polling ratio Result
Test bench 18 ms ~55 10 (every 100 ms) 5.5 : 1 Stable. FIFO holds 0–1 frames.
Field 65 ms ~15 10 1.5 : 1 Unstable. FIFO holds 1–4 frames; RXD LED appears stuck on.

In the test bench, one telegram per ~100 ms and one P_RCV call per ~18 ms gives 5–6 polling opportunities per telegram — the FIFO never accumulates more than one frame, and the RXD LED only blinks on briefly for the duration of the wire time.

In the field, one telegram per 100 ms and one P_RCV call per 65 ms gives less than 1.5 polling opportunities per telegram. Several frames pile up between P_RCV calls, the RXD LED stays lit while the FIFO holds more than one frame, and the DONE bit only fires when the FIFO is read. Worst case, the FIFO fills to its 1024-byte limit and the CP341 starts dropping characters. The drop is reported as a "Receiver FIFO overflow" counter increment in the online diagnostics.

Rule of thumb for any CP341 application:
f_polling (Hz) >= f_telegram (Hz) × 2
If the polling rate is below the incoming telegram rate, characters will accumulate, RXD will appear "stuck on", and the user program will see gaps.

5. Additional Causes Confirmed During Diagnosis

The Siemens SiePortal thread on Modbus Communication using CP-341 in S7-300 highlights the same class of issue: when OB1 scan time is too long, the user program must be reorganized so the receive block runs in every cycle regardless of where it sits in the call tree. Five common contributors found during diagnosis are listed below.

5.1 Single-call polling in OB1

Calling the receive function (in this case FC130 wrapping P_RCV) once per OB1 and only on a conditional rung starves the FIFO if the condition is rarely true. The condition must be TRUE every cycle until NDR goes high. Wrapping the call in IF bPoll THEN P_RCV(...); END_IF; with bPoll toggled by some upstream logic is a frequent cause of intermittent reception.

5.2 OB35 at 5 ms is not free

Trying to fix slow polling by moving the receive block into OB35 (5 ms cyclic interrupt) makes the OB1 cycle time go up because OB35 preempts OB1. The net effect is no improvement and a higher overall jitter, especially because the motion-control FBs in OB1 are now fragmented by interrupts. A 50–100 ms OB35 is acceptable, but 5 ms is not for this workload.

5.3 Enable handling on P_RCV

The receive enable input (EN_R on FB2 P_RCV) must be TRUE continuously while the receive is in progress. Toggling EN_R between calls cancels the in-progress read and forces a re-start of the receiver FSM. Leave EN_R stuck at TRUE; use NDR and ERROR as the only state bits.

5.4 Send request handling

The send request (REQ on FB3 P_SEND) must be a single-scan pulse, not a level. Pulsing REQ during an in-progress receive aborts the receive. The pulse should occur only after the receive NDR bit, receive ERROR bit, or a programmed timeout has fired. Holding REQ = 1 for more than one OB1 cycle is the most common send-side bug seen on this module.

5.5 Field environment

EMI from a 250 kW variable-frequency drive in the next cabinet, missing shield ground at one end, or a non-isolated RS-232 to RS-422 converter sitting near a contactor can corrupt characters and trigger the "receive error" branch in P_RCV. The test bench has none of these. Always check ground bonding and shield termination before re-tuning the program — a software fix applied on top of a hardware noise problem will not hold in production.

6. Diagnostic Procedure

  1. Open STEP 7 → HW Config → CP341 → Properties → Diagnostics. Read the diagnostic buffer of the module (via SFC 51 "RDSYSST" with SZL_ID = W#16#00D1 / index W#16#0000 to W#16#000F) or the "Module Information" right-click in the PG online view.
  2. Open the online CP341 diagnostic screen. Note the Received telegrams, Transmitted telegrams, Receiver FIFO overflow, and Receiver parity/framing errors counters. The first two should grow at the expected telegram rate; the second two should be zero.
  3. Use a serial-line tap (e.g. a Y-cable on RS-422 plus a USB-to-RS422 dongle on a laptop running a terminal at the same baud rate) to capture wire traffic. Verify that the partner is actually transmitting at the rate the application expects, and that the telegram structure matches the configured end-delimiter in HW Config.
  4. In OB1, add a temporary CTU counter that increments on every OB1 cycle (CU := TRUE in an unconditional rung) and a second counter that increments on every P_RCV call. Download and watch the ratio in VAT online. A ratio of 1:1 with P_RCV called only once per cycle indicates the polling rate is the bottleneck.
  5. Check the CP341 firmware version (read from the module's diagnostic buffer, byte 0) against the loadable driver version (visible in HW Config → CP341 → Properties → "Loadable Driver"). Mismatched firmware and driver .hex are a known source of dropped characters and FIFO lock-ups. Use the driver version that ships with the module's firmware; STEP 7 will warn at hardware configuration download if they are incompatible.
  6. Verify the diagnostic-interrupt OB (OB82) is present in the program. Without OB82 the CPU goes to STOP on a CP341 diagnostic interrupt (e.g. wire break, FIFO overflow), and the application has no recovery path.

7. Solution: Code and Cycle Time

The minimum, scope-limited fix is to call P_RCV at least 2–4 times per OB1 cycle until the NDR bit latches. The structural fix is to keep OB1 scan time under 30 ms for any application where the partner transmits faster than 2 Hz.

7.1 Polling loop in OB1

In S7-SCL (recommended) or ladder, call P_RCV in a loop until it returns NDR = 0:

// S7-SCL fragment, STEP 7 V5.x
// "rcvBuf" is a 256-byte ARRAY of BYTE shared via INOUT
// "rcvLen" is INT, length of last received telegram
// "rcvDone" is BOOL, set on each successful NDR
// "CP341_RCV" is an instance DB of FB2 P_RCV

rcvDone := FALSE;
FOR i := 1 TO 8 DO                  // up to 8 drains per OB1 scan
    "CP341_RCV"(REQ   := FALSE,    // ASCII receiver: REQ unused
                EN_R  := TRUE,      // always enabled, do NOT toggle
                RCV   := "rcvBuf",
                LEN   := 256,
                RST   := FALSE,
                NDR   := ndr,
                ERROR := err,
                LADDR := 256,      // CP341 logical base address
                DB_NO := 100);     // not used by ASCII driver
    IF ndr THEN
        rcvDone := TRUE;
        rcvLen  := "CP341_RCV".LEN;
        // copy rcvBuf[0..rcvLen-1] into application ring buffer
    END_IF;
    IF err THEN
        // log error and clear with RST pulse for one cycle
    END_IF;
END_FOR;

Calling the FB 8 times per OB1 gives an 8 × 65 ms = 520 ms drain window per real-time second, more than enough to keep up with a 100 ms broadcast at 38.4 kbps.

7.2 Send request handling

Pulse REQ for exactly one cycle after the receive has completed or timed out. In ladder this is typically implemented as a one-shot on the trailing edge of the receive NDR / ERROR / timeout, or as a positive edge from an operator pushbutton debounce FB:

// S7-SCL fragment for "COID\r\n" send pulse
// Trigger conditions: operator button, or timeout watchdog, or first scan
IF sendTrigger AND NOT sendTriggerOld THEN
    "CP341_SND".REQ := TRUE;
ELSE
    "CP341_SND".REQ := FALSE;
END_IF;
sendTriggerOld := sendTrigger;

// Load send buffer once on first scan
IF firstScan THEN
    "sndBuf[0]" := BYTE#16#43;  // 'C'
    "sndBuf[1]" := BYTE#16#4F;  // 'O'
    "sndBuf[2]" := BYTE#16#49;  // 'I'
    "sndBuf[3]" := BYTE#16#44;  // 'D'
    "sndBuf[4]" := BYTE#16#0D;  // CR
    "sndBuf[5]" := BYTE#16#0A;  // LF
    "sndLen"    := 6;
END_IF;

7.3 Timeout watchdog

ASCII driver has no built-in timeout. Use a TON with PT = 500 ms. On expiry, pulse REQ for the reset ("COID\r\n") command and continue. Without a watchdog a single dropped byte on the wire can stall the receive forever, and the RXD LED appears "stuck on" for tens of seconds.

7.4 Move the receive block

If OB1 is unavoidably slow (> 100 ms), call P_RCV from a time-of-day interrupt OB (OB10) at 50–100 ms. Do not use OB35 at 5 ms; the preemption cost outweighs the benefit. OB10 is non-preempting in the same priority class as OB1 when configured with a phase offset, and the call tree is clean.

7.5 Verify environment

  • Confirm the shield is bonded to ground at exactly one end (typically the CP341 end for RS-422).
  • Confirm the RS-422 terminator (typically 120 Ω between + and –) is present at the receiver, not at the sender. Two terminators in parallel halve the impedance and over-damp the signal, which causes inter-symbol jitter and intermittent framing errors.
  • Confirm the partner device's GND (pin 5 of the X27 connector on the CP341 side) is tied to the CP341's GND. Floating ground is the number-one cause of intermittent framing errors that look like slow polling.
  • Confirm the cable is twisted-pair and shielded, with each signal on its own pair (TX+/TX–, RX+/RX–). Using a non-twisted multi-core cable for RS-422 collapses the differential margin.

8. Verification

After the code change, verify with the following checklist:

  • Online diagnostic counters: Receiver FIFO overflow = 0 for 10 minutes of continuous operation.
  • P_RCV NDR pulses at least once per OB1 cycle in steady state.
  • Operator reset command ("COID\r\n") is sent within 200 ms of the reset button being pressed.
  • Length display in the HMI updates within 1 s of the partner's display.
  • RXD LED on CP341 blinks off between telegrams, not stuck on.
  • OB1 scan time stays below 50 ms (watched via the cycle-time OB or SFC 78 "OB_RT" in STEP 7).

If FIFO overflow is still non-zero, either the partner is broadcasting faster than expected, the CPU scan time has crept up again, or the loadable driver version is mismatched with the firmware. In the first case, increase the loop count from 8 to 16 and recheck. In the second case, profile OB1 with the cycle-time OB and identify the FB that has grown. In the third case, delete the CP341 from HW Config, re-insert it, allow STEP 7 to re-push the correct driver, and re-download the hardware configuration.

9. Common Errors and Pitfalls

Error Symptom Fix
P_RCV EN_R toggled by a condition Receive works only in some OB1 cycles; FIFO overflow grows slowly Always TRUE. Use NDR and ERROR as state.
P_SEND REQ held TRUE for many cycles Send telegrams overlap, receive aborts with parity/frame error Single-cycle pulse, triggered on NDR trailing edge or operator edge.
Instance DB for P_RCV / P_SEND not downloaded CPU goes to STOP with SF on CP341; "Instance DB missing" diagnostic Generate instance DB from FB "special object" property and download with the program.
Driver version mismatch Random character drops, FIFO overflow grows, RXD LED flickers Delete CP341 from HW Config, re-insert, allow STEP 7 to re-push driver, re-download HW Config.
"No Communication" or "Interface Error" diagnostic after a hot-swap CP341 does not re-initialise after firmware change Power-cycle the module or trigger re-initialise via SFC 51.
ASCII driver configured with wrong end delimiter P_RCV never sets NDR; RXD LED blinks at telegram rate but no data in PLC Set end delimiter in HW Config to match what the partner transmits (CR, LF, CR+LF, or user-defined bytes).
OB82 missing CPU goes to STOP on FIFO overflow Add empty OB82 to the program.
RS-422 terminator on sender only Inter-symbol jitter, sporadic framing errors at 38.4 kbps+ Move 120 Ω terminator to receiver end of the bus.

10. Quick-Reference Parameter Table

Parameter ASCII driver 3964(R) driver Modbus master Modbus slave
Baud rate 110 – 115200 bps 110 – 115200 bps 110 – 38400 bps (19200 typical) 110 – 38400 bps
Parity None / Even / Odd None / Even / Odd None / Even / Odd None / Even / Odd
Data bits 7 or 8 7 or 8 8 8
Stop bits 1 or 2 1 or 2 1 or 2 1 or 2
End delimiter CR / LF / CR+LF / user-defined (protocol managed) (protocol managed) (protocol managed)
RX FIFO size 1024 bytes 1024 bytes 1024 bytes 1024 bytes
TX FIFO size 1024 bytes 1024 bytes 1024 bytes 1024 bytes
Send FB FB3 (P_SEND) FB3 (P_SEND) FB8 (P_SND_RK) / FB9 (P_SND_M) FB11 (P_SLV_R) / FB13 (P_SLV_T)
Receive FB FB2 (P_RCV) FB2 (P_RCV) FB7 (P_RCV_RK) / FB10 (P_RCV_M) FB10 (P_SLV_T)

Use the order-number suffix in HW Config to pick the right loadable driver. The driver file lives on the STEP 7 PG at Siemens\Automation\S7-...\Drivers and is pushed to the module on first download. The CP341 firmware version is read from the module's diagnostic buffer, byte 0, and must match the driver.

11. Performance Calculation for Receiver Polling

Use the following formula to dimension the loop count of the receive block:

loopCount_min = ceil( (t_telegram_ms + slack) / t_OB1_ms )

where
  t_telegram_ms = partner transmit period in ms
                 (broadcast: 100 ms in the example above)
  slack          = 0.5 to 1.0 (50%–100% headroom for jitter)
  t_OB1_ms       = measured OB1 cycle time in ms (65 ms in the example)

For the carpet line:
  loopCount_min = ceil( (100 + 100) / 65 ) = ceil(3.08) = 4
  recommended   = 8 (gives 2× headroom for jitter, partner slowdowns, FB growth)

If loopCount_min exceeds 16, OB1 is too slow for the partner's transmit rate. Move the receive block into OB10 at 50–100 ms, or upgrade the CPU to a 315-2 PN/DP or 317-2 PN/DP to reduce OB1 baseline cycle time.

12. Related Siemens Documentation

13. Frequently Asked Questions

Why does my CP341 RXD LED stay continuously lit on the S7-300?

Incoming bytes are arriving faster than the OB1 cycle is calling P_RCV, so the 1024-byte receive FIFO is filling with multiple telegrams. Either shorten the OB1 cycle, increase the number of P_RCV calls per cycle, or move the receive block to OB10 at 50–100 ms.

What is the correct baud rate range for the CP 341 RS-422 variant (6ES7 341-1BH02-0AE0)?

Up to 115.2 kbps in firmware 2.0 and later, with the loadable ASCII, 3964(R), Modbus RTU master, or Modbus RTU slave driver. The earlier 1BH01-0AE0 variant is limited to 38.4 kbps.

Should I use OB35 at 5 ms to make CP341 reception faster on the S7-300?

No. OB35 at 5 ms preempts OB1 and inflates the baseline cycle time. Use OB35 at 50–100 ms, or call P_RCV 4–8 times in a loop in OB1, or move the receive block to OB10. Verify with the CP341 online diagnostic counters that "Receiver FIFO overflow" stays at zero.

My CPU goes to STOP with SF on the CP341 after a firmware change. What is missing?

Most likely the loadable driver version in HW Config does not match the CP341's firmware, or the instance DB for P_RCV / P_SEND was not downloaded. Delete the CP341 from HW Config, re-insert it, allow STEP 7 to re-push the correct driver, regenerate the instance DB, and re-download. Also add an empty OB82 to handle diagnostic interrupts.

How do I switch a CP 341 from ASCII to Modbus RTU master on S7-300?

Open HW Config → CP341 → Properties → Parameter Assignment, change the "Protocol" selection to "Modbus Master", and download the hardware configuration. The CP341 will load the Modbus master driver PtP_MBUS_Vxx.hex. Replace FB2 P_RCV / FB3 P_SEND with FB7 P_RCV_RK / FB8 P_SND_RK (send/receive with RK512-style data record) or FB9 P_SND_M / FB10 P_RCV_M for register-level Modbus. See the CP 341 (S7-300, S7-400) manual for the exact FB-to-driver mapping.

Back to blog