S7-1200 SEND_PTP Error 8088: Resolving CM 1241 RS232 ASCII Transmission
The error code 8088 returned by the SEND_PTP instruction on a Siemens S7-1200 with a CM 1241 RS232 communication module is one of the most common faults encountered when sending ASCII command strings to a serial device. The error indicates that the LEN input references more bytes than the source DATA area can provide. In practice, this is almost always caused by a STRING declaration in the global DB that is declared as a fixed-size STRING (e.g. STRING[10]) or by a data block with symbolic-only access enabled.
This article covers the exact root cause of error 8088, the proper STRING declaration for SEND_PTP, hardware configuration of the CM 1241 (6ES7241-1AH32-0XB0), and a step-by-step commissioning procedure for sending ASCII commands such as "1Z" and "0Z" to a video adapter, scale, pump, or instrument.
1. Problem Description
A first-time STEP 7 Basic / TIA Portal user attempts to send a simple ASCII command string (e.g. 1Z, 0Z, *IDN?) to an RS232 device through a CM 1241 communication module. The SEND_PTP block is called from an OB1 cycle, the REQ input is driven by a discrete input or a one-shot flag, the PORT input is wired to the CM 1241 hardware identifier, and the DATA input points to a STRING element in a global DB.
On the first rising edge of REQ the block sets DONE = 0, ERROR = 1, and STATUS = 8088 (hexadecimal 16#8088). The TIA Portal online help for SEND_PTP does not list 8088 as a documented status code, which makes the fault appear mysterious.
Affected Hardware and Software
| Item | Value |
|---|---|
| CPU family | S7-1200 (any firmware) |
| Communication module | CM 1241 RS232 (6ES7241-1AH32-0XB0) or legacy CM 1241 RS232 (6ES7241-1AF30-0XB0) |
| Engineering tool | STEP 7 Basic V10.5, V11, V13, V15, V15.1, V16, V17, V18 |
| Instruction | SEND_PTP, SENDING_PTP (V18) |
| Firmware of CM 1241 | V1.0 and later (no impact on this error) |
2. Root Cause of Error 8088
The SEND_PTP block internally evaluates the source buffer at DATA by reading the first two bytes of the source area as the maximum STRING length (byte 0) and the actual STRING length (byte 1), and then reading LEN bytes from offset 2 onwards. If LEN exceeds the actual length of the STRING payload, the block reports 16#8088: "Length parameter is greater than the user data length in the source area."
The most common triggers are:
-
Symbolic-only DB: A global DB created with Symbolic access only enabled hides the two-byte STRING header from SEND_PTP. The block cannot read the actual length and falls back to comparing
LENagainst the buffer size, which fails whenLEN> declared STRING length. -
Short fixed STRING: Declaring a
STRING[2]and trying to send 5 bytes throughLEN= 5. - Declaring a STRING without explicit length in a different DB layout that starts at an offset where the header bytes are not where SEND_PTP expects them.
-
Empty string: The variable is declared but never written, so the actual length byte is 0 and any non-zero
LENreturns 8088.
3. Required Hardware and Software
3.1 CM 1241 RS232 Module
The CM 1241 RS232 is a point-to-point communication module for the S7-1200 that supports the following character-oriented protocols: ASCII, USS, 3964(R), and Modbus RTU (master). Refer to the S7-1200 CM 1241 module manual (entry 8859629) for the full specification.
| Parameter | Value |
|---|---|
| Article number (current) | 6ES7241-1AH32-0XB0 |
| Article number (legacy) | 6ES7241-1AF30-0XB0 |
| Electrical interface | RS232, D-sub male, 9-pin |
| Signals used | TXD, RXD, RTS, CTS, DCD, DTR, DSR, RI |
| Baud rates | 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200 |
| Data bits | 7 or 8 |
| Parity | None, Even, Odd, Mark, Space |
| Stop bits | 1 or 2 |
| Flow control | None, XON/XOFF, RTS/CTS (hardware) |
| Maximum cable length | 10 m (RS232 standard limit) |
| Power consumption | 1.1 W from backplane bus |
2.2 SEND_PTP / RCV_PTP Instruction
The PtP (Point-to-Point) instructions are part of the Communications > PtP palette in TIA Portal. As of V18 the SEND_PTP block has been renamed SENDING_PTP, but the interface and behaviour are identical. See the S7-1200 PtP instructions manual (entry 109751716) for parameter details.
| Input / Output | Type | Description |
|---|---|---|
| REQ | BOOL | Rising edge triggers a send job |
| PORT | PORT (HW identifier) | Hardware identifier of the CM 1241 |
| DATA | VARIANT | Pointer to the source STRING buffer (e.g. P#DB2.DBX256.0) |
| LEN | UINT | Number of bytes to send, 1 to 1024 |
| DONE | BOOL | Set for one cycle on successful completion |
| ERROR | BOOL | Set for one cycle on failure |
| STATUS | WORD | Detailed error or status code (e.g. 16#8088) |
4. Step-by-Step Solution
4.1 Create the Send Buffer DB
- In the TIA Portal project tree, right-click Program blocks > Add new block > Data block.
- Name the DB
DB_SendBuffer(for example). In the Properties dialog, uncheck "Symbolic access only". This is the critical step that prevents the 8088 error. - Inside the DB add a single element:
Name: SendStr Type: STRING[254] // or just STRING (defaults to 254) - Set the Start value to the command you intend to send, e.g.
'1Z'for power-on and'0Z'for power-off. The two characters plus a terminator are typically followed by CR/LF if the target device requires it.
4.2 Assign the Hardware Identifier
- Open Device configuration for the S7-1200 CPU and drag the CM 1241 RS232 from the catalog to the left of the CPU (slot 101 in TIA Portal V14+).
- In the CM 1241 properties, expand Hardware identifier and note the value, e.g.
269. This is thePORTinput of SEND_PTP.
4.3 Configure the Serial Port
Open the Properties > Port configuration of the CM 1241 and set:
| Parameter | Recommended setting for a typical video adapter / instrument |
|---|---|
| Protocol | ASCII |
| Baud rate | 9600 |
| Data bits | 8 |
| Parity | None |
| Stop bits | 1 |
| Flow control | None for three-wire (TX/RX/GND); RTS/CTS for full handshake |
| XON character | 11h (default) |
| XOFF character | 13h (default) |
| Wait time | 5000 ms |
4.4 Call SEND_PTP in OB1
// OB1 - cyclic main
// Using the SEND_PTP from the PtP library
SEND_PTP_DB(
REQ := bSendTrigger, // one-shot BOOL (rising edge)
PORT := 269, // hardware identifier of CM 1241
DATA := P#DB2.DBX256.0 BYTE 256,// pointer to SendStr in DB_SendBuffer
LEN := DB2.ActualLen, // length of payload to send
DONE => bDone,
ERROR => bError,
STATUS=> wStatus
);
The LEN input is the number of bytes the instruction will actually transmit. If you want to send the full STRING as defined in the DB, you can read the actual length from byte 1 of the STRING header using a small SCL snippet or by exposing the header as a separate AT view:
// Alternative: read actual STRING length
#ActualLen := DB2.SendStr.LEN; // implicit property on STRING variables
4.5 Avoid the Symbolic-Only Pitfall
To verify the DB is not symbolic-only, expand the block in the project tree, right-click the DB and choose Properties > Attributes. The checkbox "Optimised block access" / "Symbolic access only" must be off. With an optimised DB the two-byte STRING header is moved by the compiler and SEND_PTP reads a different offset, producing exactly 16#8088.
5. Verification
-
Online monitor: In TIA Portal, go online with the CPU and open the SEND_PTP block. Force
REQto TRUE for one cycle. Watch theSTATUSoutput. It must return16#0000on success, not 16#8088. -
STATUS codes to expect on success:
-
16#0000– Send job completed, no error. -
16#7000– No job in progress, idle. -
16#7001– First call, job running. -
16#7002– Subsequent calls while job is running.
-
-
Wire-level check: Connect a USB-RS232 sniffer or a scope on the TXD line of the CM 1241. You should see the ASCII bytes
31 5A 0D 0A(for1Z\r\n) leave the module within a few milliseconds of the rising edge ofREQ. - Device echo: If the target device echoes the command, wire RXD back to a PC terminal and confirm the bytes are correct.
6. SEND_PTP and RCV_PTP Error Code Reference
The following subset covers the codes most often seen in the field. For the complete list, refer to the S7-1200 PtP instructions manual.
| STATUS (hex) | Meaning | Remediation |
|---|---|---|
| 16#0000 | Job completed without error | None – success |
| 16#7000 | No job active | Normal idle state |
| 16#7001 | First call after rising edge of REQ | Wait for completion |
| 16#7002 | Subsequent call, job in progress | Wait for completion |
| 16#8085 | LEN = 0 or LEN > 1024 | Set LEN to a value between 1 and 1024 |
| 16#8088 | LEN larger than the source DATA area | Disable symbolic-only on the DB; ensure STRING has at least LEN bytes of actual content; do not declare a SHORT_STRING |
| 16#8188 | Port not configured for ASCII, or wrong HW identifier | Re-check protocol selection and PORT value |
| 16#8288 | Hardware fault on CM 1241 | Replace module, check diagnostics buffer |
| 16#8388 | Transmission error (parity, framing, break) | Match baud/parity/stop bits to the device |
7. Common Pitfalls and Field-Proven Caveats
7.1 Optimised Block Access
TIA Portal V14 and later set new DBs to Optimised block access by default. SEND_PTP requires the absolute address of the STRING, which only exists in non-optimised (classic) DBs. Either disable the option at DB creation or use the AT overlay technique:
DATA_BLOCK "DB_SendBuffer"
{ S7_Optimize_Access := 'FALSE' }
VERSION : 0.1
STRUCT
SendStr : STRING[254]; // 256 bytes incl. header
END_STRUCT;
END_DATA_BLOCK
7.2 Short String Declaration
Declaring STRING[2] to hold '1Z' works for the data itself, but the 256-byte full-range STRING provides more headroom and avoids the compiler reordering the header. Stick with STRING or STRING[254].
7.3 LEN Greater Than Actual String Length
Even with a 254-byte STRING, if you have not written the variable (SendStr := '1Z';) the actual length byte is zero and any positive LEN produces 8088. Always initialise the buffer in the start-up OB or a one-shot in OB1.
7.4 Wrong Hardware Identifier
The PORT input is not a slot number, it is a system constant (e.g. 269). Use the System constants tab of the PLC tags, or drag the constant from the device configuration. A wrong value returns 16#8188, not 8088, but the user often misreads the diagnostic.
7.5 String Constants in the Source DB
SEND_PTP can send a STRING declared in a standard (non-optimised) DB and a STRING declared as a local tag in the calling FB/OB. It cannot send a STRING declared inside a UDT or in an optimised DB without further handling. If you must use a UDT, place the STRING inside a non-optimised DB instance.
7.6 Trailing CR/LF
Many RS232 devices (video adapters, scales, lab instruments) require a carriage return (0Dh) and line feed (0Ah) terminator. Append them to your STRING in the start-up routine:
"DB_SendBuffer".SendStr := CONCAT(IN1 := '1Z', IN2 := '$R$L');
// $R = 0x0D, $L = 0x0A in S7-1200 STRING syntax
8. End-to-End Commissioning Procedure
- Wire the CM 1241 RS232 to the target device. For a three-wire connection, link pins 2 (TXD), 3 (RXD) and 5 (GND). For full handshake use 7 (RTS) and 8 (CTS) as well.
- Configure the CM 1241 in TIA Portal with the baud rate, parity, and stop bits of the target device.
- Compile the project and download hardware configuration.
- Create a non-optimised global DB with a 254-byte STRING and a small instance DB for SEND_PTP.
- Insert SEND_PTP in OB1, wire REQ to a one-shot, PORT to the system constant, DATA to the absolute pointer, and LEN to the actual STRING length.
- Go online, force REQ, monitor STATUS. Expect 16#0000.
- Confirm with a scope or terminal emulator that the bytes appear on the line.
- Document the wiring and the parameter set in the project comments for the next commissioning engineer.
9. Frequently Asked Questions
What does SEND_PTP error 16#8088 mean on the S7-1200 CM 1241?
Error 16#8088 means the LEN input is greater than the actual length of the source STRING in the DATA area. The most common cause is a global DB that is created with "Symbolic access only" or "Optimised block access" enabled, which hides the two-byte STRING header from SEND_PTP. Disable that option and ensure the buffer is a STRING[254].
Do I need to set the LEN parameter when calling SEND_PTP?
Yes. LEN is required and must be between 1 and 1024. If you want the instruction to send the entire STRING exactly as written, set LEN to the actual length returned by the implicit .LEN property of the STRING variable, e.g. LEN := "DB_Buffer".SendStr.LEN.
Why does the CM 1241 work in the device configuration but SEND_PTP still returns an error?
The PORT input of SEND_PTP must be the HW identifier (system constant), not the slot number. Drag the constant from the PLC tags > System constants list, or right-click the input and pick the entry for the CM 1241. A mismatch returns 16#8188.
Can I use SEND_PTP to send binary data as well as ASCII?
Yes. The protocol selection "ASCII" on the CM 1241 only sets the character framing (data bits, parity, stop bits). The actual byte content sent comes from the source buffer. If you point DATA to an array of BYTE and set LEN to the number of bytes, you can transmit any 8-bit value from 00h to FFh.
How do I add a carriage return and line feed to my command string?
Use the CONCAT instruction in SCL: "DB_Buffer".SendStr := CONCAT(IN1 := '1Z', IN2 := '$R$L');. The sequence $R is 0x0D and $L is 0x0A. Many RS232 devices will not process the command without these terminators.
What is the difference between SEND_PTP and SENDING_PTP in TIA Portal V18?
SENDING_PTP is the renamed instruction in TIA Portal V18 and later. The interface, parameters, and error codes are identical to SEND_PTP. Older projects opened in V18 will still show SEND_PTP and the compiler will not flag it.