Problem Statement: Single-Character CP 340 Output
A common commissioning issue on S7-300 platforms equipped with the CP 340 point-to-point communication module is that the serial port appears to transmit the WITS (Wellsite Information Transfer Specification) frame one byte at a time when viewed in HyperTerminal, PuTTY, or any terminal emulator. The intended behaviour is that the entire WITS record (header "!!", repeated index/data lines, terminator "&&") arrives as a contiguous burst so the receiving software can parse the frame in a single read.
Symptom pattern as observed on the field:
- HyperTerminal echoes one character per OB cycle, with visible inter-character gaps.
- Reception is correct, not corrupted; only the cadence is wrong.
- Initial commissioning may show garbled text until the parity is corrected; the parity default on the CP 340 is even, which most PC COM ports treat as 7E1, while HyperTerminal defaults to 8N1 (no parity).
- Lowering the cyclic interrupt period (OB35 at 100 ms versus OB32 at 1000 ms) makes the stream faster but does not solve the underlying issue.
CP 340 Hardware Architecture and Variants
The CP 340 is the legacy point-to-point module for the S7-300 and S7-400 families. Three physical variants exist, each with a different electrical interface but identical firmware behaviour for the user-facing FBs.
| MLFB Order Number | Interface | Max Baud | Typical Use |
|---|---|---|---|
| 6ES7340-1AH02-0AE0 | RS-232C (V.24) | 19.2 kbit/s | PC, modem, HyperTerminal |
| 6ES7340-1BH02-0AE0 | RS-422 / RS-485 (X27) | 19.2 kbit/s | Multi-drop field devices |
| 6ES7340-1CH02-0AE0 | 20 mA current loop (TTY) | 19.2 kbit/s | Legacy TTY peripherals |
The reference manual "PtP coupling and configuration of CP 340" documents the module variants, the framing engine, and the interrupts the module uses to handshake with the CPU. Per that manual, the CP 340 holds an internal transmit buffer (typ. 1024 bytes for the -1AH02/-1BH02/-1CH02 series); when the CPU hands the module more bytes than fit in the buffer, the FB returns a busy status and the application must re-issue the job once the module has drained the buffer. This is the root mechanism that, when misunderstood, produces the character-by-character behaviour described above. See the CP 340 manual (PDF) and the CP 340 entry page for the full module description.
Root Cause: Send Buffer and OB Cycle Interaction
The transmit job presented to the CP 340 is built by the application program and typically uses one of two blocks: FB2 P_SEND (raw byte array) or FB5 P_PRINT (formatted text with up to 4 variables). Both blocks copy a contiguous range of bytes from a DB into the module's transmit buffer. The module then drains that buffer through the serial engine at the configured baud rate.
Inter-character gap on the wire at 9600 8N1 is approximately 1.04 ms (10 bits per character at 9 600 bit/s). If the application builds a one-character string and submits it every OB35 cycle (100 ms), the wire will look like:
The "burst" effect that the application requires is therefore a function of how much data the application hands to the module per job, not of the OB period. The OB simply decides how often a complete frame is dispatched; the module always serialises whatever it has at line speed.
OB Configuration: Selecting the Correct Cyclic Interrupt
S7-300/400 cyclic-interrupt OBs are OB30 through OB38. Each has a default period that can be re-phased with SFC 26 / SFC 27 at runtime.
| OB | Default Period | Typical Use |
|---|---|---|
| OB30 | 5 000 ms | Slow supervisory tasks |
| OB31 | 2 000 ms | Slow scans |
| OB32 | 1 000 ms | 1 s telemetry (WITS, modems) |
| OB33 | 500 ms | Mid-rate polling |
| OB34 | 200 ms | Faster polling |
| OB35 | 100 ms | Default cyclic interrupt |
| OB36 | 50 ms | Closed-loop control |
| OB37 | 20 ms | High-rate control |
| OB38 | 10 ms | Fast I/O, high-speed protocols |
For a 1-second WITS record, OB32 is the canonical choice. Putting the P_SEND / P_PRINT call inside OB32 means the record is dispatched every 1 000 ms; the CP 340 then drains the frame in roughly 264 ms at 9 600 8N1 for a 254-byte payload. The remaining ~700 ms of idle is normal and gives the receiving system time to process the frame.
P_PRINT: The Dedicated Print Function Block
For formatted textual output (the WITS frame is text, not raw binary), FB5 P_PRINT is the correct tool. P_PRINT accepts a format string with up to four embedded variables using the standard C-style format specifiers (%d, %f, %s, %x) and writes the rendered string to the CP 340's send buffer in a single FB call. Because the call hands the entire formatted string to the module at once, the module then transmits it as a continuous byte stream. The P_PRINT instruction is documented in the TIA Portal help under "P_PRINT: Print message text with up to 4 variables (S7-300, S7-400)" at P_PRINT reference.
Key parameters of FB5 P_PRINT (instance DB assigned per logical port):
| Parameter | Direction | Type | Description |
|---|---|---|---|
| REQ | IN | BOOL | Rising edge triggers a print job |
| IN | STRING | Format string with %d/%f/%s specifiers | |
| DST | IN | STRING[12] | Job name shown in diagnostic buffer |
| DSTAT | OUT | WORD | Detailed status (FB-specific) |
| ERROR | OUT | BOOL | TRUE = job terminated with error |
| STATUS | OUT | WORD | CP 340 status word |
Maximum text length is 200 characters per call when using P_PRINT; for longer records (e.g. a 254-byte WITS burst), split the payload into consecutive P_PRINT calls or use P_SEND with a STRING/ARRAY of CHAR.
P_SEND: Raw-Byte Alternative
FB2 P_SEND transmits a raw byte range from a DB. Use it when the format string of P_PRINT is too restrictive or when the payload is binary. The application concatenates the WITS header, body, and terminator into a STRING or ARRAY[0..N] OF CHAR in a DB, then calls P_SEND with the start address and length.
| Parameter | Direction | Type | Description |
|---|---|---|---|
| REQ | IN | BOOL | Rising edge triggers the send |
| SD | IN | ANY | Source data area (DB, MB, etc.) |
| LEN | IN | INT | Number of bytes to send (1..1024) |
| DONE | OUT | BOOL | Job completed without error |
| ERROR | OUT | BOOL | TRUE = job failed |
| STATUS | OUT | WORD | CP 340 status word |
Sample STL snippet for building and transmitting a WITS frame in a single P_SEND call (assumes a 316/317 CPU and STEP 7 V5.x):
// Build WITS frame in DB100
// String layout: 2-byte header length, then ASCII bytes
L 254 // total length
T DB100.DBB 0 // max length byte of STRING[254]
L 254
T DB100.DBB 1 // actual length byte
L '!!'
T DB100.DBB 2
T DB100.DBB 3
// ... fill body bytes 4..251 with "0100.12345\r\n" etc.
L '&&'
T DB100.DBB 252
T DB100.DBB 253
L 254
T DB100.DBW 254 // pad to fill DB area if needed
// Trigger P_SEND every OB32 cycle
CALL FB2 , DB200
REQ :=M 10.0 // one-shot from OB32 edge
SD :=P#DB100.DBX 0 BYTE 256
LEN :=254
DONE :=M 10.1
ERROR :=M 10.2
STATUS :=MW 12
Parity and Serial Protocol Defaults
The CP 340 is configured per logical port in STEP 7 HW Config / NetPro. The protocol parameters exposed are baud rate, data bits (7/8), parity (none/even/odd/mark/space), stop bits (1/2), and flow control (none / XON-XOFF / RTS-CTS / XON-XOFF + RTS-CTS for the -1AH02 RS-232C variant). The factory default is:
| Parameter | CP 340 default | HyperTerminal default |
|---|---|---|
| Baud | 9 600 | 9 600 |
| Data bits | 8 | 8 |
| Parity | EVEN | NONE |
| Stop bits | 1 | 1 |
| Flow control | NONE | NONE |
Even parity means the CP 340 inserts a parity bit on the wire that HyperTerminal ignores, so the high bit of each byte appears "wrong" in the terminal window. The fix is one of:
- Set HyperTerminal to 7E1, or
- Reconfigure the CP 340 protocol in HW Config to "None" parity and 8 data bits, and re-download the hardware configuration.
Recommendation: change the CP 340 to "None / 8 / 1" and leave HyperTerminal at its 8N1 default. This avoids any future mismatch with PC tools and is the modern convention.
Step-by-Step: Implementing Burst Transmission
-
Create a STRING DB. In STEP 7, insert a new DB (e.g. DB100) and declare
WitsFrame : STRING[254];. The default STRING[254] reserves 256 bytes (2 length + 254 data) and is large enough for the WITS records shown in the source example. - Populate the string in OB1 or a function called from OB1. Concatenate the literal text using the standard STRING concatenation (FC2 CONCAT, FC4 DELETE, FC11 FIND, etc.) or write a small FC that appends each line. Initialise once at startup and update index bytes per cycle.
- Insert the CP 340 in HW Config. Drag the CP 340 from the hardware catalog to the S7-300 rack. Open the object properties of the PtP port, set protocol = ASCII, baud = 9 600, data bits = 8, parity = None, stop bits = 1. Save and download the hardware configuration.
- Create an instance DB for the FB. For P_SEND, place FB2 in OB32 and assign DB200 as the instance. For P_PRINT, place FB5 and assign DB300. The instance DB holds the channel state; the same DB must be used for the lifetime of the channel.
- Call the FB in OB32. Wire REQ to a one-shot from a clock-bit flip-flop so the FB sees a rising edge once per second. Connect SD / PRINT to the STRING built in step 2.
- Compile and download. Use STEP 7 > PLC > Download to RAM. Use PLC > Monitor/Modify to watch the STATUS word of the FB and the send-buffer fill level.
- Reset the CP 340 if STATUS indicates a stuck channel. A rising edge on the SFC reset of the CP 340 (or power cycling the CPU) clears any pending receive or transmit state. See "Diagnostic LEDs and Error Codes" below for STATUS values that require this step.
Verification Procedures
After the fix, run a verification matrix before commissioning the field device:
| Check | Tool | Pass criterion |
|---|---|---|
| Continuous burst on the wire | Oscilloscope on TxD line, single capture | No idle gap > 2 character times inside the frame |
| HyperTerminal echo | HyperTerminal / PuTTY at 9 600 8N1 | Each line of the WITS record appears as a single line, not as one character per line |
| DONE / ERROR on the FB | STEP 7 VAT table on M10.1 / M10.2 | DONE = TRUE once per OB32 cycle, ERROR = FALSE |
| STATUS word | STEP 7 VAT table on MW12 | 0x0000 (idle) or transient non-zero during the job, no 0x0E1F / 0x0E20 / 0x0E25 persistent values |
| Frame integrity | WITS master / SCADA receiving the record | CRC or checksum valid, "!!" header and "&&" terminator present |
| Long-run stability | 24 h soak test | No STATUS drift, no watchdog events on the CP 340 |
Diagnostic LEDs and Error Codes
The CP 340 front-panel LEDs are the fastest in-the-field diagnostic indicator:
| LED | State | Meaning |
|---|---|---|
| SF (red) | ON | Group error; consult STATUS word |
| TxD (green) | Flashing | Module transmitting |
| RxD (green) | Flashing | Module receiving |
| All LEDs OFF | — | No 24 V backplane supply or no parameter assignment |
Selected STATUS values (decimal shown; refer to the CP 340 manual for the full list):
| STATUS hex | STATUS dec | Cause | Corrective action |
|---|---|---|---|
| 0x0000 | 0 | Job complete, no error | None |
| 0x0E01 | 3585 | Job aborted (user clear) | Re-issue REQ |
| 0x0E03 | 3587 | Frame abort from receiver (BREAK) | Check wiring, disable BREAK detection if not needed |
| 0x0E05 | 3589 | CTS timeout (RS-232C with flow control) | Check DCE ready line, or disable RTS/CTS |
| 0x0E0F | 3599 | Parameter assignment error | Re-download HW Config; verify protocol |
| 0x0E1F | 3615 | Send buffer overflow (LEN > max) | Reduce LEN to 1..1024 for P_SEND, or to 200 for P_PRINT |
| 0x0E20 | 3616 | Receive buffer overflow | Increase polling frequency on P_RECV or shorten remote bursts |
| 0x0E25 | 3621 | Interface not initialized | Re-download HW Config or cycle power on the CP 340 |
Common Pitfalls in the Field
- Calling the FB every OB1 scan with a one-character slice: the wire looks correct but the receive software never sees a full frame within its timeout window.
- Using STRING[80] default for a 200-byte record: P_SEND will truncate to 80 bytes without raising an error, and the WITS master will see a short frame.
- Two CPUs using the same instance DB for P_SEND: the instance DB is not re-entrant. Each CPU requires its own FB instance DB.
- Forgetting the trailing CR / LF in the WITS record: the master may not advance to the next line, and the frame appears to "hang" in the terminal.
- Configuring XON/XOFF and then sending the XON/XOFF characters (0x11 / 0x13) as part of the payload: the CP 340 will interpret them as flow-control commands and stall the stream.
When to Migrate to CP 341 / CP 441
The CP 340 supports ASCII framing only. If the field device requires Modbus RTU (RTU mode binary), 3964(R), or RK-512, move to a CP 341 (6ES7341-1AH02-0AE0 / -1BH02-0AE0) or CP 441 (6ES7441-1AA04-0AE0 / -2AA04-0AE0). The migration is pin-compatible on the S7-300 backplane; only the FB library changes. The same P_PRINT / P_SEND concept still applies but the module is parameterised as a "Modbus master" or "3964(R) link" in HW Config rather than as raw ASCII.
Why does the CP 340 only output one character per OB cycle to HyperTerminal?
The application program is submitting a one-character job to the module on every cycle. The CP 340 transmits whatever buffer it is handed; at 9 600 8N1 the inter-character gap between two one-byte jobs is the OB period (e.g. 1 000 ms for OB32), which is visible in the terminal. Build the complete WITS frame in a STRING/DB and call P_SEND or P_PRINT once per cycle with the full payload so the module drains the buffer as a single burst.
Which OB is correct for a 1-second WITS transmission on S7-300?
Use OB32, whose default period is 1 000 ms. OB35 is the 100 ms cyclic interrupt and will dispatch frames ten times per second. Either can be re-phased with SFC 26 / SFC 27 at runtime, but OB32 with the default phase is the canonical choice for 1 s telemetry.
Should I use P_PRINT or P_SEND for the WITS record?
Use P_PRINT (FB5) when the payload is formatted ASCII text with embedded variables; it accepts up to 4 format specifiers per call and a 200-character text. Use P_SEND (FB2) when the payload is a binary array or exceeds 200 bytes, or when the format string is awkward. For the 254-byte WITS record in the source example, P_SEND with a STRING[254] DB is the cleaner fit.
The CP 340 parity default is even but HyperTerminal is 8N1. What is the quick fix?
Reconfigure the CP 340 in STEP 7 HW Config to parity = None, data bits = 8, stop bits = 1, then re-download the hardware configuration. This matches the 8N1 default of HyperTerminal, PuTTY, and most PC serial software and avoids the high-bit corruption caused by the CP 340's default 7E1 framing. See the CP 340 manual (PDF) for the parameter list.
How do I know whether the CP 340 is actually transmitting or just buffered?
Watch the front-panel TxD LED; it flashes for the duration of the burst. For a definitive answer, put a scope on the TxD line of the CP 340 (pin 2 of the -1AH02 RS-232C variant) and confirm that the line idles high (mark) between frames and goes low for the start bit of each character. A persistent STATUS word of 0x0000 with DONE toggling each cycle is the software-side confirmation.