IP_Control UDP: Fixing Multi-Node Connection Limits on ILC

Daniel Price7 min read
Industrial NetworkingOther ManufacturerTroubleshooting
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

Problem Details

An application uses the IP_Control function block on an Inline Controller (ILC 151 class) to exchange UDP datagrams with a large number of remote nodes — in the reported case around 50. Two symptoms dominate:

  1. Instantiating a second IP_Control block with connection parameters identical to an already-open connection does not produce a second independent socket. The stack appears to route the second instance onto the existing connection.
  2. On older firmware, payload data appeared on the wrong connection — datagrams belonging to connection A were delivered to the buffer of connection B. A configurable connect delay was introduced as a workaround for this defect.

A third constraint is architectural rather than a fault: the controller cannot hold 50 simultaneous sockets open. The ILC 1xx family supports a limited pool of independent parallel Ethernet connections — on the order of 8 to 16 depending on controller and firmware. Any design assuming one permanently-open socket per remote node will fail once the pool is exhausted, regardless of how the function blocks are written.

Design rule: With more remote nodes than available connection slots, the only viable topology is sequential multiplexing — open, transact, close, advance to the next node. Confirm the exact socket limit for your controller and firmware in the device data sheet before fixing the pool size in code.

Root Cause Analysis

Symptom Root cause Class
Second instance shares the first connection Identical connection tuple (local port, remote IP, remote port, connection type). The stack cannot open the same endpoint twice, so it resolves the request to the existing handle. By design
Data appears on the wrong connection Firmware defect in older ILC releases during rapid successive connect operations. Mitigated by the IP connect delay parameter. Firmware bug
Connection open fails after N nodes Parallel connection pool exhausted (8–16 range on ILC 1xx class controllers). Hardware/stack limit
Throughput far below expectation One send or one receive operation needs at least one full PLC cycle; ~20 ms per packet is normal for this controller class. Expected behaviour

Why identical parameters collapse

A UDP endpoint is uniquely identified by the socket tuple. If two IP_Control instances are configured with the same local port and the same peer, there is no way for the stack to demultiplex inbound datagrams between them — nothing in the datagram header distinguishes instance 1 from instance 2. The stack therefore either returns an error or binds both instances to one handle. This is not a bug you can code around; you must make the tuples unique.

Solution

1. Make every concurrent connection tuple unique

If two logical channels must run at the same time to the same peer, differentiate them:

  • Assign a distinct local (source) port per instance — the simplest and most reliable differentiator.
  • Or assign a distinct remote port per logical channel, if the peer application supports it.
  • Never duplicate the full tuple across instances and expect two handles.

Maintain a small port allocation table in the project documentation so future edits do not silently reintroduce a duplicate:

Instance      LocalPort   PeerIP           PeerPort   Purpose
IP_Ctrl_1     50001       192.168.0.11     50001      Process data
IP_Ctrl_2     50002       192.168.0.11     50002      Diagnostics
IP_Ctrl_3     50003       192.168.0.12     50001      Process data

2. Multiplex the node list through a connection pool

For 50 nodes with only a handful of slots, implement a round-robin state machine. Keep the pool size at or below the confirmed limit, and reserve at least one slot for engineering access (programming, diagnostics) so a debug session does not starve the application.

CASE eState OF
  IDLE:
    (* select next node from the address array *)
    nNode := (nNode MOD nNodeCount) + 1;
    xConnect := TRUE;
    eState := CONNECTING;

  CONNECTING:
    IF IP_Ctrl.CONNECTED THEN
      tGuard(IN := FALSE);
      eState := TRANSACT;
    ELSIF tGuard.Q THEN            (* connect timeout *)
      eState := TEARDOWN;          (* log + skip node *)
    END_IF

  TRANSACT:
    (* send request, wait for response or timeout *)
    (* budget >= 2 PLC cycles minimum: one to send, one to receive *)
    IF xRxDone OR tGuard.Q THEN
      eState := TEARDOWN;
    END_IF

  TEARDOWN:
    xConnect := FALSE;
    IF NOT IP_Ctrl.CONNECTED THEN
      tSettle(IN := TRUE);         (* optional inter-connect delay *)
      IF tSettle.Q THEN
        tSettle(IN := FALSE);
        eState := IDLE;
      END_IF
    END_IF
END_CASE

Always drive the disconnect explicitly and confirm the handle has actually closed before requesting the next open. Firing a new connect request while the previous close is still in progress is exactly the condition that historically produced cross-connection data mixing.

3. Re-evaluate the IP connect delay

The connect delay parameter exists as a workaround for a firmware defect in which connection data was swapped between handles. On current firmware this delay is frequently unnecessary.

  1. Record the current firmware version of the controller from the diagnostics/engineering tool.
  2. Run the application with the delay at its existing value and log a per-node checksum or node ID inside each payload.
  3. Reduce the delay stepwise — for example halve it — and re-run for an extended soak period.
  4. Test the delay set to 0. If payload node IDs still match the intended peer over a long soak, the delay is not required on that firmware.
  5. If any mismatch appears, restore the last known-good delay value and document it as a firmware-dependent constant, not a tuning knob.
Verification payload: Embed the target node ID (or full peer IP) as the first bytes of every request and require the responder to echo it. This turns a silent data-swap defect into an explicit, loggable mismatch instead of a plausible-looking wrong value in a process variable.

4. Budget the cycle time realistically

On the ILC 1xx class, a single packet send or receive consumes at minimum one PLC cycle, with roughly 20 ms per packet being normal. Build the scan budget from that number rather than from raw Ethernet bandwidth.

Phase per node Minimum cycles
Connect / open handle 1+
Send request 1
Receive response 1
Disconnect / close handle 1+

With a ~20 ms per-packet floor, a single-slot sequential poll of 50 nodes lands in the low seconds per full sweep before any retry or timeout handling. If the application requires a faster refresh, the levers are: run several pool slots in parallel (up to the connection limit), shrink the payload set, or prioritise nodes so critical devices are polled every sweep and the rest on a slower rotation.

Verification

  1. Handle uniqueness: Bring up all intended concurrent instances and confirm each reports its own connected status. If two instances become active from a single connect request, the tuples are duplicated.
  2. Pool ceiling: Incrementally open connections until an open request fails. Record the number — that is your usable pool for this firmware. Set the software pool size at least one below it.
  3. Cross-talk soak: Run the full node rotation for several hours with echoed node IDs. Zero mismatches is the pass criterion; anything else means the connect delay is still required.
  4. Packet capture: Mirror the controller port to a capture tool. Verify source/destination port pairs match the allocation table and that each close is completed before the next open is issued.
  5. Cycle-time margin: Log actual task cycle time under full communication load. Confirm the worst-case cycle still meets the task watchdog with margin; UDP handling adds jitter to the scan.

Reporting an Unresolved Case

If the behaviour persists after the steps above, collect the following before contacting manufacturer support — a diagnosis is not possible without it:

  • Exact controller article/model and installed firmware version.
  • Complete connection parameter set per instance: connection type (UDP), local port, peer IP, peer port.
  • The full source of both function block instances, including how connect/disconnect is sequenced.
  • A description of the intended data flow: who initiates, who responds, payload size, expected repetition rate.
  • A packet capture showing the failing transaction alongside a known-good one.

FAQ

How many simultaneous Ethernet connections can an ILC 151 handle?

Controllers in the ILC 1xx class support a limited pool of independent parallel connections, on the order of 8 to 16 depending on model and firmware. Verify the exact figure in the device data sheet and size your software connection pool at least one slot below it.

Why does a second IP_Control instance reuse the first connection?

Because the connection tuple is identical, the stack cannot open the same endpoint twice and resolves the request to the existing handle. Assign a unique local source port to each concurrent instance.

Can I set the IP connect delay to 0?

Often yes. The delay was introduced to work around an older firmware defect that swapped data between connections. Reduce it stepwise on current firmware and soak-test with echoed node IDs before committing to 0.

Why does each UDP packet take about 20 ms?

On ILC 1xx controllers, one send or one receive operation completes per PLC cycle, so roughly 20 ms per packet is normal. Budget at least four cycles per node for open, send, receive, and close.

How do I poll 50 UDP nodes with only a few sockets?

Use a round-robin state machine that opens a connection, transacts, closes it, and confirms closure before advancing to the next node. Run several pool slots in parallel up to the connection limit, and prioritise critical nodes on a faster rotation.

Back to blog