Skip to content

MSG — EtherNet/IP

Category
Communication
Type
Output
Availability
Boards with an Ethernet shield or port (W5100 / W5500 shields; Mega, STM32, Pico, Teensy recommended)

MSG instruction block for an EtherNet/IP read: Type: READ EIP, Device: PLC, Local: PLC_Data, Length: 4


With the protocol set to eip, MSG reads or writes a tag by name in an Allen-Bradley Logix controller (CompactLogix, ControlLogix, Micro800 with the CIP Data Table service) over EtherNet/IP explicit messaging. The rung’s rising edge queues the request; a client service runs the TCP connection a little on every scan, so the logic never waits on the network. The reply lands in the Local array, or the Local array is written to the PLC’s tag, and the optional status tag reports the result. Use it to hand production counts, recipes and status between an Arduino and a Logix PLC without any tag mapping on the PLC side. Do not use it for I/O-style cyclic data: it is one request per rung edge, and each transfer is a full round trip.


Operand Type Format Valid Range Required Description
Direction Choice read / write — Yes Read the PLC tag into Local, or write Local into the PLC tag.
Protocol Choice eip Selected for you when the device is an EtherNet/IP peer Yes
Port Comm port Ethernet The port an Ethernet shield provides Yes
Device Network peer Name An Ethernet Device under the Ethernet port with Protocol = EtherNet/IP and a valid IP address Yes Supplies IP, TCP port (44818) and the CPU slot for the route.
Local data Tag INT, DINT or REAL array, or Buf[n] Window must fit; the type must match the PLC tag Yes INT ↔ Logix INT, DINT ↔ DINT, REAL ↔ REAL. The CIP type sent comes from this tag.
Length INT 1 to what fits one frame Build error above the limit Yes Elements transferred.
Remote tag Text Logix tag name, optionally .member or [index] Letters, digits, underscore Yes The PLC-side tag, e.g. Line_Counts or Recipe[2]. Case as in the PLC.
Status (opt) CONTROL tag Name One per MSG No EN queued, DN success, ER failure, POS = CIP general status (0 = OK, 255 = transport failure).

Nothing. No connection exists until the first message is queued.

Nothing new. A queued or in-flight transfer continues. The edge memory is armed.

On the rising edge the request is queued; with a status tag, EN = 1, DN = ER = 0. The client service then, over the following scans: opens the TCP session if none is open (one bounded 200 ms connect attempt, retried every 2 s while the PLC is unreachable), registers the session, sends the CIP Read Tag or Write Tag inside an Unconnected Send routed to the CPU slot, and waits up to one second for the reply. On success a read is unpacked element by element into Local and DN = 1; a write sets DN = 1. On a CIP error, a type or length mismatch, or a timeout, nothing is copied, ER = 1 and POS holds the status; the socket is dropped so the next attempt starts clean.

Nothing.

Outcome EN DN ER POS Local
Queued / in flight 1 0 0 last unchanged
Success 0 1 0 0 updated (read)
PLC refused (unknown tag 0x04, type mismatch 0xFF ext 0x2107, …) 0 0 1 CIP general status unchanged
No reply / no connection 0 0 1 255 unchanged

Member Data type Set by Cleared by Description
EN BOOL Rung edge Service on completion Queued or in flight.
DN BOOL Service on success Next rung edge Last transfer succeeded.
ER BOOL Service on failure Next rung edge Last transfer failed.
POS DINT Service — CIP general status of the last transfer; 0 = OK, 255 = transport failure.

Scenario: A line PLC keeps four production counters in a DINT array tag Line_Counts. An Arduino behind a W5100 Ethernet shield reads them on demand and flags success or failure for the operator display.

Network tree: Eth — W5100 Ethernet Shield on SPI, static IP 192.168.1.177. PLC — Ethernet Device under Ethernet, Protocol EtherNet/IP, IP 192.168.1.20, port 44818, slot 0.

Tags:

  • Read_PLC — Read PLC counts, BOOL
  • PLC_Data — Line counts from the PLC, DINT[4]
  • Plc_Sts — PLC message status, CONTROL
  • Plc_Ok, Plc_Fault — BOOL

Rung 1:

—|XIC Read_PLC|———[MSG READ EIP Device PLC Local PLC_Data Length 4 Remote tag Line_Counts Status Plc_Sts]———

Rung 2:

——┬——|XIC Plc_Sts.DN|———(OTE Plc_Ok)——————┬——
└——|XIC Plc_Sts.ER|———(OTE Plc_Fault)———┘

Figure 1 — The MSG dialog for the EtherNet/IP read: read, eip, port Ethernet, device PLC, local PLC_Data, length 4, remote tag Line_Counts, status Plc_Sts

Scan 1 — Read_PLC = 0. Nothing queued. Plc_Sts.EN = 0.

Figure 2 — EIP MSG rung false: Read_PLC off, wire dark, the block showing READ EIP, PLC, PLC_Data, Length 4

Scan 2 — Read_PLC = 1 (rising edge). The request is queued: Plc_Sts.EN = 1, DN = ER = 0. A few scans later, on hardware, the reply arrives: PLC_Data = the four counters, Plc_Sts.DN = 1, EN = 0, and rung 2 energizes Plc_Ok.

Figure 3 — EIP MSG rung true: Read_PLC on, the wire lit through the block

Figure 4 — Both rungs with Plc_Sts.DN set: the read rung above, and below it the status rung’s top leg lit with Plc_Ok energized while the ER leg stays dark

Values before and after: PLC_Data 0,0,0,0 → the PLC’s Line_Counts; Plc_Sts.DN 0 → 1. In the simulator nothing is transferred; Figure 4 was taken with Plc_Sts.DN set by hand in the Tag Browser, which is why the read rung above it is still lit.



Types must match the PLC tag. The CIP element type is taken from the Local tag: INT, DINT or REAL. Reading a Logix DINT into an INT array is refused by the PLC and reported as ER with POS 255 and extended status 0x2107. A BOOL or STRING Local is a build error.

Tag names, not addresses. Controller-scope tags are named as they appear in Studio 5000. Program-scope tags need the Program:MainProgram. prefix. Array elements and structure members work: Recipe[2], Motor.Speed.

Route and slot. The request is wrapped in an Unconnected Send to 1,<slot>, the backplane route a real Logix MSG uses. A CompactLogix with embedded Ethernet answers with slot 0. Leave the peer’s “Connected” style options off; this is unconnected messaging only.

One peer per project, within the socket budget. Each client holds one socket. A W5100 has four sockets, a W5500 eight, and the board’s own EtherNet/IP server (when enabled on the shield) takes two.

Memory. The client needs about 600 bytes of frame buffer. It builds and runs on an Uno with a warning, but a Mega, STM32, Pico or Teensy is where it belongs alongside a real program.

Length limit. A transfer must fit one CIP frame; the build reports the limit for the Local type. Split a large block across several MSGs.

Verified against a 1769-L23E in both directions over a Mega with a W5100 shield.

Applies to LadderIDE >=1.2.2 · Last reviewed 2026-09-11 · Screenshots verified 2026-09-11