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.
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
- PLC_3 cannot poll the source PLCS for freshness; it only learns of new data when a send arrives.
- 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
- Download hardware configuration to all three CPUs. Confirm the PROFINET interface is in RUN (green LED) and the link is up.
- Place all three CPUs in RUN. Open Online > Diagnostics > Connection on PLC_3 and verify both connections transition to Established.
- From the watch table on PLC_1, force a value in
dbSendToPLC3.Counter. Toggle the request bit. ObserveDONErising on the TSEND_C andRCVD_LENon the matching TRCV_C reaching the expected byte count (24 in the example). - Repeat for PLC_2 and verify the second TRCV_C receives its data into a different receive DB.
- Power-cycle PLC_1. The connection on PLC_3 should drop and re-establish automatically within a few seconds when PLC_1 returns. Monitor
STATUSfor transitions through 7001 → 7002 → 0000. - 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.