Rockwell EtherNet/IP
Connect Allen-Bradley controllers over EtherNet/IP: ControlLogix, CompactLogix, PLC-5, SLC 500, MicroLogix and Micro800, their tag addresses, data types and network discovery.
The Rockwell EtherNet/IP driver talks to Allen-Bradley / Rockwell controllers over EtherNet/IP. ControlLogix and CompactLogix controllers are addressed by the controller tag name declared in the Logix project, a Micro800 by the name of its global variable, and a PLC-5, SLC 500 or MicroLogix by data file address, with no register map involved. Add a device under the Rockwell EtherNet/IP driver in the Connector and pick its Controller family; the panel shows only the fields that family uses.
Controller families
The device's Controller family decides how the controller is reached and how its tags are addressed:
| Controller family | Controllers | Tags are addressed by | Slot |
|---|---|---|---|
| ControlLogix / CompactLogix | ControlLogix, CompactLogix | Controller tag, the tag name | yes |
| PLC-5 | PLC-5 with an Ethernet port (PLC-5/20E, /40E, /80E) | Data file address, such as N7:0 |
no |
| SLC 500 | SLC 5/05 | Data file address | no |
| MicroLogix | MicroLogix 1100 and 1400, and the others through a 1761-NET-ENI | Data file address | no |
| Micro800 | Micro820, Micro850, Micro870 | Controller tag, the name of a global variable | no |
ControlLogix / CompactLogix is the default, and a device created before the field existed is one, so it reads exactly as it always did. Only a ControlLogix or CompactLogix controller is reached across the backplane at a slot: every other family answers on its own Ethernet port, and its device has no Slot field. A scan reads the family off the controller's identity, so a controller it finds arrives with its family already picked.
Connection
| Field | Meaning | Default |
|---|---|---|
| Host | IP address or host name of the controller's Ethernet port. | empty |
| Controller family | Which family the controller belongs to; it decides the fields below and how tags are addressed. | ControlLogix / CompactLogix |
| Slot | ControlLogix / CompactLogix only: which position of the chassis the controller is seated in, counted from 0. | 0 |
| Poll interval (ms) | Device-wide read period for tags that do not override it. | 1,000 |
There is no port field: EtherNet/IP uses its standard TCP port 44818. The CIP
route is the backplane plus the Slot, so a controller seated anywhere in
the chassis is reachable; a discovered controller starts at slot 0 and the
field is where you correct it. There is no rack field: a CIP route carries no
rack number. Requests time out after 10 seconds. The device header shows the
assembled endpoint, for example eip://192.168.0.10:0, where the number after
the address is the slot.
A controller of any other family carries no slot, and its header names the family
instead, for example eip://192.168.0.20?family=slc500.
Each tag may set its own Poll interval (ms); a tag value of 0 falls back to the device interval.
Addressing
A Rockwell tag is addressed by two fields in the tag's Source card:
| Field | Meaning | Accepted values | Default |
|---|---|---|---|
| Controller tag | The tag name as declared in the controller. Required. | free text | empty |
| Offset in tag (bytes, bits for BOOL) | Where inside that tag's data the value sits: a byte offset, or a bit offset for Boolean tags. | 0–255 | 0 |
The driver opens the named controller tag and picks the value out of its data buffer at the offset. For a plain atomic tag the offset stays 0. The offset is what lets one controller tag serve several channels: a DINT at the start of a structure is offset 0, the REAL four bytes later is offset 4, and for a Boolean tag the offset counts bits instead of bytes.
| To read | Controller tag | Offset | Data type |
|---|---|---|---|
A controller-scope DINT Counter |
Counter |
0 | Int32 |
A program-scope DINT in Main |
Program:Main.Counter |
0 | Int32 |
A REAL array element Temps[2] |
Temps[2] |
0 | Float |
An element of a BOOL array Flags[5] |
Flags[5] |
0 | Boolean |
The second DINT inside structure Recipe |
Recipe |
4 | Int32 |
Bit 3 of the data in Flags |
Flags |
3 | Boolean |
In a BOOL array the index names the BOOL, not the controller's 32-bit word:
Flags[5] is BOOL 5, and a bit offset counts on from the BOOL named, so
Flags[5] with offset 2 is BOOL 7.
The name reaches the controller whole, periods included, and a read and a
write of the same tag land in the same place. That is what makes a
program-scoped name such as Program:Main.Counter work. A dotted member path
(MyUdt.Member) is resolved by the controller when the controller publishes
that member by name; where it does not, name the base controller-scope tag and
reach inside it with the byte offset instead, which always works. The Source
card's read-only Source address (wire) line shows the assembled address as
you edit.
A Micro800 is addressed the same way, by the name of a global variable such as
Level: it has no program-scoped tags to name.
Data file addresses
A PLC-5, SLC 500 or MicroLogix tag is addressed by one field, Data file address: the file letter and number, a colon and the element, then a member after a dot or a bit after a slash. There is no offset field, because the address names its element, member and bit itself, and the field refuses as you type an address the driver cannot read, saying why.
| File | Examples | Reads | Data type |
|---|---|---|---|
| Integer (N) | N7:0, N7:0/15 |
a 16-bit word, or one of its bits | Int16 or UInt16; Boolean for a bit |
| Bit (B) | B3:0, B3:0/2 |
a 16-bit word, or one of its bits | Int16 or UInt16; Boolean for a bit |
| Float (F) | F8:1 |
a 32-bit floating point value | Float |
| Long integer (L) | L9:0 |
a 32-bit integer | Int32 or UInt32 |
| Timer (T) | T4:0.ACC, T4:0.PRE, T4:0.DN |
ACC or PRE, or the bit EN, TT or DN | Int16 or UInt16; Boolean for a bit |
| Counter (C) | C5:0.ACC, C5:0.PRE, C5:0.DN |
ACC or PRE, or the bit CU, CD, DN, OV or UN | Int16 or UInt16; Boolean for a bit |
| Control (R) | R6:0.LEN, R6:0.POS |
LEN or POS | Int16 or UInt16 |
| Status (S) | S:1, S:1/15 |
a word of the status file, or one of its bits | Int16 or UInt16; Boolean for a bit |
| Input (I), output (O) | I:0, I:0/1, O:0/1 |
a word of the input or output image, or one of its bits | Int16 or UInt16; Boolean for a bit |
The Data type offered follows the file, and typing an address whose file does
not hold the tag's type changes it to the file's own. The status, input and output
files may be written without their number, as the programming software writes
them; the driver sends them as S2:1, I1:0/1 and O0:0/1, which the
Source address (wire) line shows. In an input or output address the element is
the word's position in the image: a MicroLogix's embedded inputs are I:0/0
onward. A timer, counter or control element is read through one of its members,
never whole, and string, ASCII, BCD, message and PID files are not read. A PLC-5
numbers its inputs and outputs in octal, which the driver does not read, so its I
and O files are refused: read such a value through a data file the program copies
it into. Whether a file exists is known only when it is read: a file the controller
does not hold (N9:0 with no N9) reads as an error from that tag's first read,
and every other tag of the device keeps reading.
Data types
Every atomic CIP type is available as a tag Data type:
| Data type | CIP type | Size |
|---|---|---|
| Boolean | BOOL | 1 bit at the bit offset |
| SByte | SINT | 1 byte |
| Byte | USINT | 1 byte |
| Int16 | INT | 2 bytes |
| UInt16 | UINT | 2 bytes |
| Int32 | DINT | 4 bytes |
| UInt32 | UDINT | 4 bytes |
| Int64 | LINT | 8 bytes |
| UInt64 | ULINT | 8 bytes |
| Float | REAL | 4 bytes |
| Double | LREAL | 8 bytes |
Structures and UDTs are not supported: only the atomic types above can be read or written, which is why the byte offset exists to reach members inside them. String is deliberately absent from the picker: a Logix STRING is not an atomic type but a structure of a length and an 82-byte array, and the driver can neither read nor write one. Byte order on the wire is CIP's own little-endian and is handled automatically; there is no byte-order option.
On a PLC-5, SLC 500 or MicroLogix the type follows the data file instead, as the table of data file addresses above shows.
Writes
Tags whose Access is Read and write or Write only can be written. A write sends the value it was asked for and nothing beside it, so a bit or a member that changes on the controller at the same instant is never put back to what it was a moment before:
| The tag addresses | What the write sends |
|---|---|
| A whole atomic tag (offset 0 and the tag's own size), or a BOOL tag | The value, to that tag |
A bit of an integer tag (Flags, offset 3, Boolean) |
That bit alone, as Flags.3: the controller changes it in place and leaves the other bits as they are |
An element of a BOOL array (Flags[5], Boolean) |
That BOOL alone, as bit 5 of the array's first word (Flags[0].5): the controller changes it in place and leaves the other BOOLs of the word as they are |
A value inside a structure (Recipe, offset 4) |
That member alone, by its name (Recipe.Speed), found in the structure definition the controller publishes |
A write that could only be made by sending the rest of the tag back is refused,
and the reason names the address: part of an atomic tag (an Int16 at offset 2
of a DINT), a bit of a REAL, or an offset where no member of the structure
starts with the size of the value. Address that value by its own name instead,
for example Recipe.Speed with offset 0. The driver works out where a tag's
writes land on its first write and keeps that while the device stays
connected. A new tag starts as Read only.
A data file address is written as it is named: a word, a float or a member whole,
and a bit (B3:0/2, T4:0.DN) alone, which the controller changes in place,
leaving the other bits of its word as they are.
Discovery
The Connector's Discover button broadcasts a CIP List Identity request on every network this computer is on and keeps listening until 10 seconds pass with no new answer. The scan names those networks while it runs, so a result of zero says where the question actually went: a station with virtual adapters for machines, WSL or a VPN often has more networks than the operator expects, and candidates may arrive from one of them.
Interfaces that cannot carry the request are skipped: anything not up, loopback
and tunnel adapters, and an address the interface gave itself because nothing
answered DHCP (169.254.x.x). Only a reply that is a controller's own identity
answer becomes a candidate device, named eip:// plus its address; anything
else answering on the EtherNet/IP port is ignored and said so in the journal.
An Omron controller answers the same request and is left out as well, with a line of its own in
the journal: an NJ, NX or NY controller is offered by the Omron driver's
scan instead.
For each candidate the scan then reads the controller-scope tag list and offers
its atomic tags as candidate channels, each with offset 0.
An array of an atomic type is offered as its first element in that type
(Temps[0], or Grid[0,0] for two dimensions), and a BOOL array as a Boolean
on its first BOOL (Flags[0]).
Discovery discards what the driver cannot poll: structure and UDT tags
(Logix STRINGs included) are dropped, and Program:, Task: and Map:
entries are skipped. A controller on a network this computer is not on does not
answer the broadcast; add it by hand.
A tag of any other type, such as a system type, is not offered either, and
the journal says so.
The identity a controller answers with carries its catalog number, which names its
family: a PLC-5, SLC 500, MicroLogix or Micro800 arrives with its family picked and
its address naming it (eip://192.168.0.20?family=micrologix). A PLC-5, SLC 500
or MicroLogix publishes no tag list, so it arrives with no candidate channels and
its tags are typed by data file address; a Micro800's tag list is read like a Logix
one.
A Logix or Micro800 controller you already have reads its tag list again from its own page: Discover tags, on the head of its Tags card, offers only the controller tags it has no tag for yet, compared by name without regard to case. A data file controller has no list to read and shows no Discover tags (see Discovering a device's tags).
Good to know
- Every request to the controller times out after 10 seconds, and the discovery listen window closes after 10 seconds of silence.
- The driver opens each controller tag once and keeps it open while the device is connected, so a controller with dozens of tags is read over the sessions it already has instead of opening and closing one per reading. A reading that fails lets its tag go, and the next one opens it again by name.
- Renaming a tag in the Logix project silently breaks the channel; the tag then reads as bad quality until the configured name matches again.