1. Problem Description
On a SIMATIC S7-300 station consisting of a CPU 317 and a CP 341 point-to-point module (the module often labelled CMPTP in older project text and referred to as CP 341 RS232 in catalog order numbers such as 6ES7 341-1AH01-0AE0), the user program calls the Send_P2P function block (FB 8) from the SIMATIC S7 Point-to-Point Communication library (block version 1.3) under STEP 7 V5.6 + SPx. The request to send is issued (REQ edge or EN_R set) and the block returns on the DONE/ERROR/STATUS outputs a status word of 16#8281 (decimal 33409) – a negative acknowledgement while writing. No bytes reach the partner device. The instance DB is correctly built (no length / range errors), and the project has been compiled without complaints.
Error 16#8281 is one of the most common status words returned by Send_P2P / Receive_P2P (FB 8 / FB 7) and almost always indicates that the CP 341 driver attempted to hand the frame to the UART/line driver and the line driver was not allowed to transmit – either because the partner pulled the handshake line low, because the cable is wrong, or because the module's interface parameters in HW Config are inconsistent with the partner.
2. Root Cause Analysis for Status 16#8281
The CP 341 firmware reports 16#8281 (NACK while writing) when the layer-2 transmit path is closed by one of the following mechanisms:
| # | Root cause | How to confirm |
|---|---|---|
| 1 | RS232 hardware handshake disabled in HW Config but the partner asserts RTS/CTS or holds DCD/DSR low. | Oscilloscope on pins 4 (RTS out), 5 (CTS in), 8 (DCD) of the Sub-D connector. |
| 2 | RS232 hardware handshake enabled in HW Config, but the partner never raises CTS (pin 5) because it is wired wrong or unpowered. | Measure pin 5 with a voltmeter; valid level is > +3 V for "clear to send". |
| 3 | Wrong protocol frame selected – e.g. ASCII driver with character-delay end criteria set to a value the partner cannot guarantee, so the line driver times out before the full frame is clocked in. | Read STATUS while the block is busy (EN_R = 1, no DONE) – a 16#1E (decimal 30) means end-criteria timeout. |
| 4 | Baud rate, parity, data bits or stop bits differ from the partner. The receiver side of the CP 341 reports a parity/framing overrun, and the transmit path is held back by the line monitor. | Run the CP 341 diagnostic buffer (Module Information → Diagnostics) and look for "Frame error", "Parity error" or "Overrun". |
| 5 | Half-duplex RS485 or 4-wire mode selected on the CP 341 while the cable is wired for RS232, or vice versa. The transmitter enable is held off permanently. | Read the interface assignment in HW Config → CP 341 → Properties → Parameters → Interface. |
| 6 | Duplicate address reservation: the input area is mapped to the module but the output area is missing in HW Config – STATUS 16#8281 may appear if the OB1 load image was not refreshed for the output side because the slot is mis-sized. | HW Config → CP 341 → Properties → Addresses. Both Inputs and Outputs should be present and equal length (≥ 2 bytes for S7-300, typically IB/QB 0..15 default). |
| 7 | Driver block (FB 8) loaded into the wrong project path – the instance DB points to the wrong library version (e.g. Send_P2P V2.0 used with a V1.3 block header). | Open the instance DB and check the block version. Re-install the library from the STEP 7 V5.6 CD (SIMATIC S7 PtP). |
3. Hardware Configuration Check
Open the S7-300 station in HW Config and select the CP 341. The following screens are all required for a clean configuration – if any is left at default, status 16#8281 is likely.
3.1 General / Addresses tab
- Slot: the CP 341 must be on a slot supported by the S7-300 rack (slot 4–11) and wired to the backplane bus. CPU 317 typically occupies slot 2 or 3.
- I/O addresses: the Inputs must be in the process image (PI) and at least 2 bytes long. The Outputs are also at least 2 bytes. If only Inputs are visible in the project (a common shortcut with FB 8/FB 7 from older hand-copied projects), the SEND call cannot move data to the UART and the firmware returns 16#8281 after the first transmission attempt.
3.2 Interface assignment
Set the physical interface explicitly. Do not leave it on "Automatic".
| Parameter | Recommended for generic RS232 partner |
|---|---|
| Interface | RS232 (full duplex) |
| Half/Full duplex | Full duplex |
| Hardware handshake | Enabled only if the partner drives CTS |
| Data flow control (XON/XOFF) | Disabled unless the partner requires software handshake |
3.3 Protocol / Frame
On the Protocol page the protocol-specific parameters must match the partner exactly. For ASCII:
| Parameter | Suggested value |
|---|---|
| Baud rate | Match partner (commonly 9600 or 19200) |
| Data bits | 8 |
| Parity | None (or Even – match partner) |
| Stop bits | 1 |
| End-of-receive criteria | Character delay time (e.g. 4 ms – see §4) |
| End-of-frame character | CR (0x0D), LF (0x0A) or both, depending on the partner |
4. Recommended End-of-Frame Criteria
The default character-elapsed time in many older STEP 7 V5.5 projects is 22 ms, the STEP 7 V5.6 default is 4 ms. For ASCII protocols with a known delimiter (CR/LF) the preferred end criteria is the frame end character so the receiver does not have to wait for the timer. If the partner does not send a delimiter, use the character delay time and size it for the longest inter-character gap the partner is allowed to produce. For a 9600-baud line with 11 bits/character (1 start, 8 data, 1 stop, 1 parity) one character is ≈ 1.15 ms; a 4-character gap is ≈ 4.6 ms. 4 ms is therefore the practical minimum – it is fast enough to keep the receive block responsive but tolerant of normal UART jitter.
5. Software Block Parameters
Send_P2P (FB 8) and Receive_P2P (FB 7) of the SIMATIC S7 PtP library expose the following interface. Values for the typical "no protocol – raw ASCII" use case are given below.
5.1 FB 8 Send_P2P inputs
| Parameter | Type | Meaning / recommended value |
|---|---|---|
| REQ | BOOL | Rising edge starts a send job. Pulse it for exactly one OB1 cycle. |
| R | BOOL | Reset the block (cancel a running job). |
| LADDR | INT | Logical base address of the CP 341 from HW Config (e.g. 256). |
| DB_NO | INT | Number of the data DB that contains the telegram. |
| DBB_NO | INT | Byte offset inside DB_NO where the telegram starts. |
| LEN | INT | Telegram length in bytes (1…200 for the CP 341 ASCII driver). |
| RTS_ON | BOOL | Set TRUE only if hardware handshake is "RTS always ON" (for half-duplex). For full-duplex RS232 with the CP 341 handling RTS/CTS internally, leave FALSE. |
| RTS_OFF | BOOL | Set TRUE only if the driver is required to drop RTS after transmission. |
| BREAK | BOOL | Transmit a break condition. Leave FALSE. |
| DRIVER | BYTE | Driver selector: B#16#01 = ASCII, B#16#02 = 3964(R), B#16#04 = RK 512. For raw RS232 ASCII use B#16#01. |
5.2 FB 8 Send_P2P outputs
| Parameter | Type | Meaning |
|---|---|---|
| DONE | BOOL | One-cycle TRUE when the telegram has been handed to the line driver (not when the partner acknowledges it!). |
| ERROR | BOOL | TRUE on failure; STATUS contains the cause. |
| STATUS | WORD | 16-bit status. 0 = ok. 16#8281 = NACK while writing. |
| LEN_OUT | INT | Number of bytes actually transmitted (useful for partial sends). |
5.3 Working OB1 call (STL)
// One-shot on rising edge of M10.0 (operator request)
A M 10.0
FP M 10.1
= M 10.2 // local REQ edge
// Trigger Send_P2P
CALL "SEND_P2P" , DB101
REQ :=M10.2
R :=FALSE
LADDR :=256 // CP 341 base address from HW Config
DB_NO :=20 // telegram data block
DBB_NO :=0
LEN :=MW12 // current telegram length, 1..200
RTS_ON :=FALSE // full-duplex, hardware auto
RTS_OFF :=FALSE
BREAK :=FALSE
DRIVER :=B#16#1 // ASCII
DONE :=M20.0
ERROR :=M20.1
STATUS :=MW22
LEN_OUT :=MW24
5.4 Send_P2P STATUS reference
| STATUS (hex) | STATUS (dec) | Meaning | Action |
|---|---|---|---|
| 0000 | 0 | Job complete, no error | None |
| 7000 | 28672 | No job active, block ready | Issue REQ |
| 7001 | 28673 | First call with REQ, job accepted, busy | Wait for DONE / ERROR |
| 7002 | 28674 | Subsequent call, job still busy | Wait |
| 8085 | 32901 | LEN, DB_NO, DBB_NO or DRIVER out of range | Check LEN ≤ 200, DB exists, DBB within DB |
| 8090 | 32912 | Module withdrawn or not configured at LADDR | Check HW Config, LADDR matches module base address |
| 80A0 | 32928 | Negative acknowledgement from module on read | CP 341 diagnostic buffer |
| 80A1 | 32929 | Negative acknowledgement from module on write | CP 341 diagnostic buffer |
| 8281 | 33409 | Negative acknowledgement while writing (line driver refused transmit) | Check handshake, cable, partner power, end-criteria timeout |
| 82C0 | 33472 | Telegram aborted by R = TRUE | Reset state machine |
| 82C1 | 33473 | Number of received characters exceeded the receive buffer | Increase LEN or read FB 7 buffer faster |
6. Recommended Program Structure
For reliable commissioning, collapse the SEND/RECV state machine into two booleans and one call of each block per cycle. The reason is simple: if a SEND is re-triggered before the previous job finishes, FB 8 will reject it with 16#8281 because the line driver has not yet released the channel.
6.1 Two-bool state machine pattern
// M_bSend, M_bRecv are mutually exclusive booleans
A M 30.0 // operator wants to send
AN M 30.1 // no receive in progress
S M 30.2 // M_bSend := TRUE
A M 30.1 // receive in progress
R M 30.2 // M_bSend := FALSE
// Send_P2P call (gated by M_bSend)
A M 30.2
A "DIAG_OK" // partner healthy (DCD/DSR latch)
= M 10.2 // REQ edge to FB 8
// Receive_P2P call (gated by M_bRecv)
A M 30.1
= M 11.0 // EN_R to FB 7
6.2 Timer hygiene
Use one IEC timer (TP / TON) per direction. Do not embed the timer inside an IF/THEN construct that can be skipped, otherwise the timer will hold its state and stall the state machine.
// Send timeout 1 s (block should finish much faster)
CALL "IEC_TON" , DB200
IN := M30.2
PT := T#1S
Q := M30.3 // M_bSendTimeout
ET := MW40
A M 30.3
S "ALARM_SEND_TIMEOUT" // latch fault
R M 30.2
7. RS232 Cable and Signal Verification
The CP 341 RS232 Sub-D male pin-out is:
| Pin | Signal | Direction (CP 341 →) | Comment |
|---|---|---|---|
| 2 | TxD | Output | Transmit data |
| 3 | RxD | Input | Receive data |
| 4 | RTS | Output | Request to send (driven high when CP 341 wants to transmit) |
| 5 | CTS | Input | Clear to send. Must be high for transmit; if the partner is DTE-style, loop 4 → 5 on the partner side or use a NULL-modem cable |
| 6 | DSR | Input | Data set ready. Optional; if not used, the CP 341 firmware still checks it when "Hardware handshake" is enabled |
| 7 | SGND | — | Signal ground |
| 8 | DCD | Input | Data carrier detect |
| 20 | DTR | Output | Data terminal ready |
Two practical measurements that almost always isolate a 16#8281 caused by a wiring problem:
- With the partner powered and idle, measure pin 5 (CTS) referenced to pin 7 (GND). A reading in the range +3 V to +12 V means "clear to send". A reading below +3 V, or a negative reading, means the partner is refusing permission to send – verify its handshake configuration and the cable used.
- Trigger a Send_P2P from the PLC and watch pin 4 (RTS). It should toggle from approximately +12 V (idle) to approximately −12 V (active request). If RTS does not toggle, the firmware refused the job before touching the line and the cause is logical (wrong LADDR, wrong DB, wrong LEN) – this would more typically show 16#8085 or 16#8090 instead of 16#8281, but a stuck protocol state is still possible after a 3964(R) BREAK.
8. Diagnostic Procedure
- Open STEP 7 V5.6, go online with the CPU 317, right-click the CP 341 → Module Information → Diagnostics Buffer. Look for entries with class "Line error", "Frame error", "Partner NACK" or "Break". These confirm whether the firmware itself reports 16#8281 because the line driver flagged a fault.
- Open the instance DB of FB 8 in the online view. Watch
STATUSlive. If you see 16#8281 immediately on REQ rising, suspect handshake. If you see 16#7001 → 16#8281 after a few hundred ms, suspect end-criteria timeout. - Use a serial line analyzer (or a laptop with a USB RS232 dongle and PuTTY/Termite in show control lines mode) to monitor both data and RTS/CTS. The CP 341 raising RTS without CTS being asserted by the partner is the canonical 16#8281 signature.
- Try the partner at a much lower baud rate (e.g. 1200) and a relaxed character delay (e.g. 50 ms) to rule out timer-vs-protocol mismatches before chasing wiring faults.
- If you have a 3964(R) protocol selected, remember that the firmware waits for the partner's DLE/ETX or DLE/NAK response. A partner that never answers will be reported as a 16#8281 "NACK while writing".
9. Step-by-Step Resolution
- Verify the module type and firmware. Open HW Config → CP 341 → Properties → Diagnostics. Confirm the MLFB (6ES7 341-1Axxx-0AE0 for RS232) and that the firmware version matches the Send_P2P block version. Mismatch produces cryptic 16#8281 cycles.
- Re-check the address reservation. Confirm that the CP 341 has both an input range and an output range in the process image. If only inputs are reserved, the SEND/RECV primitives cannot be loaded. Add the output range of equal size in HW Config.
- Match the interface parameters to the partner. RS232, full duplex, baud, parity, data bits, stop bits. If the partner is unknown, try 9600/8/N/1 first and use a known-good device as reference.
- Decide the handshake. If the partner drives CTS, enable hardware handshake in HW Config. If the partner does not drive CTS, disable hardware handshake and make sure no DCD/DSR line is left floating-low – some drivers interpret a floating line as NACK.
- Set the end-of-frame criteria. 4 ms character delay is a safe default for ASCII at 9600 baud; longer (10–20 ms) for partners that interleave slow I/O. For deterministic protocols, use the frame-end character.
- Simplify the OB1 code. One Send_P2P, one Receive_P2P, two bools for the state machine, one timer per direction. Remove duplicate calls and conditional REQ pulses that overlap with previous jobs.
- Download HW Config and the program. A change to the CP 341 protocol parameters is only active after a STOP → RUN on the CPU or an online re-initialization through the diagnostic buffer.
- Trigger one telegram and read the STATUS. If 16#8281 persists, capture the diagnostic buffer entry generated in the same second – its text will identify the layer-2 cause.
10. Verification
Successful resolution is confirmed by all of the following:
- FB 8 returns
DONE= TRUE for one cycle,ERROR= FALSE,STATUS= 16#0000. - FB 7 receives the partner's reply with the expected length and content;
LEN_OUT= expected reply size. - The CP 341 diagnostic buffer contains no "NACK", "Frame error" or "Break" entries during 1 h of operation.
- On a scope, the CP 341 raises RTS, the partner raises CTS within 1 character time, and data toggles on TxD/RxD symmetrically.
- 1000 consecutive SEND/RECV cycles complete without 16#8281.
11. Related Pitfalls
- Wrong block version. Send_P2P V1.3 is the STEP 7 V5.6 release. If the project still contains V1.0 instance DBs from STEP 7 V5.2, FB 8 will appear to compile but will not write to the module – the call returns 16#8281 because the parameter interface is not aligned. Re-install the library and regenerate the instance DB.
- Send_P2P inside OB1 with REQ held permanently. Holding REQ = TRUE without observing DONE blocks the line driver and any second job is reported as 16#8281. Use a one-cycle edge.
- 3964(R) initialisation. When DRIVER = B#16#02, the block first sends DLE/STX and waits for DLE/ACK. If the partner does not answer with the configured handshake, the firmware reports 16#8281 even though the line itself is healthy. This is the most common 3964(R) 16#8281 case.
- Double addressing. If another CP 341 (or any other intelligent module) sits on the same logical address, Send_P2P will return 16#8281 the moment the firmware detects a collision on the backplane bus.
- CP 341 in MPI mode by accident. If the CP 341 has been repurposed or re-parameterised for ASCII, the parameter set must be downloaded to the module with "Download to module" in HW Config, not just saved to the project. The block will then return 16#8281 until the firmware is initialised with the new protocol.
12. Reference Documents
- SIMATIC S7-300 CP 341 Point-to-Point Communication, Installation and Parameter Assignment Manual
- SIMATIC S7 Point-to-Point Communication FB 7/FB 8 (SEND/RECEIVE) Programming Manual
- STEP 7 V5.6 – Function Block Interface for CP 341 / CP 340 / CP 441
- CP 341 Status Code Reference (16#8281 – NACK while writing)
What does Send_P2P status 16#8281 mean on a CP 341?
Status 16#8281 (decimal 33409) means "negative acknowledgement while writing". The CP 341 firmware tried to transmit a telegram but the line driver refused – typically because the partner pulled CTS low, the cable is wrong, or the configured end-of-frame criteria caused the transmit path to be held off. Read the CP 341 diagnostic buffer for the exact line-level reason.
How do I clear Send_P2P error 16#8281 after a wiring fix?
After correcting the cable or handshake, stop the CPU 317, run HW Config → CP 341 → "Download to module" so the new protocol parameters are pushed to the module's flash, and cold-restart the CPU. A RUN→STOP→RUN cycle alone is not enough to re-initialise the firmware. Then trigger a single SEND and confirm STATUS = 16#0000.
Can status 16#8281 be caused by a wrong LADDR in the Send_P2P call?
Yes. A wrong LADDR typically produces 16#8090 ("module not configured at this logical address"), but a mis-sized address reservation (only inputs, no outputs) will surface as 16#8281 the moment the block tries to write to the missing output area. Always check both the input and output ranges of the CP 341 in HW Config → Addresses.
Should I use 3964(R) or ASCII for a generic RS232 partner?
For a third-party device that does not implement the Siemens 3964(R) handshake, select the ASCII driver (DRIVER = B#16#01). With 3964(R), a partner that does not reply with DLE/ACK after the CP 341 sends DLE/STX will cause 16#8281 within the configured acknowledgement timeout. Use ASCII unless the partner explicitly supports 3964(R).
What is the correct character delay time for ASCII on a CP 341?
For 9600 baud with 8-N-1 (≈ 1.15 ms per character), 4 ms is the minimum safe character delay and the STEP 7 V5.6 default. Slower partners should be configured with 10–20 ms. The value must be at least 2× the worst-case inter-character gap produced by the partner, otherwise the receive block will close the frame early and the next transmission attempt may be rejected with 16#8281.