CP 340 Modbus RTU to DCS Resolving CRC Errors and Protocol Limits

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

Problem Definition

A SIMATIC S7-300 station equipped with a CP 340 point-to-point communication processor must exchange process data with a Delta Distributed Control System (DCS) over a serial line. The DCS exposes only a Modbus RTU slave port (RS-485 two-wire, 9600 bit/s, 8E1) for third-party integration. The engineering team wires the CP 340 to the DCS, installs the SIMATIC PtP library shipped with STEP 7 V5.x, calls FB 2 P_SEND and FB 3 P_RCV in OB1, and begins hand-rolling Modbus request telegrams: slave address, function code, starting register, quantity, payload, and a manually computed CRC-16.

The very first transaction returns "CRC error" on the DCS engineering station. The PLC transmits frames that look correct in a serial analyzer, but the DCS rejects every telegram. Retries with reversed byte order, swapped polynomial, and different initial values of the CRC register (0xFFFF vs 0x0000) do not clear the fault.

This is a deterministic outcome of the CP 340 hardware/firmware design: the CP 340 does not contain a Modbus RTU data link layer. There is no on-board CRC-16 generator, no inter-frame timer, no automatic function-code dispatch, and no slave address filtering. The only protocols burned into the CP 340 firmware are ASCII and 3964R. Any Modbus RTU behavior on the wire is being synthesized in the PLC scan, and that synthesis cannot meet the timing tolerances the Modbus specification requires.

Root Cause

The CRC error reported by the Delta DCS is the visible symptom. Three independent root causes are stacked beneath it:

  1. Protocol mismatch. The CP 340 firmware contains no Modbus RTU driver. Per the official CP 340 manual, the loadable drivers available for the module are ASCII, 3964R, and a printer driver; Modbus RTU master/slave is not on that list. See the protocol matrix in the Siemens CP 340 PtP documentation.
  2. CRC-16 implementation drift. Modbus RTU specifies CRC-16 with polynomial 0xA001 (reflected 0x8005), initial value 0xFFFF, and no final XOR. Common PLC implementations compute the CRC over the wrong byte range, swap the low and high bytes when transmitting, transmit the CRC big-endian instead of little-endian, or include the silent interval bytes in the CRC window. Each of these defeats the DCS check.
  3. Inter-frame timing violations. Modbus RTU requires a 3.5 character silence to mark frame start and end, and frames must be transmitted as a contiguous stream. The PLC scan is non-deterministic (typically 10 to 80 ms); if the user program builds the telegram inside DBs and then hands it to P_SEND, the bytes are buffered in the CP and emitted back-to-back, which is fine, but if the CRC is computed by user code in OB1 with multiple intermediate function calls, the CP 340's send buffer can be flushed in two segments separated by more than the 1.5 character inter-character threshold — causing the DCS to interpret the second half as a new, malformed frame.
Field-proven fact: A Siemens applications engineer publicly stated that "implementing Modbus RTU on a CP 340 takes roughly 18 months of debugging" because the CP provides no protocol services. The recommendation from Siemens support is unambiguous: do not synthesize Modbus RTU on a CP 340.

CP 340 Hardware Identification

The CP 340 family is identified by MLFB (order number). Confirm the physical variant before any configuration work, because each interface type has different electrical limits and pin assignments.

MLFB Interface Max Baud Notes
6ES7340-1AH02-0AE0 RS-232C (V.24) 19.2 kbit/s TxD, RxD, RTS, CTS only — no Modbus
6ES7340-1BH02-0AE0 RS-485 (two-wire) 9.6 kbit/s Common choice for Modbus wiring, but firmware cannot run Modbus
6ES7340-1CH02-0AE0 RS-422 (four-wire) 19.2 kbit/s Full-duplex, point-to-point only

Every variant above carries firmware that exposes only two protocol drivers: ASCII (transparent character mode with optional start/end characters and configurable fill time) and 3964R (Siemens proprietary SDLC-like protocol used between S5 and S7 partners).

Protocol Matrix — What CP 340 Will and Will Not Run

Protocol CP 340 native CP 340 loadable CP 341 native CP 341 loadable
ASCII driver Yes (FB 2 / FB 3) Yes (FB 2 / FB 3)
3964R Yes (FB 2 / FB 3) Yes (FB 2 / FB 3)
Printer driver Yes (FB 4 / FB 5) Yes
Modbus RTU master No Third-party only No Yes — dongle license required
Modbus RTU slave No Third-party only No Yes — dongle license required
RK512 / 3964R with RK512 No No Yes — loadable driver

The Modbus RTU master/slave driver for CP 341 is sold as a separate package (MLFB 6ES7870-1AA01-0YA0 historically; the current designation lives under the SIMATIC S7-300 communication catalog). It is delivered on a floppy / DVD and bound to the CP 341 by a license key / hardware dongle. Without that dongle present on the CP 341, the loadable driver will not initialize and the CP falls back to ASCII / 3964R only.

Modbus RTU Frame Structure Expected by the DCS

Before choosing a fix, document exactly what the Delta DCS expects. A Modbus RTU frame follows this layout:

| Slave ID | Function Code | Data Field              | CRC-16 Lo | CRC-16 Hi |
| 1 byte   | 1 byte        | N bytes (variable)      | 1 byte    | 1 byte    |

For function code 03 (Read Holding Registers), the data field contains a 2-byte starting address, a 2-byte quantity, and the CRC-16 is computed over the entire preceding bytes (slave ID through last data byte). For function code 06 (Write Single Register), the data field contains 2-byte address and 2-byte value. For function code 16 (Write Multiple Registers), the data field contains 2-byte starting address, 2-byte quantity, 1-byte byte count, N x 2-byte registers.

CRC-16 parameters:

  • Polynomial: 0xA001 (reflected form of 0x8005)
  • Initial value: 0xFFFF
  • Final XOR: 0x0000
  • Byte order on the wire: low byte first, then high byte

A reference CRC-16 routine in Structured Text is shown later in the article so that engineers can verify the calculation when debugging third-party packages.

Solution Path Selection

Three legitimate solutions exist, ranked by Siemens-preferred order:

  1. Path A — Upgrade to CP 341 with Modbus master/slave loadable driver. The supported, sanctioned path. Adds hardware cost and one-day commissioning but eliminates CRC and timing concerns.
  2. Path B — Negotiate ASCII protocol with the DCS. If the Delta DCS exposes a generic ASCII serial port (many Delta controllers offer both Modbus RTU and a free-form ASCII channel), the existing CP 340 can be used with no hardware change.
  3. Path C — Third-party Modbus RTU driver for CP 340. Available from independent vendors. Provides FB blocks similar to the CP 341 set. Siemens provides no support for these packages, and they often target a specific CP 340 firmware revision.
Do not attempt to implement Modbus RTU on the CP 340 by manual CRC computation in the PLC user program. The DCS will report CRC errors intermittently, and the failure mode varies with PLC scan time, communication load, and operator station activity.

Solution Path A — Upgrade to CP 341 with Modbus Master

Hardware swap

  1. Power down the S7-300 rack.
  2. Remove the CP 340 module; preserve the backplane connector wiring list.
  3. Insert the CP 341 in the same slot. The CP 341 is pin-compatible at the backplane but requires its own MLFB per interface type:
    • 6ES7341-1AH02-0AE0 — RS-232C
    • 6ES7341-1BH02-0AE0 — RS-485 two-wire
    • 6ES7341-1CH02-0AE0 — RS-422/RS-485 four-wire
  4. Order the loadable Modbus driver license (dongle) from your Siemens distributor. The license is hardware-bound; one dongle authorizes one CP 341 module.
  5. Wire the serial connector identically to the CP 340 wiring. RS-485 two-wire is the typical Modbus RTU wiring: A+ to DCS A+, B− to DCS B−, shield to ground at one end only, 120 Ω termination at each end of the trunk.

STEP 7 hardware configuration

  1. Open the SIMATIC Manager project containing the S7-300 station.
  2. In HW Config, delete the CP 340 from the rack and insert the CP 341 in the same slot.
  3. Double-click the CP 341 to open its properties dialog. Under Interface, select the protocol: Modbus Master (RTU) or Modbus Slave (RTU). The CP 341 will refuse to load the driver if the dongle is not detected.
  4. Configure the serial line parameters: 9600 bit/s, 8 data bits, even parity, 1 stop bit (8E1 is the most common Delta DCS setting; verify against the DCS documentation).
  5. Set the CP 341 diagnostic interrupts if you want OB82 to fire on line faults.
  6. Save and download the hardware configuration.

STEP 7 program structure with the Modbus master library

The loadable Modbus master driver exposes two FBs (block numbers vary by driver version; the modern designation is in the SIMATIC manual that ships with the dongle). The typical call pattern is:

// OB1 — cyclic call
CALL FB_MODBUS_MASTER, DB_MODBUS
   REQ        := M_REQ_START        // start a single transaction
   ID          := 0                  // logical CP 341 address (from HW Config)
   slave_addr  := MB_SLAVE_ID        // 1..247, Delta DCS node
   function    := MB_FC_READ_HOLDING // 03, 06, 16 etc.
   start_addr  := MW_MODBUS_START    // 0-based register offset
   qty         := MW_MODBUS_QTY      // number of 16-bit registers
   tx_data_ptr := P#DB_TX.DBX0 BYTE 32
   rx_data_ptr := P#DB_RX.DBX0 BYTE 256
   done        := M_DONE
   error       := M_ERROR
   status      := MW_STATUS

The library handles CRC-16 generation, inter-frame silence, and response validation internally. The status word returned to MW_STATUS follows the Siemens Modbus master convention:

Status (hex) Meaning
0x0000 Idle / ready
0x7000 Job in progress
0x0001 Transaction complete, data valid
0x8181 Slave did not respond (timeout)
0x8182 CRC error in received frame
0x8183 Invalid function code from slave
0x8184 Invalid address from slave
0x8185 Invalid data value from slave
0x8186 Slave reports an exception (function code with high bit set)
0x8187 Memory allocation error in user DB
0x8188 Parity / framing error on the line

Map each of these status codes to a tag in the PLC and to an alarm or HMI message so that operators can distinguish a real DCS fault from a wiring fault.

Solution Path B — ASCII Protocol to Delta DCS

Many Delta DCS controllers (e.g., DVP series PLC used as DCS node, or AH series with serial card) expose a configurable ASCII mode. In this mode the DCS sends and receives CR/LF-terminated text strings. The CP 340 handles ASCII natively with FB 2 P_SEND and FB 3 P_RCV; no CRC, no Modbus framing, no third-party driver.

Configure the CP 340 for ASCII

  1. In HW Config, double-click the CP 340, select protocol ASCII.
  2. Set baud rate to match the DCS (9600 8N1 is the typical default for Delta).
  3. Set end-of-receive delimiter: CR (0x0D) or LF (0x0A) — match the DCS configuration exactly. If both are required, set both.
  4. Set fill character delay if the DCS is slow (10 to 50 ms is common).
  5. Disable XON/XOFF and disable any 3964R-specific parameters.

Application frame

Define a fixed-format text protocol with the DCS team. Example for a periodic data push:

<STX>PLC1,AI01=23.45,AI02=110.2,DI01=1<CR><LF>

The CP 340 transmits the entire DB byte-for-byte; the receiving DCS parses the CSV fields. CRC is not part of the protocol — protect integrity with a checksum character at the end of the line or rely on the parity bit and the periodic retransmission.

Solution Path C — Third-Party Modbus RTU Driver for CP 340

Independent vendors sell a Modbus RTU master/slave package that loads into a CP 340. Search the SIMATIC third-party catalog or contact your Siemens distributor for the current options. Each package typically provides:

  • A DLL / loadable firmware for the CP 340 module.
  • Two FBs callable from OB1 (one for sending, one for receiving) — block numbers vary by vendor; some assign FB 42 / FB 43 in the user project as the suggested block numbers, others use FB 100+.
  • An installation routine that registers the driver against a specific CP 340 firmware version (commonly 1.x and 2.x; check the matrix in the vendor's release notes).
Support boundary: Siemens technical support will not troubleshoot third-party drivers on a CP 340. If you go this route, secure a maintenance contract with the third-party vendor and document the exact driver version, CP 340 MLFB, and CP 340 firmware version. A STEP 7 upgrade that changes the CP 340 firmware can render the third-party driver inoperative.

Reference CRC-16 Routine for Diagnostic Use

When debugging a third-party driver or hand-rolled implementation, drop this Structured Text function into a STEP 7 SCL source file and call it from OB1 to compute the expected CRC of a buffer. Use it to compare against what arrives at the DCS or against what the CP transmits:

FUNCTION FC_CRC16 : WORD
VAR_INPUT
   pData   : POINTER TO BYTE;
   iLen    : INT;
END_VAR
VAR
   i       : INT;
   j       : INT;
   crc     : WORD;
   b       : BYTE;
END_VAR
BEGIN
   crc := 16#FFFF;
   FOR i := 0 TO iLen - 1 DO
      crc := crc XOR WORD(pData^[i]);
      FOR j := 0 TO 7 DO
         IF (crc AND 16#0001) <> 0 THEN
            crc := (SHR(crc,1) XOR 16#A001);
         ELSE
            crc := SHR(crc,1);
         END_IF;
      END_FOR;
   END_FOR;
   FC_CRC16 := crc;
END_FUNCTION

Test vector: 01 03 00 00 00 0A → CRC = C5CD, transmitted as CD C5 (low byte first).

Hardware Configuration Walk-Through (CP 340 ASCII Example)

  1. Open the STEP 7 project and load HW Config.
  2. Drag the CP 340 from the hardware catalog onto the S7-300 rack. Confirm slot number matches the physical module.
  3. Double-click the CP 340 → Properties. Set the interface to RS-485 if the DCS uses two-wire Modbus or to RS-232C for point-to-point ASCII.
  4. Select protocol ASCII. (The Modbus RTU option will not appear — this is the confirmation that the CP 340 cannot do Modbus natively.)
  5. Configure baud rate, parity, data bits, stop bits to match the DCS.
  6. Set the start-of-receive trigger if the DCS sends framing characters; otherwise leave blank.
  7. Assign the CP 340 to a logical interrupt OB if you need immediate notification of receive events (OB40).
  8. Save, compile, download to the PLC. The CP 340 will not initialize until the configuration is downloaded.

Program Structure (CP 340 ASCII Path)

// OB1 — cyclic
// Build outbound data in DB100
      L     DB100.DBB0          // first byte
      T     DB110.DBB0          // mirror to send buffer
// ... copy full payload ...
// Trigger send
      A     M    10.0           // rising edge trigger from HMI or sequencer
      =     L     0.0
      A     L     0.0
      FP    M    10.1
      =     M    10.2
      CALL  FB    2, DB20
         REQ   := M10.2
         ID    := 0                // logical CP address from HW Config
         LADDR := W#16#100         // I/O base address of CP 340
         DB_NO := 110              // DB containing send buffer
         DBB_NO:= 0                // start byte offset in DB110
         LEN   := 64               // byte count
         DONE  := M20.0
         ERROR := M20.1
         STATUS:= MW22

// Receive
      CALL  FB    3, DB21
         EN    := TRUE
         ID    := 0
         LADDR := W#16#100
         DB_NO := 111              // receive DB
         DBB_NO:= 0
         LEN   := 256              // max buffer length
         NDR   := M21.0            // new data received
         ERROR := M21.1
         STATUS:= MW23
         LEN_OUT:= MW24            // actual byte count received

RS-485 Wiring Notes for Modbus / ASCII to Delta DCS

CP 340 / 341 RS-485 pin Signal Delta DCS terminal
Pin 4 (T/B) Data A+ D+ / A
Pin 8 (R/A) Data B− D− / B
Pin 1 (Shield) Cable shield FG (ground at DCS end only)
120 Ω termination Install at CP end and at far DCS end if bus > 10 m

Do not ground the shield at both ends — this creates a ground loop that injects common-mode noise and corrupts bytes, surfacing as CRC errors or framing errors.

Verification and Commissioning

  1. With the CP powered and configured, check HW Config → Online → Module Information. Confirm the diagnostic buffer shows no entry of type Module fault or Parameter assignment error.
  2. From the STEP 7 online portal, open Monitor/Modify on the CP 340/341 diagnostic tags. Verify the line status (line idle, no break, no framing errors).
  3. Connect a serial analyzer (or use a passive tap) between the CP and the DCS. Capture the first 10 transactions. Confirm byte timing and CRC visually.
  4. Trigger a single read transaction from the PLC. Verify the DONE flag rises, the STATUS word is 0x0001, and the receive DB contains the expected register values mapped to the Delta DCS tag.
  5. Trigger a single write transaction (function code 06 or 16). Read the same register back from the DCS to confirm the write landed.
  6. Run the link under full PLC scan load for at least 30 minutes; verify no CRC errors appear in the CP diagnostic buffer or in the DCS event log.
  7. Force a DCS-side slave fault (disconnect the A wire momentarily) and confirm the PLC ERROR flag rises within the configured response timeout and the STATUS word returns 0x8181 or the equivalent for your driver.

Troubleshooting Matrix

Symptom Likely Cause Action
DCS reports CRC error on every transaction Modbus RTU being synthesized by hand in CP 340 user program Switch to CP 341 with Modbus driver, or use ASCII path, or install third-party Modbus driver
DCS reports CRC error intermittently Inter-character gap exceeding 1.5 char due to PLC scan segmentation Build the full Modbus frame in a contiguous DB and trigger P_SEND once
No response from slave (timeout) Wrong slave ID, swapped A/B wires, baud rate mismatch Capture on analyzer; verify single-byte echo of slave ID; check A+ and B− polarity against DCS pinout
Parity / framing error in CP diagnostic buffer Parity mismatch, stop bit mismatch, baud rate off by factor of 2 Match DCS settings exactly; verify with analyzer at both ends
CP 341 Modbus driver will not load License dongle missing or wrong MLFB Insert correct dongle; verify in HW Config that the CP 341 shows the driver as licensed
STATUS = 0x8182 (CRC error in received frame) Line noise, missing termination, ground loop on shield Add 120 Ω at both ends; ground shield at DCS only; check for VFD-induced noise if motor cables run parallel
STATUS = 0x8186 (slave exception) DCS rejects function code or address range Check DCS Modbus address map; confirm register range is readable/writable from the DCS side
Intermittent good and bad transactions Duplicate slave ID on the bus Confirm each node has a unique Modbus address 1..247
Receive buffer empty though analyzer shows traffic ASCII end-of-receive character not configured Set CR / LF delimiter to match DCS; if DCS uses no delimiter, set fixed length or character timeout

Choosing Between the Three Paths

Criterion Path A: CP 341 + Modbus Path B: ASCII Path C: 3rd-party Modbus on CP 340
Siemens support Full Full None from Siemens
Hardware cost CP 341 + dongle license None (re-use CP 340) None (re-use CP 340)
Engineering effort Low — loadable driver Medium — define text protocol with DCS team Medium — driver install, version pinning
CRC integrity Hardware-managed Not used (ASCII) Driver-managed
Risk on STEP 7 upgrade Low Low High — driver may not survive firmware change
Performance (transactions/sec) High — 30 to 50/s typical Medium — limited by line discipline High

For most brownfield integration projects where the Delta DCS is fixed and only exposes Modbus RTU, Path A is the correct answer. The cost of a CP 341 plus license is small compared to weeks of debugging hand-rolled CRC code on the CP 340, and the result is a Siemens-supported, deterministic link.

FAQ

Does the Siemens CP 340 support Modbus RTU natively?

No. The CP 340 firmware includes only the ASCII and 3964R drivers. Modbus RTU master or slave on a CP 340 requires either a third-party loadable driver (no Siemens support) or a hardware upgrade to a CP 341 with the Modbus master/slave loadable driver and license dongle.

Why does the Delta DCS report a CRC error on every Modbus request from the CP 340?

Because the CP 340 has no on-board Modbus RTU data link layer. The CRC-16, inter-frame silence, and slave address filtering must all be implemented in the PLC user program, and small differences in byte order, polynomial application, or transmit timing produce a CRC that does not match the DCS expectation. The supported fix is to swap the CP 340 for a CP 341 and load the Modbus master driver.

Which FBs do I call to send and receive with the CP 340?

For ASCII and 3964R use FB 2 P_SEND and FB 3 P_RCV from the SIMATIC PtP library. For Modbus RTU on a CP 341, call the FBs shipped with the Modbus master loadable driver (commonly designated P_SND_MB / P_RCV_MB in current documentation; check the manual that ships with the dongle for exact block numbers and the call interface).

What are the common CP 340 / CP 341 MLFBs and how do they differ?

CP 340: 6ES7340-1AH02-0AE0 (RS-232C), 6ES7340-1BH02-0AE0 (RS-485 2-wire), 6ES7340-1CH02-0AE0 (RS-422/485 4-wire). CP 341: 6ES7341-1AH02-0AE0, 6ES7341-1BH02-0AE0, 6ES7341-1CH02-0AE0 for the same three interface options. Both modules are S7-300 plug-in design and are pin-compatible at the backplane.

Can I keep the CP 340 and talk to the Delta DCS in ASCII instead of Modbus RTU?

Yes, if the Delta DCS supports a generic ASCII mode with CR/LF-terminated strings. Configure the CP 340 to the ASCII driver, match baud rate and parity to the DCS, and define a simple comma-separated or tag-based text protocol. This avoids Modbus framing entirely but requires agreement on the text format with the DCS engineering team.

Back to blog