S7-1200 SEND_PTP Error 8088: Fixing CM 1241 RS232 ASCII

David Krause11 min read
S7-1200SiemensTroubleshooting
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

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:

  1. 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 LEN against the buffer size, which fails when LEN > declared STRING length.
  2. Short fixed STRING: Declaring a STRING[2] and trying to send 5 bytes through LEN = 5.
  3. 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.
  4. Empty string: The variable is declared but never written, so the actual length byte is 0 and any non-zero LEN returns 8088.
Rule of thumb: Always create the global DB for SEND_PTP buffers with "Symbolic access only" disabled and declare the STRING element as a 254-character STRING (default maximum in S7-1200) so SEND_PTP can read the actual length header correctly.

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

  1. In the TIA Portal project tree, right-click Program blocks > Add new block > Data block.
  2. 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.
  3. Inside the DB add a single element:
    Name:    SendStr
    Type:    STRING[254]   // or just STRING (defaults to 254)
  4. 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.
The default STRING in S7-1200 occupies 256 bytes (2-byte header + 254-byte payload). Do not shrink it. SEND_PTP uses the 16#00 byte 1 of the STRING header to know the actual string length.

4.2 Assign the Hardware Identifier

  1. 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+).
  2. In the CM 1241 properties, expand Hardware identifier and note the value, e.g. 269. This is the PORT input 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

  1. Online monitor: In TIA Portal, go online with the CPU and open the SEND_PTP block. Force REQ to TRUE for one cycle. Watch the STATUS output. It must return 16#0000 on success, not 16#8088.
  2. 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.
  3. 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 (for 1Z\r\n) leave the module within a few milliseconds of the rising edge of REQ.
  4. 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

  1. 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.
  2. Configure the CM 1241 in TIA Portal with the baud rate, parity, and stop bits of the target device.
  3. Compile the project and download hardware configuration.
  4. Create a non-optimised global DB with a 254-byte STRING and a small instance DB for SEND_PTP.
  5. 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.
  6. Go online, force REQ, monitor STATUS. Expect 16#0000.
  7. Confirm with a scope or terminal emulator that the bytes appear on the line.
  8. 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.

Back to blog