Problem Statement: TURCV Stuck in Status 16#7002 on UDP Broadcast
Engineers deploying S7-1500 CPUs (S7-1516-3 PN/DP and similar) frequently hit a wall when implementing a UDP broadcast subscriber: the TRCV / TURCV instruction never sets the NDR bit even though the TCON block reports a healthy connection. The instruction outputs STATUS = 16#7002 with BUSY = TRUE continuously, the receive DB stays empty, and the address DB never records a sender. TCON itself shows no error, so the socket appears bound. Wireshark on a peer PC and a C# application on the same subnet capture the broadcast frames without issue, confirming the packets are on the wire.
This article dissects the precise configuration gap between a working point-to-point UDP "send-and-receive" link and a broadcast receive link, the role of the TCON_Param structure (UDT 65) used by TCON, the meaning of the 16#7002 status code returned by TRCV/TURCV, and the PROFINET interface settings that determine whether the S7-1500 actually consumes a broadcast frame. The diagnostic procedure applies to firmware V2.0 onward on the S7-1500 CPUs and to TIA Portal V14 SP1 through V18.
Root Cause: Why UDP Broadcast Reception Fails by Default
Three concurrent faults typically produce this symptom. They are not mutually exclusive, and field experience shows that at least two are usually present simultaneously on a first deployment.
- RemoteAddress filter mismatch. The default UDT 65 "TCON_Param" instance generated by TIA Portal is configured for point-to-point UDP. The RemoteAddress field is left at 0.0.0.0 with a non-zero remote TSAP/port, or set to the unicast address of a specific partner. For broadcast reception, RemoteAddress must equal the subnet-directed broadcast (e.g., 192.168.0.255 for a /24 subnet) or be set to 0.0.0.0 with RemoteTSAPLength = 0 so the socket accepts any sender. When the field is left at the partner's unicast address, the S7-1500 communication stack filters incoming datagrams by remote endpoint and silently discards anything that does not match.
- LocalPort bind mismatch. For UDP on S7-1500, the local TSAP/port must be set explicitly to the port on which the broadcaster targets the PLC. If LocalPort is left at 0, the stack opens an ephemeral port, and broadcast packets aimed at the well-known target port are dropped at the IP layer.
- Layer-2 broadcast suppression. The X1 PROFINET interface on the S7-1500 accepts broadcast by default, but a managed switch between the broadcaster and the PLC may have IGMP/MLD snooping, broadcast storm control, or port isolation enabled. Wireshark on a directly attached PC still sees the frame because it sits in the same broadcast domain, but the PLC port may be filtered.
When STATUS = 16#7002 is reported, the connection has been successfully established, the receive job is active, and the socket is waiting for the first datagram. Because the socket filter rejects every incoming packet, BUSY stays TRUE forever and NDR never transitions from FALSE to TRUE. This is the diagnostic signature of a UDP receive filter mismatch on an otherwise healthy socket.
Connection Model: How TCON Handles UDP on S7-1500
Contrary to common intuition, UDP "connection" handling on S7-1500 is implemented as a unidirectional or bidirectional socket bind. TCON does not establish a connection in the TCP sense; it creates a socket, binds it to a local endpoint, and optionally associates it with a remote endpoint for filtering purposes. TRCV/TURCV then reads from that socket. For broadcast reception, three combinations of TCON_Param are valid.
| Use Case | ConnectionType | ActiveEstablished | Local Port | Remote Address | Remote Port |
|---|---|---|---|---|---|
| Receive broadcasts from any sender | 16#0B (TCP slot) or 16#11 (UDP) | FALSE | Specific (e.g., 3000) | 0.0.0.0 | 0 (any) |
| Receive broadcasts from one subnet | 16#0B or 16#11 | FALSE | Specific port | Subnet broadcast (192.168.0.255) | Specific port |
| Bidirectional send and receive broadcast | 16#0B or 16#11 | TRUE | Specific port | Broadcast address | Specific port |
The S7-1500 firmware supports ConnectionType = 16#0B for UDP on most CPU variants. The value 16#11 is the explicit UDP code and is accepted on firmware V2.6 and later. The official SIMATIC S7-1500 / ET 200MP Communication Function Manual documents the UDT 65 layout for both connection types.
Prerequisites
| Item | Required Value | Notes |
|---|---|---|
| CPU | S7-1516-3 PN/DP (6ES7516-3AN02-0AB0 or 6ES7516-3AP02-0AB0) | Firmware V2.0 minimum; V2.6+ recommended for full UDP broadcast support |
| TIA Portal | V14 SP1 minimum, V16/V17/V18 recommended | Adds new TCON_Param fields and ConnectionType 16#11 |
| Instruction library | "Communication" → "Open User Communication" | Blocks: TCON, TDISCON, TUSEND / TSEND, TURCV / TRCV |
| UDT | "TCON_Param" (UDT 65) auto-generated by TIA Portal | Do not hand-craft; let TIA Portal generate it from the connection configuration |
| PROFINET interface | X1 (PN interface) with IP inside broadcast subnet | X2 if equipped has an independent IP stack |
| Network | Switch with broadcast forwarding enabled on PLC port | Disable storm control and IGMP snooping on the PLC port during commissioning |
| Firmware version check | Online → Accessible nodes → Properties | Confirm firmware supports UDP broadcast filter syntax |
TCON Connection Data Structure (UDT 65) Parameter Mapping
TCON receives a pointer to a connection description DB that contains a UDT 65 "TCON_Param" instance. The fields that determine broadcast behavior are listed below with their byte offsets inside the structure.
| Field | Offset (bytes) | Type | Value for Broadcast RX | Description |
|---|---|---|---|---|
| BlockID | 0 | WORD | 16#0001 (UDP) or 16#0002 (TCP active) | Connection block version identifier |
| ID | 2 | WORD | W#16#0001 to W#16#0FFF | Connection reference; must match the ID input on TRCV |
| ConnectionType | 4 | BYTE | 16#0B (TCP slot reused for UDP) or 16#11 (UDP, FW V2.6+) | 16#0B is universal; 16#11 is explicit UDP |
| ActiveEstablished | 5 | BOOL | FALSE for receive | PLC does not initiate UDP, it listens |
| LocalAddress[1..4] | 6 | ARRAY[1..4] of BYTE | 0,0,0,0 (any) | Local IP; 0.0.0.0 binds to all local interfaces |
| LocalTSAPLength | 10 | BYTE | 2 | Length of port identifier (UDP = 2 bytes) |
| LocalTSAP[1..2] | 11 | ARRAY[1..2] of BYTE | Local port, big-endian (e.g., 16#0B, 16#B8 for 3000) | The port the S7-1500 listens on |
| RemoteAddress[1..4] | 13 | ARRAY[1..4] of BYTE | 192,168,0,255 (broadcast) OR 0,0,0,0 (any) | Critical field for broadcast reception |
| RemoteTSAPLength | 17 | BYTE | 0 (any port) or 2 (specific) | Set to 0 to accept any sender port |
| RemoteTSAP[1..2] | 18 | ARRAY[1..2] of BYTE | 0,0 if length 0; else specific port big-endian | Filter on sender port |
| NextStSendLength | 20 | WORD | 0 | Reserved |
| NextStSendMode | 22 | BYTE | 0 | Reserved |
| Spare | 23 | BYTE | 0 | Reserved |
| ConnectionName | 24 | STRING[16] | Descriptive tag | Optional, for diagnostics only |
Local and remote TSAP IDs are encoded in big-endian byte order. To listen on UDP port 3000 (decimal), LocalTSAP[1] = 16#0B and LocalTSAP[2] = 16#B8 (0x0BB8 = 3000). For port 5000, use 16#13 and 16#88 (0x1388 = 5000).
TURCV / TRCV Block Parameter Reference
| Parameter | Direction | Type | Description | |
|---|---|---|---|---|
| EN_R | Input | BOOL | Receive enable; hold TRUE for continuous broadcast subscription | |
| ID | Input | WORD | Connection reference from TCON; must match UDT 65 ID field | |
| LEN | Input | DINT | 0 = accept any length up to receive buffer size | |
| DATA | InOut | VARIANT | Pointer to receive DB (Array of BYTE) | |
| ADDR | InOut | VARIANT | Pointer to address DB; sender's IP and port written here on each receive | |
| NDR | Output | BOOL | New data received; one-shot pulse per datagram | |
| ERROR | Output | BOOL | Error flag | |
| STATUS | Output | WORD | Status code; 16#7002 = "Receiving, no data yet" | |
| BUSY | Output | BOOL | Job in progress | |
| RCVD_LEN | Output | DINT | Length of data received (TRCV/TRCV_C only) |
For continuous broadcast reception, hold EN_R permanently TRUE. The block keeps the receive job active and sets NDR for one cycle each time a datagram arrives. If the application toggles EN_R only on demand, broadcast packets that arrive between jobs are discarded by the socket.
PROFINET Interface Configuration
- Open the device configuration of the S7-1516-3 in TIA Portal.
- Select the X1 PROFINET interface.
- In Properties → Ethernet addresses, assign an IP address inside the broadcast subnet (e.g., 192.168.0.10/24).
- Verify the subnet mask is /24 (255.255.255.0). A /16 mask would push the subnet broadcast to 192.168.255.255, and a /24 broadcast is filtered.
- Confirm "Use router" is unchecked unless the broadcaster routes through a router that forwards directed broadcasts (most do not by default).
- Disable PROFINET functionality if not needed; PROFINET consumes some protocol handlers but does not affect UDP broadcast reception directly.
- Under Properties → Advanced → Port options, verify that no MAC or broadcast ACL is configured that would drop unknown frames.
Step-by-Step Configuration Procedure
- Add a global DB named "ConnectionDB" with a single variable of type "TCON_Param" (UDT 65). TIA Portal auto-generates UDT 65 the first time TCON is dragged into a code block.
- Configure the ConnectionDB instance with the following values for broadcast RX on port 3000 / subnet 192.168.0.0/24:
- ID = W#16#0001
- ConnectionType = 16#0B (or 16#11 for FW V2.6+)
- ActiveEstablished = FALSE
- LocalAddress[1..4] = 0,0,0,0
- LocalTSAPLength = 2
- LocalTSAP[1] = 16#0B, LocalTSAP[2] = 16#B8 (port 3000)
- RemoteAddress[1..4] = 192,168,0,255 (subnet broadcast)
- RemoteTSAPLength = 0
- RemoteTSAP[1..2] = 0,0 - Create an instance DB for TRCV (e.g., "iDB_TRCV").
- Call TCON in OB1 with REQ = TRUE (one-shot rising edge), ID = 1, CONNECT = "ConnectionDB". TCON completes with STATUS = 16#7000 (idle) once the socket is bound.
- Create a receive DB "DB_RcvData" with Array[0..1499] of BYTE (covers the standard Ethernet MTU minus headers).
- Create an address DB "DB_RcvAddr" using UDT "TADDR_Param" (UDT 66) to capture the sender's IP and port on each receive.
- Call TRCV with EN_R = TRUE, ID = 1, LEN = 0 (any), DATA = "DB_RcvData", ADDR = "DB_RcvAddr".
- Monitor NDR. On the first received datagram, NDR pulses TRUE for one cycle and the data appears in DB_RcvData with the sender's IP and port recorded in DB_RcvAddr.
Equivalent Structured Text (SCL) skeleton for the receive side:
// One-shot TCON in OB100 or first scan
IF "FirstScan" THEN
"TCON_DB".REQ := TRUE;
END_IF;
"TCON_DB".ID := 1;
"TCON_DB".CONNECT := "ConnectionDB";
// Continuous TRCV in OB1
"TRCV_DB".EN_R := TRUE;
"TRCV_DB".ID := 1;
"TRCV_DB".LEN := 0;
"TRCV_DB".DATA := "DB_RcvData";
"TRCV_DB".ADDR := "DB_RcvAddr";
IF "TRCV_DB".NDR THEN
// process "DB_RcvData"[0.."TRCV_DB".RCVD_LEN-1]
END_IF;
TRCV_C vs TRCV (TURCV) Differences
TRCV_C is the higher-level wrapper that internally calls TCON, TRCV, and TDISCON in sequence. It is convenient for short-lived connections. For long-lived broadcast subscriptions, the lower-level TRCV with explicit TCON is preferred for diagnostic clarity.
| Feature | TRCV alone | TRCV_C wrapper |
|---|---|---|
| TCON control | Caller manages TCON explicitly | TRCV_C issues TCON internally |
| Connection persistence | Stays open across scans | Can disconnect/reconnect based on CONT parameter |
| Diagnostic visibility | Direct access to TCON STATUS | TCON STATUS hidden inside instance DB |
| Best for broadcast subscription | Yes — explicit control of bind parameters | Acceptable but harder to diagnose 16#7002 |
| Code footprint | Larger (TCON + TRCV + TDISCON) | Compact (one block, one instance DB) |
The two wrappers consume the same TCON_Param structure, so a working TRCV_C configuration can be migrated to direct TCON + TRCV by moving the connection parameters out of the TRCV_C instance DB into a global connection DB.
Status and Error Code Reference
| STATUS (hex) | Meaning | Recommended Action |
|---|---|---|
| 16#0000 | Connection idle / receive complete (NDR or ERROR set) | Normal; evaluate NDR or ERROR |
| 16#7000 | No job active | Normal idle state |
| 16#7001 | Job being processed, BUSY = TRUE | Wait for completion |
| 16#7002 | Connection established / receive request issued, BUSY = TRUE | Diagnose TCON if persistent; diagnose receive filter if NDR never fires |
| 16#7003 | Connection being terminated | Wait for termination to complete |
| 16#80A0 | Group error | Check the secondary status in the diagnostic DB |
| 16#80A1 | Connection or channel error | Verify physical connection and IP stack |
| 16#80A4 | TCP/UDP connection error | Check LocalPort / RemotePort consistency |
| 16#80A7 | Connection terminated by partner | Unusual for UDP; investigate partner application |
| 16#80AA | Connection not yet established | Issue TCON before TRCV; check TCON STATUS |
| 16#80AB | Security settings violated | Check the CPU's access protection list |
| 16#80C3 | Resource temporarily unavailable | Reduce concurrent UDP connections |
| 16#80C4 | Communication error | Check for IP conflicts and duplicate MAC/IP pairs |
| 16#80C5 | Connection already exists | Re-use existing connection ID; do not open duplicates |
Verification Procedure
- On the PC running the broadcast sender, launch Wireshark on the interface that connects to the PLC's subnet.
- Apply the filter
udp.port == 3000(substitute the actual port). - Trigger a broadcast send and verify the packet appears in Wireshark with destination address 192.168.0.255 (or the relevant subnet broadcast).
- If Wireshark shows the packet but the PLC still reports 16#7002, mirror the PLC's X1 port to a monitor port and confirm the packet arrives at the PLC's physical port. If it does not, the switch is dropping the broadcast.
- If the packet arrives at the PLC port but NDR never fires, open the project online, monitor all, and inspect the ConnectionDB. Confirm RemoteAddress, LocalTSAP, ConnectionType, and ActiveEstablished match the values in the table above.
- Change RemoteAddress to 0,0,0,0 and RemoteTSAPLength to 0 to accept any sender. If NDR now fires, the previous filter was rejecting the packet.
- Once NDR fires, restore the specific broadcast address and a non-zero RemoteTSAPLength for production hardening.
- Validate the sender's address DB (TADDR_Param) is populated; it confirms the datagram passed the IP layer and was delivered to the socket.
Common Pitfalls Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| TRCV stays at 16#7002 forever | RemoteAddress filter rejects the broadcast | Set RemoteAddress to subnet broadcast and RemoteTSAPLength to 0 |
| TCON returns 16#80A4 | LocalPort already in use by another connection | Change LocalPort or release the conflicting ID |
| TRCV returns 16#80AA | TCON was never issued or failed silently | Issue TCON with a one-shot REQ before TRCV; check TCON STATUS |
| Sender IP captured is 192.168.0.255 | Sender is broadcasting and the PLC is replying to itself | Do not send from the PLC on the same connection; separate send/receive IDs |
| NDR fires but RCVD_LEN is wrong | Receive buffer too small or LEN set incorrectly | Set LEN = 0 to accept any length; verify DB size covers expected datagrams |
| Receives work for 60 s then stop | Watchdog or session timeout on managed switch | Configure switch for permanent broadcast forwarding on the PLC port |
| Only some datagrams received | Storm control threshold exceeded | Raise storm control threshold or move PLC to a dedicated VLAN |
Alternative Approaches and Workarounds
If broadcast reception remains unreliable due to switch configuration, consider these patterns.
- Unicast subscription. Modify the PC application to send unicast UDP packets to each subscribed PLC individually, using the PLC's IP as the destination. This bypasses broadcast storm controls and is the recommended approach on managed industrial networks.
- Multicast (PIM/IGMP). Convert to IP multicast (e.g., 239.255.0.1) and configure IGMP snooping properly on the switches. The S7-1500 supports multicast via TCON with ConnectionType = 16#11 and the multicast group in RemoteAddress.
- Use the CP 1543-1 communications processor. Offload UDP handling to a dedicated CP module, which can provide additional firewalling and broadcast filter controls via the security configuration.
- TUSEND from a sender instance. If the broadcast originates from another S7-1500, use TUSEND with the broadcast address as the remote endpoint rather than relying on a Windows application.
- PROFINET IO alarm model. For control-relevant broadcast, consider mapping UDP events onto PROFINET IO alarms instead, leveraging PROFINET's reliable channel.
Behavior Comparison: S7-1500 vs S7-1200 vs S7-300/400
| Aspect | S7-1500 | S7-1200 | S7-300/400 |
|---|---|---|---|
| Receive instruction | TRCV / TRCV_C (TCON + TRCV) | TRCV_C only | TURCV / AG_RECV / AG_LRECV |
| ConnectionType 16#11 (UDP) | FW V2.6+ | All FW | N/A (uses T_UDP) |
| Maximum UDP connections | 16–64 depending on CPU | 8 (CPU 1214) to 32 (CPU 1515C) | 16 typically |
| UDT name | UDT 65 "TCON_Param" | UDT 65 "TCON_Param" | Any, no UDT constraint |
| Broadcast filter syntax | RemoteAddress = broadcast | RemoteAddress = broadcast | Set REMOTE_ADDR to broadcast |
Frequently Asked Questions
Why does TRCV show STATUS = 16#7002 forever and never set NDR?
Status 16#7002 means the receive job is active and waiting for data. If NDR never fires, the receive filter in the TCON_Param is rejecting incoming datagrams. Most often the RemoteAddress field is set to the partner's unicast IP or to 0.0.0.0 without RemoteTSAPLength = 0. Set RemoteAddress to the subnet broadcast (e.g., 192.168.0.255) or to 0.0.0.0 with RemoteTSAPLength = 0 to accept any sender.
What is the correct ConnectionType value for UDP broadcast on S7-1500?
For firmware V2.0–V2.5 use 16#0B with the UDP-specific TSAP layout. For firmware V2.6 onward the explicit UDP code is 16#11. Both work; 16#11 is clearer in the program but is rejected by older firmware versions.
Can I use TRCV_C instead of explicit TCON + TRCV for broadcast reception?
Yes, but TRCV_C hides the TCON STATUS code inside its instance DB, making 16#7002 diagnostics harder. For broadcast subscriptions that run for the lifetime of the PLC, the explicit TCON + TRCV pattern is recommended.
Why does Wireshark see the broadcast but the S7-1500 does not?
Three usual causes: (1) the managed switch has broadcast storm control or IGMP/MLD snooping enabled on the PLC's port; (2) the PLC's X1 IP and the sender's subnet mask do not match, so the broadcast address differs; (3) the PC's Windows firewall is blocking outbound broadcasts. Test by mirror-porting the PLC's port to confirm arrival at the PLC's physical interface.
How many simultaneous UDP connections does the S7-1516-3 support?
The CPU 1516 supports 16 concurrent open-user-communication connections; the CPU 1518 supports 64. Each broadcast subscription consumes one connection. Plan connection IDs across the full range 1–4095 and group send/receive operations on a single connection where possible.
Should I bind to 0.0.0.0 or to the broadcast address in RemoteAddress?
For maximum compatibility across managed switches, use the explicit subnet broadcast address (e.g., 192.168.0.255) and a non-zero RemoteTSAPLength only if you need to filter by sender port. The 0.0.0.0 + RemoteTSAPLength = 0 combination is the most permissive and is the recommended diagnostic configuration when troubleshooting.