Resolving S7-1200 TRCV_C Empty Buffer with Status 7006

David Krause18 min read
SiemensTIA PortalTroubleshooting
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

Symptoms and Field Observation

When a SIMATIC S7-1200 CPU is wired to a Microscan Ethernet TCP/IP barcode scanner through Open User Communication (OUC) and the receive block is configured in TIA Portal V13 SP1 with TRCV_C block version 4.0, integrators observe the following abnormal behavior on the live system:

  • STATUS output of TRCV_C reads 16#7006 (decimal 28678) continuously while the TCP connection remains held open.
  • RCVD_LEN output reads 0 for every OB1 cycle, even immediately after the scanner is triggered.
  • The destination data block - typically declared as Array[0..N] of Byte or Array[0..N] of Char - is never written by the block. All bytes remain at the configured initial value.
  • The scanner is proven to be transmitting valid TCP payloads when observed with a PC-based tool such as the Hercules SETUP utility in TCP client mode. No request message is required from the PLC to elicit a payload; the scanner fires on its hardware trigger input and pushes the ASCII data unsolicited.
  • Setting the LEN input of TRCV_C to a non-zero value (e.g. 1, 100, or 65535) changes the symptom to ERROR = TRUE and STATUS = 16#8088 - "LEN parameter does not correspond to the receive area set at the DATA parameter".

Together, these observations point to a data-flow binding problem between the TRCV_C instruction and the receive buffer tag, not to a physical, network-layer, or scanner-side fault. The fix is a one-time reconfiguration of the DATA pin in TIA Portal.

Affected Environment and Versions

Component Configuration
PLC SIMATIC S7-1200 (CPU 1211C, 1212C, 1214C, 1215C, 1217C, 1214FC; tested on 6ES7214-1AG40-0XB0)
CPU firmware V4.0 (TIA Portal V13 SP1 baseline) through V4.6 (TIA Portal V17/V18); TRCV_C is supported on firmware V4.0 and higher
TIA Portal V13 SP1 (reported), V14, V14 SP1, V15, V15.1, V16, V17, V18
Receive instruction TRCV_C (legacy Open User Communication), block version 4.0
Companion instruction TSEND_C (for bidirectional traffic on the same connection)
Partner device Microscan Ethernet TCP/IP barcode scanner (MS-2, MS-3, MS-4, ID-20, ID-30, ID-40, V420, V430 families)
Protocol Raw TCP (RFC 793), no application layer encapsulation - no ISO-on-TCP, no Modbus/TCP wrapper
Default scanner port TCP 2001 (Microscan factory default) - configurable via ESP or web UI
Default PLC port (passive) Any unused TCP port above 1024 - typically 2000, 2001, 2002, or 3000 series
Max concurrent OUC connections 8 on CPU 1214C, fewer on 1211C/1212C (see CPU-specific manual)

Root Cause: The DATA Pin Assignment

The TRCV_C instruction is implemented as a self-contained compound FB that performs both TCP connection management and payload buffering. Per the official Siemens documentation for the SIMATIC S7-1200 manual collection, TRCV_C interprets the DATA input as the absolute start address and length of a contiguous receive buffer within the work memory of the S7-1200. The block then uses the difference between the buffer size and the currently-used offset to decide how many bytes can still be accepted in the current ad-hoc frame.

When a user drops a tag of type Array[0..199] of Byte onto the DATA pin and TIA Portal auto-resolves it to MyArray[0] (the first element only), the block sees the receive buffer as a one-byte area located at the start of the array. Two distinct failure modes follow:

  1. Ad-hoc mode (LEN = 0): The block is told it has one byte of buffer, so it is willing to accept only a single byte per call. Because barcode payloads are typically 10-60 ASCII characters (and can be up to 255 characters with certain 2D codes), the arriving data is silently truncated to one byte and the rest is held in the internal TCP receive FIFO without ever being written back to the user tag. RCV_LEN may briefly report 1, but if the program reads it before the next OB1 cycle, it shows 0 because the next TRCV_C invocation re-arms the buffer pointer and clears the bookkeeping.
  2. Length-specified mode (LEN > 0): The static length at the LEN input disagrees with the dynamic size derived from the 1-byte buffer at the DATA pin, so TRCV_C reports 16#8088 (STATUS) with ERROR = TRUE. This is the secondary symptom most often reported together with the empty buffer.

The correct binding is to assign the entire symbolic array tag to the DATA pin. In the TIA Portal variable-selection dialog, this is done by clicking the array name itself rather than expanding the [...] node. Once the full array is bound, the block can compute a buffer size equal to the array length, and the ad-hoc receive works against the entire area.

Critical: Always verify the binding by hovering the mouse over the DATA pin in the LAD/FBD editor. The tooltip should show the full array name (e.g. "DB_Scan".rcvBuf) and not "DB_Scan".rcvBuf[0]. If the tooltip shows an index, the binding is wrong and TRCV_C will silently behave as a one-byte receiver.

TRCV_C Parameter Reference

The following table lists every input and output of the TRCV_C block that is relevant to this fix, with the data type, direction, and functional meaning. Reference: Siemens Support - TRCV_C: Establishing a connection and receiving data (S7-1200).

Parameter Direction Type Meaning
REQ Input BOOL Rising edge starts a new receive job. In ad-hoc mode keep REQ = TRUE and let TRCV_C manage internally.
CONT Input BOOL Keep connection open after job completion. Must remain TRUE for sustained scanner traffic.
LEN Input UINT Length to receive. 0 = ad-hoc (variable length, controlled by DATA buffer size). 1 - 8192 = fixed length protocol.
DATA InOut VARIANT Receive buffer. Must be the whole array (e.g. DB_Scan.rcvBuf), not an indexed element.
CONNECT Input BOOL TRUE = establish / maintain connection, FALSE = tear down.
ID Input WORD Connection identifier 1-16 (S7-1200), tied to TCON_IP_v4 / TCON parameters.
Connection InOut VARIANT Pointer to the connection description DB (e.g. TCON_IP_V4).
DONE Output BOOL One-shot pulse when a frame has been received successfully.
BUSY Output BOOL TRUE while a job is in progress.
ERROR Output BOOL TRUE when the last job terminated with an error (see STATUS).
STATUS Output WORD Status / error code. 16#7006 = NO_DATA, no payload available yet.
RCVD_LEN Output UINT Number of bytes actually received in the most recent frame.

Solution: Link the Whole Array to the DATA Pin

Open the TRCV_C instance in the LAD/FBD editor. Re-wire the DATA input as follows:

  1. In the project tree, open Program blocks > DB_Scan (your receive data block).
  2. Click directly on the array tag name (e.g. rcvBuf) - do not expand the [0..199] array node to drill into the first element.
  3. Drag the array tag (or the name itself) onto the DATA input of TRCV_C. The input field will display the symbolic name without any trailing [n].
  4. Confirm with the tooltip: hover the DATA pin; the tooltip must show "DB_Scan".rcvBuf only.
  5. Set LEN to 0 for ad-hoc mode.
  6. Compile the project (Project > Compile > Software), download, and STOP/RUN the CPU to force a full reinitialization of the connection.

The block now sees a 200-byte (or whatever the array size is) contiguous buffer in the work memory and is allowed to receive up to that many bytes in a single ad-hoc frame. The DONE bit will pulse for one OB1 cycle when a frame has been written, RCVD_LEN will reflect the actual payload size, and the bytes will be visible in the data block from rcvBuf[0] upward.

Alternative data types: TRCV_C also accepts an element of a STRING tag or a STRUCT tag, but the same rule applies: bind the whole STRING variable or the whole STRUCT variable, not a sub-element. The legacy documentation explicitly notes that TRCV_C will not receive data into Boolean locations.

LEN Parameter and Ad-hoc Mode

The LEN input selects between two protocol variants. Both variants rely on the same underlying TCP socket, but they differ in how the length of each receive frame is determined.

LEN value Protocol variant Behavior
0 Ad-hoc mode Length is determined by the number of bytes that arrive from the partner between two OB1 cycles, bounded by the size of the DATA buffer. Recommended for barcode scanners where each scan produces a variable-length payload.
1 - 8192 Length-specified mode TRCV_C will only return DONE after exactly LEN bytes have been received. Used for fixed-length protocol frames.
65535 Ad-hoc mode (older TIA Portal V11 - V12 convention) Historical alias for LEN = 0. Replaced by LEN = 0 in V13 and later. Setting LEN = 65535 on V13+ typically produces error 16#80B5 or 16#8088.

For Microscan scanners that fire a single ASCII string terminated by a CR/LF or by a configurable suffix, ad-hoc mode (LEN = 0) is the right choice. The block will return DONE as soon as the partner closes the write side of the frame or the OS hands off the buffered bytes.

Note on framing: The standard TCP stack on the S7-1200 uses the Nagle algorithm, which can coalesce small writes from the scanner. If your application requires immediate delivery of every byte (e.g. single-character trigger commands), consider disabling the Nagle delay by setting the connection's TCP_NODELAY attribute in the TCON_IP_V4 structure to TRUE. This is rarely needed for barcode payload reception.
TRCV_C Steady-State Operation Cycle (ad-hoc, LEN=0) REQ=0 STATUS 7000 REQ=1, CONNECT=1 STATUS 7001/7002 SOCKET OPEN STATUS 7003/7005 NO DATA YET STATUS 7006 DONE pulse (1 cycle) RCV_LEN = bytes ERROR=1 STATUS 80xx loop back to listen (REQ still 1) 7006 is the steady "listening" state - data arriving transitions to DONE for one OB1 cycle, then back to 7006

Status and Error Code Reference

The following are the STATUS values most commonly observed when TRCV_C is used as the receive block for an external TCP partner such as a Microscan scanner. Reference: TIA Portal - Legacy TSEND_C and TRCV_C instructions.

STATUS (hex) STATUS (dec) Meaning
7000 28672 Block not active, REQ = 0, no connection.
7001 28673 First call, connection establishment started.
7002 28674 Connection establishment in progress, awaiting partner.
7003 28675 Connection established, no receive job active.
7004 28676 Connection terminated cleanly.
7005 28677 Connection established, receive path ready.
7006 28678 NO_DATA - connection established, receive job active, no new payload has been received. This is the value reported in the field symptom; it is not itself an error.
80A1 32929 Connection terminated by partner, no more data available.
80A2 32930 Local connection error, partner did not acknowledge FIN.
80A3 32931 Connection aborted locally or by partner, receive buffer locked.
80A4 32932 IP address of partner not assigned / not reachable.
80A7 32935 Connection terminated by partner, restart required.
80A8 32936 Local connection abort, frame error.
80A9 32937 Remote connection abort, frame error.
80AA 32938 Local connection abort, no resources.
80AB 32939 Remote connection abort, no resources.
80AC 32940 Local connection abort, ARP failure.
80AD 32941 Remote connection abort, ARP failure.
80AE 32942 Local connection abort, no TCP socket available.
80AF 32943 Connection ID already in use by another block.
80B0 32944 Connection establishment in progress, awaiting CONNECT.
80B1 32945 Establishment failed, no free connection resource.
80B2 32946 Establishment failed, parameter assignment error.
80B3 32947 Establishment aborted, no further resources.
80B4 32948 Connection limit reached (max 8 active OUC connections on S7-1200).
80B5 32949 Parameter assignment error in the connection description DB (e.g. invalid LEN, port out of range).
8088 32904 LEN parameter does not correspond to the receive area set at the DATA parameter (e.g. LEN greater than array size, or DATA bound to a sub-element).
80C0 32960 Temporary resource error, retry on next cycle.
80C1 32961 Temporary resource error, retry on next cycle.
80C2 32962 Temporary resource error, retry on next cycle.
80C3 32963 Temporary resource error, retry on next cycle.
80C4 32964 Internal system error, firmware update recommended.

Microscan Scanner Ethernet Configuration

Before chasing the TRCV_C binding problem, confirm the scanner side is configured to push data unsolicited on TCP. A Microscan scanner is normally configured through the ESP (Easy Setup Program) desktop utility, through the on-board web interface (default 192.168.1.20:80), or through the scanner's serial configuration menu accessed via the configuration bar code. The relevant settings are:

Setting Recommended value Comment
IP Address 192.168.1.20 (example) Must be on the same subnet as the S7-1200 PN interface.
Subnet Mask 255.255.255.0 Match PLC subnet.
Default Gateway 192.168.1.1 or empty Required only if the scanner must reach a host outside the local subnet.
Protocol TCP Server (default) or TCP Client (if scanner is to dial out) For unsolicited push on trigger, set the scanner as TCP Server, then have the S7-1200 issue an active connect via CONNECT = TRUE.
Destination IP PLC IP address (192.168.1.10) Only relevant if scanner is TCP Client.
Destination Port PLC port (e.g. 2000) Only relevant if scanner is TCP Client. PLC must be in passive (server) mode.
Local Port (TCP Server) 2001 (Microscan factory default) PLC must connect to this port from the active side.
End of Message Suffix CR or CR LF Optional. S7-1200 TRCV_C will deliver everything received as one ad-hoc frame regardless.
Data Format ASCII string (readable) - not binary Microscan default.
Trigger Mode External edge, level, or serial command Scanner fires payload on hardware or software trigger.

If the scanner is left in its factory-default TCP Server mode on port 2001, the S7-1200 program should establish the connection actively by leaving CONNECT = TRUE and populating the TCON_IP_V4 connection parameter DB with ActiveEstablishment = TRUE, RemoteAddress = "192.168.1.20", and RemotePort = 2001. The first TRCV_C call will open the socket; subsequent calls just receive.

S7-1200 CPU 1214C DC/DC/DC IP 192.168.1.10 PN port X1 Microscan TCP/IP Scanner IP 192.168.1.20 Port 2001 (TCP Server) Managed Switch PROFINET EtherNet TCP/IP TCP/IP S7-1200 issues active connect from 192.168.1.10 to 192.168.1.20:2001

Step-by-Step Fix and Verification Procedure

Use this checklist to apply the fix and to prove the receive path is end-to-end functional on the live network.

  1. Place the CPU in STOP, open the TIA Portal project, and download the project.
  2. Open the FB / OB that contains TRCV_C in the LAD or FBD editor.
  3. Click the DATA input of TRCV_C and delete the existing wire.
  4. From the project tree, expand the receive DB (e.g. DB_Scan), then drag the array tag (e.g. rcvBuf : Array[0..199] of Byte) - not the element rcvBuf[0] - onto the DATA input.
  5. Verify with the tooltip that the binding reads "DB_Scan".rcvBuf without an index.
  6. Set LEN to 0 for ad-hoc mode.
  7. Confirm the connection DB (e.g. TCON_IP_V4) has ActiveEstablishment = TRUE, RemoteAddress = "192.168.1.20", RemotePort = 2001, and a unique ID (e.g. 1) that matches the ID input of TRCV_C.
  8. Compile the project (Project > Compile > Software).
  9. Download the new build to the S7-1200 and STOP/RUN the CPU to force a full reinitialization of the connection resource.
  10. Open an online watch table on the TRCV_C instance. Monitor STATUS, ERROR, RCVD_LEN, and the first 16 bytes of rcvBuf.
  11. Trigger the Microscan scanner with a known bar code (e.g. 123456789012). STATUS should remain 16#7006 between scans, DONE should pulse TRUE for one OB1 cycle on receipt, RCVD_LEN should report the number of bytes in the payload (e.g. 12 for the 12-digit code), and the bytes in rcvBuf[0..11] should be ASCII 0x31, 0x32, 0x33, ... 0x32.
  12. If STATUS remains 16#8088, the LEN/DATA binding is still wrong. Recheck the tooltip and recompile.
  13. If STATUS reports any value from the 80Ax or 80Bx family, consult the Status and Error Code Reference above to isolate the network-layer fault.

Common Pitfalls and Edge Cases

  • Indexing the array in the variable selector. The single most common cause of the empty-buffer symptom. The fix is to drop the array itself, not an element.
  • Passing a BOOL or a single BYTE tag at DATA. The Siemens manual explicitly states that TRCV_C will not receive data into Boolean locations. Use a non-scalar type (ARRAY of BYTE, ARRAY of CHAR, or STRING).
  • Using a STRING with too small a maximum length. A STRING of length 10 cannot hold a 16-character payload; the data is silently truncated. Size the STRING to the maximum scan length plus 2 bytes for the Siemens STRING header.
  • Forgetting to leave REQ = TRUE. In ad-hoc mode, REQ must remain TRUE for the block to keep listening. Latching REQ high in OB1 is the correct pattern - one-shot rising-edge calls are for length-specified mode only.
  • Calling TRCV_C in a non-cyclic OB. TRCV_C must run in a cyclic class of OB (OB1, OB3x, OB8x). Calling it in OB100 (startup) or OB121 (error) will not deliver ongoing data.
  • Not performing a STOP/RUN transition after download. TIA Portal V13 SP1 sometimes retains stale connection state in the S7-1200 firmware; a power cycle or STOP → RUN transition is required to reinitialize the connection description DB.
  • Multiple blocks competing for the same connection ID. The S7-1200 supports up to 8 open OUC connections (depending on CPU type). Each TSEND_C / TRCV_C pair must use a unique ID; otherwise STATUS reports 16#80AF "Connection ID already in use".
  • Scanner configured as TCP Client with no active listener on the PLC. If the scanner is set to TCP Client and the PLC side is configured passively, the PLC must already be in LISTEN before the scanner dials. Use TRCV_C with ActiveEstablishment = FALSE in the TCON_IP_V4 structure.
  • Firewall or managed switch blocking TCP traffic on port 2001. On a plant network, ensure the path between the PLC and the scanner has no ACL dropping the port.
  • VLAN mismatch. The S7-1200 PN interface is single-VLAN-aware; if the scanner is on a different VLAN, the PROFINET interface must be configured for that VLAN ID in the device properties.
  • Symbolic access disabled on the receive DB. The DATA input of TRCV_C requires symbolic access on the destination DB. If the DB property "Optimized block access" is set incorrectly, or "Accessible from HMI/OPC UA" interferes, the bind may fail silently. Verify under DB > Properties > Attributes.
  • Retain attribute interfering with the buffer. If the receive DB has "Retain" enabled, the previous payload survives a power cycle and may look like a working receive even when the new one is not arriving. Disable Retain on the buffer DB or zero the array in startup.

Migrating to Newer TIA Portal Versions

TRCV_C is the legacy "compound" block (connect + send/receive in one call) and remains the recommended entry point for simple scanner integration on TIA Portal V13 - V18. For users on V15.1 or later, Siemens additionally offers the pair TCON + TRCV (split into separate connection management and receive blocks) which expose the same parameters but allow the connection to be shared with TSEND on the same ID. The behavior at the DATA pin is identical: bind the whole ARRAY tag, set LEN = 0 for ad-hoc, and verify with the tooltip.

When migrating an existing project from V13 SP1 to V17 / V18, pay attention to the following points:

  • Connection parameter DBs (TCON_IP_V4) created in V13 SP1 are forward-compatible; no recreation is needed unless the firmware of the S7-1200 was also upgraded to V4.5 or higher.
  • TRCV_C block version 4.0 is replaced by 4.1 / 4.2 in newer TIA Portal versions but the call interface is identical - no code change is required.
  • TSAP / port-handling changed in V14: the LocalPort and RemotePort fields in the TCON_IP_V4 structure now accept both decimal and hexadecimal string values; older projects stored them as decimal strings, which can be silently misinterpreted after migration.
  • If the project is converted to a V17/V18 PC-based WinCC Runtime or to a PLCSIM instance, verify that the simulation profile includes the PROFINET interface and that the firewall on the engineering PC allows the loopback TCP port.

For full reference of the V13 SP1 - V18 block interface, consult the official TIA Portal manual collection: Legacy TSEND_C and TRCV_C instructions and the Siemens support entry for TRCV_C on the S7-1200.

Frequently Asked Questions

What does STATUS 16#7006 mean on TRCV_C, and is it an error?

STATUS 16#7006 (decimal 28678) is the NO_DATA state. The TCP connection is open and the receive job is armed, but no new payload has arrived from the partner since the last call. It is not an error; it is a steady-state value you will see most of the time on a quiet scanner. Only when the scanner triggers and DONE does not pulse should you treat the symptom as a fault.

Why does ERROR 16#8088 appear when I set LEN to a non-zero value?

ERROR 16#8088 means the LEN input does not match the size of the buffer at the DATA pin. With a whole ARRAY bound at DATA, LEN must be between 0 and the size of the array (e.g. 0 - 200 for Array[0..199] of Byte). Any LEN greater than the array size triggers the error. Use LEN = 0 for ad-hoc mode when the payload length varies from scan to scan.

Can I use a STRING tag instead of an ARRAY at the DATA pin?

Yes. TRCV_C accepts a STRING tag. The block writes the incoming bytes into the STRING's character area (after the two-byte Siemens header). The same rule applies: bind the whole STRING tag at DATA, not a sub-element, and use a STRING with a maximum length greater than the longest expected payload.

Does this same fix apply to the newer TRCV instruction (TCON + TRCV)?

Yes. The TCON / TRCV pair follows identical rules. Bind the whole ARRAY or STRING at the DATA input, set LEN = 0 for ad-hoc mode, and verify the tooltip shows the full symbolic tag name without an index.

Why does RCV_LEN read 0 even though STATUS is 7006?

RCVD_LEN is a one-shot output: it shows the number of bytes received in the last completed frame. Between frames it holds the last value (which can be 0 if no frame has yet been completed) until the next DONE pulse updates it. To catch a frame, monitor the rising edge of DONE and snapshot RCVD_LEN in the same OB1 cycle.

Back to blog