Configuring S7-1200 TSEND_C and TRCV_C for Multi-PLC Data

David Krause10 min read
S7-1200SiemensTutorial / How-to
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

Overview

Siemens S7-1200 CPUs expose two compact open-user-communication blocks — TSEND_C and TRCV_C — that combine connection setup, parameter assignment, and data transfer into a single instruction each. They support both TCP and ISO-on-TCP (RFC 1006) transport on the integrated PROFINET interface, making them the standard tool for peer-to-peer PLC data exchange without the overhead of full PROFINET IO configuration.

The blocks are well suited to the common case where a "server" PLC (for example PLC_3) collects process data from one or more "client" peers (PLC_1, PLC_2). A single TRCV_C instance handles one connection, so accepting data from two senders requires two independent TRCV_C instances, two connection IDs, and two partner connection definitions inside the TIA Portal device configuration.

Engineering rule: Connection IDs are local to the CPU on which the block is instantiated. A connection ID used on PLC_1 is unrelated to a connection ID used on PLC_3. The only requirement is that the IDs be unique on the CPU that owns the block.

Block Capabilities and Limits

Per the S7-1200 Manual Collection – TSEND_C and TRCV_C:

  • Minimum user-data payload per call: 1 byte
  • Maximum user-data payload per call: 8192 bytes
  • Connection types supported: TCP, ISO-on-TCP, and (for TRCV_C) UDP variants via the same instruction family
  • Connection setup is integrated; the block sets up the connection, sends/receives, and tears the connection down on a single rising edge of REQ (TSEND_C) or appropriate control bits
  • Buffering of the receive length and busy/done/error status is provided through the block's instance DB

For payloads approaching the 8 KB ceiling, the architecture must guarantee that the receiver drains the buffer in less time than the sender takes to fill and dispatch the next telegram. If jitter on the receiver is high, fragment the data into multiple smaller TSEND_C calls with sequence numbers in the payload.

Architecture: Client/Server Topology for Multi-PLC Sourcing

  1. PLC_3 cannot poll the source PLCS for freshness; it only learns of new data when a send arrives.
  2. If PLC_1 or PLC_2 is restarted, PLC_3's existing connection is dropped and must be re-established by the active partner — there is no automatic reconnect from the receiver side.

The recommended alternative — and the one used in the Siemens application example 67196808 — is to make PLC_3 the active client and PLC_1 / PLC_2 the passive servers. PLC_3 then opens two connections on its own schedule, requests the latest dataset, and tears the connection down (or keeps it warm with keep-alive). The benefits are deterministic poll timing, easier diagnostics on one CPU, and centralised control over who-is-authoritative-for-what.

Connection ID Management

Each TSEND_C / TRCV_C instance carries a 16-bit ID (connection ID) and a 16-bit CONNECTION_ID parameter. The values must be unique across all open-user-communication blocks on the same CPU. The IDs are local — two CPUs in the project may legally reuse the same numeric value.

PLC Block Connection ID (local) Connection DB Role
PLC_1 TSEND_C (to PLC_3) 1 DB_Conn1 (auto) Active (client) — original configuration
PLC_2 TSEND_C (to PLC_3) 1 DB_Conn1 (auto) Active (client) — original configuration
PLC_3 TRCV_C #1 (from PLC_1) 2 DB_Conn2 (auto) Passive (server)
PLC_3 TRCV_C #2 (from PLC_2) 3 DB_Conn3 (auto) Passive (server)

The original configuration used ID = 1 on PLC_1 (sender) and ID = 2 on PLC_3 (receiver). That is valid as long as no other block on PLC_3 also uses ID = 2. If a second incoming connection is added on PLC_3, the second TRCV_C must be assigned ID = 3 (or any unused value). TIA Portal flags duplicate IDs at compile time.

Step-by-Step Configuration

Prerequisites

  • TIA Portal V16 or later (V18 / V19 recommended for the S7-1200 G2 generation)
  • All three S7-1200 CPUs added to the same project with PROFINET interfaces configured on a common subnet
  • IP addresses assigned and pingable from a programming PC
  • Protection level set to "Full access (no password)" or a known password during commissioning

Step 1 — Define the connection partner in the device configuration

On the CPU that owns the active TSEND_C / TRCV_C block, open Devices & Networks, drag a line from the PROFINET interface of the local CPU to the partner CPU, and configure the connection as ISO-on-TCP. The local ID and the partner ID assigned here are pre-populated into the block instance when you drag the instruction from the task card.

Step 2 — Create the user data block on the sender

Build a DB of the data you want to ship, for example:

DATA_BLOCK "dbSendToPLC3"
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : F
FAMILY : COMM
VERSION : 0.1
  STRUCT
    Header : BYTE;     // sequence counter 0..255
    Counter : INT;      // application counter
    Pressure : REAL;    // engineering value
    Temperature : REAL;
    Timestamp : DTL;    // S7 DTL time stamp
  END_STRUCT;
END_DATA_BLOCK

Step 3 — Instantiate TSEND_C on PLC_1 and PLC_2

Drag Communications > Open User Communication > TSEND_C into a cyclic OB (typically OB1). Wire the inputs:

"TSEND_C_1"(REQ    := "dbSendToPLC3".Header.%X7,   // toggle bit to request send
            CONT   := TRUE,                         // keep connection warm
            LEN    := 24,                            // byte length of the payload
            DATA   := "dbSendToPLC3",
            COM_RST:= FALSE,
            DONE   => "tagTxDone1",
            BUSY   => "tagTxBusy1",
            ERROR  => "tagTxErr1",
            STATUS => "tagTxStatus1");

LEN is the byte count of the data area referenced by DATA. For an S7-Optimized DB, the compiler calculates length at compile time when you drag the symbolic tag.

Step 4 — Instantiate two TRCV_C instances on PLC_3

From the S7-1200 TRCV_C documentation, the block performs three roles: establish the connection, receive the next telegram, and tear the connection down. Each instance points at a different receive DB and uses a different ID:

// TRCV_C #1 — receives from PLC_1
"TRCV_C_1"(EN_R   := TRUE,
            CONT   := TRUE,
            LEN    := 24,
            DATA   := "dbRecvFromPLC1",
            COM_RST:= FALSE,
            DONE   => "tagRxDone1",
            BUSY   => "tagRxBusy1",
            ERROR  => "tagRxErr1",
            STATUS => "tagRxStatus1",
            RCVD_LEN => "tagRxLen1");

// TRCV_C #2 — receives from PLC_2
"TRCV_C_2"(EN_R   := TRUE,
            CONT   := TRUE,
            LEN    := 24,
            DATA   := "dbRecvFromPLC2",
            COM_RST:= FALSE,
            DONE   => "tagRxDone2",
            BUSY   => "tagRxBusy2",
            ERROR  => "tagRxErr2",
            STATUS => "tagRxStatus2",
            RCVD_LEN => "tagRxLen2");

Step 5 — Wire the partner connections

For each TRCV_C, open the block's configuration dialog, click Connection, and select the partner CPU. Use Connection name from the project tree — never assign the same connection object to two different blocks.

Step 6 — Compile and download

Compile the project, download hardware configuration, and download the program to all three CPUs in the same session. Watch the Online > Diagnostics buffer for connection setup status.

ISO-on-TCP vs TCP Selection

Criterion TCP (native) ISO-on-TCP (RFC 1006)
Header overhead Lower Slightly higher (4-byte TPDU)
Partner addressing Port number only IP + TSAP (Transport Service Access Point)
Routing across subnets / routers Native May require special router config
Partner identification on PLC_3 Port-based TSAP-based — recommended when multiple senders exist
S7-1200 first-class support Yes Yes (default for S7 peer-to-peer)

Use ISO-on-TCP for the multi-PLC sourcing case shown above: each partner gets a unique TSAP (for example 10.01 on PLC_1, 10.02 on PLC_2, 10.03 on PLC_3), and the partner-TSAP field on PLC_3 disambiguates the two senders without any application-level routing.

Error and Status Codes

TSEND_C / TRCV_C report a 16-bit STATUS word in their instance DB. Common values you will see during commissioning:

STATUS (hex) Meaning Recovery
0000 No error
7000 Block idle (no request pending) Normal when REQ is FALSE
7001 First call, busy Wait; poll BUSY and DONE
7002 Subsequent call, busy Wait
8085 LEN exceeds 8192, or LEN < 1, or DATA length < LEN Correct the LEN parameter; ensure DATA area is large enough
80A1 Connection or port already in use Check for duplicate connection IDs or partner TSAPs
80A3 Connection being established Wait; check partner CPU is in RUN
80A4 IP address of remote endpoint invalid Verify partner IP and subnet mask
80A7 TCP connection aborted by partner Check partner CPU RUN state and any firewalls
80B3 Connection setup rejected: TSAP / port already assigned Use a unique local TSAP per block
80C3 Connection resource exhausted on local CPU Reduce number of open connections; check CPU connection resource count
80C4 Temporary connection error; COM_RST will reset Trigger COM_RST or restart the connection

The full set of status codes is documented in the TRCV_C instruction reference.

Connection Resource Budget

Each S7-1200 CPU variant has a finite number of open-user-communication connections (separate from PROFINET IO and S7 connections). For example:

  • CPU 1211C / 1212C: 8 open-user-communication connections
  • CPU 1214C: 8 open-user-communication connections
  • CPU 1215C: 16 open-user-communication connections
  • CPU 1217C: 32 open-user-communication connections

TSEND_C uses one connection per direction of communication. If PLC_3 hosts two TRCV_C instances, that consumes two of its open-user-communication slots. Plan headroom for HMI, OPC UA server, and any future send-back channels.

Verification and Commissioning Checklist

  1. Download hardware configuration to all three CPUs. Confirm the PROFINET interface is in RUN (green LED) and the link is up.
  2. Place all three CPUs in RUN. Open Online > Diagnostics > Connection on PLC_3 and verify both connections transition to Established.
  3. From the watch table on PLC_1, force a value in dbSendToPLC3.Counter. Toggle the request bit. Observe DONE rising on the TSEND_C and RCVD_LEN on the matching TRCV_C reaching the expected byte count (24 in the example).
  4. Repeat for PLC_2 and verify the second TRCV_C receives its data into a different receive DB.
  5. Power-cycle PLC_1. The connection on PLC_3 should drop and re-establish automatically within a few seconds when PLC_1 returns. Monitor STATUS for transitions through 7001 → 7002 → 0000.
  6. From the programming PC, Wireshark the PROFINET segment and confirm the ISO-on-TPKT frames (EtherType 0x8100, TPDU payload) carry your expected payload size.

Troubleshooting Matrix

Symptom Likely cause Action
STATUS = 80A4 on receiver Partner IP not reachable Ping partner, verify subnet mask, disable PC firewall
STATUS = 80B3 on receiver TSAP conflict Assign unique local + partner TSAPs per block
DONE never rises on TSEND_C REQ pulse too short, or LEN = 0 Hold REQ until BUSY rises; ensure LEN matches the DB length
RCVD_LEN inconsistent on TRCV_C Senders have different payload sizes; receiver LEN too small Normalise all payload sizes; raise receiver LEN to the maximum possible
Data arrives in wrong DB on PLC_3 TRCV_C instance wired to wrong partner connection Recheck Connection dialog on each TRCV_C
Compile error: "Connection ID already in use" Two blocks on same CPU use the same ID Renumber to a free ID per the table above
Data stops after PLC_1 restart Receiver CONT = FALSE caused disconnect Set CONT = TRUE to keep the connection warm

Variant — PLC_3 as Active Client

For installations that demand deterministic polling, redeploy the topology so PLC_3 owns two TSEND_C blocks and PLC_1, PLC_2 each host one TRCV_C. The trigger is then a PLC_3 OB1 cyclic flag gated by an application-period timer (for example 100 ms via a TON). With CONT = FALSE on the TSEND_C, the connection is torn down immediately after each telegram, ensuring the partner block re-arms cleanly on every cycle.

FAQ

Can TSEND_C and TRCV_C run simultaneously on the same S7-1200?

Yes. The blocks are designed to coexist; you can place multiple instances in OB1 and TIA Portal schedules them within the same cycle. Each instance still requires a unique local connection ID.

What is the maximum payload per TSEND_C call on an S7-1200?

8192 bytes per call, as stated in the S7-1200 manual collection. For larger datasets, fragment the payload and number the fragments in a header byte.

Do I need different connection IDs on PLC_1 and PLC_3 for the same connection?

No. Connection IDs are local to the CPU. PLC_1 can use ID = 1 and PLC_3 can use ID = 2 for the same logical connection; the IDs simply have to be unique within each CPU's open-user-communication pool.

Why is the second TRCV_C on PLC_3 failing with STATUS 80A1?

STATUS 80A1 means the connection or port is already in use. Verify that the second TRCV_C is wired to a distinct partner connection object with its own TSAP, and that its local ID differs from the first TRCV_C and from any other open-user-communication block on PLC_3.

Should I choose TCP or ISO-on-TCP for three S7-1200 CPUs?

Use ISO-on-TCP for S7-to-S7 traffic. The TSAP addressing makes it explicit which partner PLC is on which port, which simplifies diagnostics and firewall rules compared with plain TCP port numbers.

How do I monitor live connection status during commissioning?

Place the block's STATUS, BUSY, ERROR, and DONE outputs in a watch table, or in the TRCV_C online help documented STATUS matrix, and right-click the connection in Online > Diagnostics > Connection for the connection state.

Back to blog