# Rockwell EtherNet/IP

> Allen-Bradley-Steuerungen über EtherNet/IP anbinden: ControlLogix, CompactLogix, PLC-5, SLC 500, MicroLogix und Micro800, ihre Tag-Adressen, Datentypen und die Suche im Netz.

Der Treiber **Rockwell EtherNet/IP** spricht über EtherNet/IP mit Allen-Bradley- und
Rockwell-Steuerungen. ControlLogix- und CompactLogix-Steuerungen werden über den Namen
des Controller-Tags adressiert, wie er im Logix-Projekt erklärt ist, eine Micro800 über
den Namen ihrer globalen Variable und eine PLC-5, SLC 500 oder MicroLogix über eine
Datendateiadresse, ganz ohne Registerbelegung. Legen Sie im [Connector](connector) ein
Gerät unter dem Treiber Rockwell EtherNet/IP an und wählen Sie seine
**Controller-Familie**; der Bereich zeigt nur die Felder, die diese Familie verwendet.

## Controller-Familien {#controller-families}

Die **Controller-Familie** des Geräts entscheidet, wie die Steuerung erreicht wird und
wie ihre Tags adressiert werden:

| Controller-Familie | Steuerungen | Tags werden adressiert über | Steckplatz |
| --- | --- | --- | --- |
| **ControlLogix / CompactLogix** | ControlLogix, CompactLogix | **Controller-Tag**, den Tag-Namen | ja |
| **PLC-5** | PLC-5 mit Ethernet-Anschluss (PLC-5/20E, /40E, /80E) | **Datendateiadresse**, etwa `N7:0` | nein |
| **SLC 500** | SLC 5/05 | **Datendateiadresse** | nein |
| **MicroLogix** | MicroLogix 1100 und 1400, die übrigen über ein 1761-NET-ENI | **Datendateiadresse** | nein |
| **Micro800** | Micro820, Micro850, Micro870 | **Controller-Tag**, den Namen einer globalen Variable | nein |

ControlLogix / CompactLogix ist die Voreinstellung, und ein Gerät, das vor diesem Feld
angelegt wurde, gehört dazu und liest also genau wie bisher. Nur eine ControlLogix- oder
CompactLogix-Steuerung wird über den Rückwandbus an einem Steckplatz erreicht: Jede
andere Familie antwortet an ihrem eigenen Ethernet-Anschluss, und ihr Gerät hat kein
Feld **Steckplatz**. Eine Suche liest die Familie aus der Identität der Steuerung, eine
gefundene Steuerung kommt also mit bereits gewählter Familie an.

## Verbindung {#connection}

| Feld | Bedeutung | Standard |
| --- | --- | --- |
| **Hostadresse** | IP-Adresse oder Hostname des Ethernet-Anschlusses der Steuerung. | leer |
| **Controller-Familie** | Zu welcher Familie die Steuerung gehört; sie entscheidet über die Felder darunter und darüber, wie Tags adressiert werden. | ControlLogix / CompactLogix |
| **Steckplatz** | Nur ControlLogix / CompactLogix: auf welchem Platz des Baugruppenträgers die Steuerung sitzt, ab 0 gezählt. | 0 |
| **Abfrageintervall (ms)** | Lesetakt für das ganze Gerät, für Tags, die ihn nicht selbst festlegen. | 1.000 |

Es gibt kein Feld für den Port: EtherNet/IP verwendet seinen üblichen TCP-Port 44818. Die
CIP-Route ist der Rückwandbus plus der **Steckplatz**, eine Steuerung ist also an jedem Platz des
Baugruppenträgers erreichbar; eine gefundene Steuerung beginnt bei Slot 0, und in diesem
Feld berichtigen Sie ihn. Ein Feld für das Rack gibt es nicht: Eine CIP-Route trägt keine
Racknummer. Anfragen laufen nach 10 Sekunden in eine Zeitüberschreitung. Die Kopfzeile des
Geräts zeigt den zusammengesetzten Endpunkt, zum Beispiel `eip://192.168.0.10:0`, wobei die
Zahl hinter der Adresse der Slot ist.

Eine Steuerung jeder anderen Familie trägt keinen Slot, und ihre Kopfzeile nennt
stattdessen die Familie, zum Beispiel `eip://192.168.0.20?family=slc500`.

Jedes Tag darf sein eigenes **Abfrageintervall (ms)** setzen; der Wert 0 an einem Tag fällt
auf das Intervall des Geräts zurück.

## Adressierung {#addressing}

Ein Rockwell-Tag wird über zwei Felder auf der Karte Quelle des Tags adressiert:

| Feld | Bedeutung | Angenommene Werte | Standard |
| --- | --- | --- | --- |
| **Controller-Tag** | Der Name des Tags, wie er in der Steuerung erklärt ist. Pflichtfeld. | Freitext | leer |
| **Offset im Tag (Bytes, Bits bei BOOL)** | Wo innerhalb der Daten dieses Tags der Wert sitzt: ein Versatz in Bytes oder, bei Tags vom Typ Boolean, ein Versatz in Bits. | 0–255 | 0 |

Der Treiber öffnet das genannte Controller-Tag und holt den Wert am Versatz aus dessen
Datenpuffer. Bei einem einfachen atomaren Tag bleibt der Versatz 0. Der Versatz ist das,
was ein Controller-Tag mehrere Kanäle bedienen lässt: Ein DINT am Anfang einer Struktur hat
den Versatz 0, das REAL vier Bytes später den Versatz 4, und bei einem Tag vom Typ Boolean
zählt der Versatz Bits statt Bytes.

| Zu lesen | Controller-Tag | Versatz | Datentyp |
| --- | --- | --- | --- |
| Ein DINT `Counter` im Gültigkeitsbereich der Steuerung | `Counter` | 0 | Int32 |
| Ein DINT im Gültigkeitsbereich des Programms `Main` | `Program:Main.Counter` | 0 | Int32 |
| Ein Element `Temps[2]` eines REAL-Feldes | `Temps[2]` | 0 | Float |
| Ein Element `Flags[5]` eines BOOL-Feldes | `Flags[5]` | 0 | Boolean |
| Das zweite DINT in der Struktur `Recipe` | `Recipe` | 4 | Int32 |
| Bit 3 der Daten in `Flags` | `Flags` | 3 | Boolean |

In einem BOOL-Feld benennt der Index das BOOL, nicht das 32-Bit-Wort der
Steuerung: `Flags[5]` ist BOOL 5, und ein Bitversatz zählt ab dem benannten BOOL
weiter, `Flags[5]` mit Versatz 2 ist also BOOL 7.

Der Name erreicht die Steuerung ganz, Punkte eingeschlossen, und ein Lese- und ein
Schreibvorgang desselben Tags landen an derselben Stelle. Genau das lässt einen Namen aus
dem Gültigkeitsbereich eines Programms wie `Program:Main.Counter` funktionieren. Einen
Pfad zu einem Element mit Punkt (`MyUdt.Member`) löst die Steuerung auf, wenn sie dieses
Element unter seinem Namen veröffentlicht; wo sie das nicht tut, nennen Sie das Tag im
Gültigkeitsbereich der Steuerung und greifen mit dem Byte-Versatz hinein, was immer
funktioniert. Die Zeile **Quelladresse (Bus)** auf der Karte Quelle, die nur gelesen wird,
zeigt die zusammengesetzte Adresse, während Sie tippen.

Eine Micro800 wird genauso adressiert, über den Namen einer globalen Variable wie
`Level`: Sie hat keine programmbezogenen Tags, die zu nennen wären.

### Datendateiadressen {#data-file-addresses}

Ein Tag einer PLC-5, SLC 500 oder MicroLogix wird über ein einziges Feld adressiert,
**Datendateiadresse**: Buchstabe und Nummer der Datei, ein Doppelpunkt und das Element,
danach ein Unterelement nach einem Punkt oder ein Bit nach einem Schrägstrich. Ein Feld
für den Offset gibt es nicht, weil die Adresse ihr Element, ihr Unterelement und ihr Bit
selbst nennt, und das Feld weist schon bei der Eingabe eine Adresse zurück, die der
Treiber nicht lesen kann, und sagt, warum.

| Datei | Beispiele | Liest | Datentyp |
| --- | --- | --- | --- |
| Integer (N) | `N7:0`, `N7:0/15` | ein 16-Bit-Wort oder eines seiner Bits | Int16 oder UInt16; Boolean für ein Bit |
| Bit (B) | `B3:0`, `B3:0/2` | ein 16-Bit-Wort oder eines seiner Bits | Int16 oder UInt16; Boolean für ein Bit |
| Gleitkomma (F) | `F8:1` | einen 32-Bit-Gleitkommawert | Float |
| Long Integer (L) | `L9:0` | eine 32-Bit-Ganzzahl | Int32 oder UInt32 |
| Timer (T) | `T4:0.ACC`, `T4:0.PRE`, `T4:0.DN` | ACC oder PRE, oder das Bit EN, TT oder DN | Int16 oder UInt16; Boolean für ein Bit |
| Zähler (C) | `C5:0.ACC`, `C5:0.PRE`, `C5:0.DN` | ACC oder PRE, oder das Bit CU, CD, DN, OV oder UN | Int16 oder UInt16; Boolean für ein Bit |
| Control (R) | `R6:0.LEN`, `R6:0.POS` | LEN oder POS | Int16 oder UInt16 |
| Status (S) | `S:1`, `S:1/15` | ein Wort der Statusdatei oder eines seiner Bits | Int16 oder UInt16; Boolean für ein Bit |
| Eingang (I), Ausgang (O) | `I:0`, `I:0/1`, `O:0/1` | ein Wort des Eingangs- oder Ausgangsabbilds oder eines seiner Bits | Int16 oder UInt16; Boolean für ein Bit |

Der angebotene **Datentyp** folgt der Datei, und eine Adresse, deren Datei den Typ des
Tags nicht führt, stellt ihn auf den Typ der Datei um. Die Status-, Eingangs- und
Ausgangsdatei dürfen ohne ihre Nummer geschrieben werden, wie die
Programmiersoftware sie schreibt; der Treiber sendet sie als `S2:1`, `I1:0/1` und
`O0:0/1`, und die Zeile **Quelladresse (Bus)** zeigt das. In einer Eingangs- oder
Ausgangsadresse ist das Element die Position des Worts im Abbild: Die eingebauten
Eingänge einer MicroLogix beginnen bei `I:0/0`. Ein Timer-, Zähler- oder
Control-Element wird über eines seiner Unterelemente gelesen, nie als Ganzes, und
String-, ASCII-, BCD-, Message- und PID-Dateien werden nicht gelesen. Eine PLC-5
nummeriert ihre Ein- und Ausgänge oktal, und das liest der Treiber nicht, deshalb werden
ihre I- und O-Dateien zurückgewiesen: Lesen Sie einen solchen Wert über eine Datendatei,
in die das Programm ihn kopiert. Ob eine Datei existiert, zeigt sich erst beim Lesen:
Eine Datei, die die Steuerung nicht hat (`N9:0` ohne N9), liest sich ab dem ersten
Lesen dieses Tags als Fehler, und alle anderen Tags des Geräts lesen weiter.

## Datentypen {#data-types}

Jeder atomare CIP-Typ steht als **Datentyp** eines Tags zur Verfügung:

| Datentyp | CIP-Typ | Größe |
| --- | --- | --- |
| Boolean | BOOL | 1 Bit am Bit-Versatz |
| 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 |

Strukturen und UDTs werden nicht unterstützt: Nur die atomaren Typen oben lassen sich lesen
oder schreiben, und genau dafür gibt es den Byte-Versatz, um Elemente in ihnen zu erreichen.
String fehlt bewusst in der Auswahl: Ein Logix-STRING ist kein atomarer Typ, sondern eine
Struktur aus einer Länge und einem 82 Byte großen Feld, und der Treiber kann keinen lesen
und keinen schreiben. Die Byte-Reihenfolge auf dem Bus ist das Little-Endian von CIP selbst
und wird automatisch behandelt; eine Wahl der Byte-Reihenfolge gibt es nicht.

Bei einer PLC-5, SLC 500 oder MicroLogix folgt der Typ stattdessen der Datendatei, wie
die Tabelle der Datendateiadressen oben zeigt.

## Schreiben {#writes}

Tags, deren **Zugriff** Lesen und schreiben oder Nur schreiben ist, lassen sich schreiben. Ein
Schreibvorgang sendet den verlangten Wert und nichts daneben. Ein Bit oder ein Element, das
sich im selben Augenblick in der Steuerung ändert, wird deshalb nie auf den Stand von eben
zurückgesetzt:

| Das Tag adressiert | Was der Schreibvorgang sendet |
| --- | --- |
| Ein ganzes atomares Tag (Versatz 0 und die Größe des Tags selbst) oder ein Tag vom Typ BOOL | Den Wert, an dieses Tag |
| Ein Bit eines Ganzzahl-Tags (`Flags`, Versatz 3, Boolean) | Nur dieses Bit, als `Flags.3`: Die Steuerung ändert es an Ort und Stelle und lässt die anderen Bits, wie sie sind |
| Ein Element eines BOOL-Feldes (`Flags[5]`, Boolean) | Nur dieses BOOL, als Bit 5 des ersten Wortes des Feldes (`Flags[0].5`): Die Steuerung ändert es an Ort und Stelle und lässt die anderen BOOLs des Wortes, wie sie sind |
| Einen Wert in einer Struktur (`Recipe`, Versatz 4) | Nur dieses Element, unter seinem Namen (`Recipe.Speed`), gefunden in der Strukturdefinition, die die Steuerung veröffentlicht |

Ein Schreibvorgang, der sich nur ausführen ließe, indem der Rest des Tags zurückgeschrieben
wird, wird abgelehnt, und die Begründung nennt die Adresse: ein Teil eines atomaren Tags
(ein Int16 bei Versatz 2 eines DINT), ein Bit eines REAL oder ein Versatz, an dem kein
Element der Struktur mit der Größe des Werts beginnt. Adressieren Sie den Wert dann unter
seinem eigenen Namen, zum Beispiel `Recipe.Speed` mit Versatz 0. Wohin die Schreibvorgänge
eines Tags gehen, ermittelt der Treiber beim ersten Schreiben und behält es, solange das
Gerät verbunden bleibt. Ein neues Tag beginnt als Nur lesen.

Eine Datendateiadresse wird so geschrieben, wie sie benannt ist: ein Wort, ein
Gleitkommawert oder ein Unterelement als Ganzes, und ein Bit (`B3:0/2`, `T4:0.DN`)
allein, das die Steuerung an Ort und Stelle ändert, während die übrigen Bits seines
Worts bleiben, wie sie sind.

## Gerätesuche {#discovery}

Die Schaltfläche Suchen des Connector sendet eine CIP-Anfrage List Identity als Rundruf in
**jedes Netz, in dem dieser Rechner ist**, und hört so lange zu, bis 10 Sekunden ohne neue
Antwort vergangen sind. Der Suchlauf nennt diese Netze, während er läuft, ein Ergebnis von
null sagt also, wohin die Frage tatsächlich ging: Eine Station mit virtuellen Adaptern für
Maschinen, WSL oder ein VPN hat oft mehr Netze, als der Bediener erwartet, und Kandidaten
können aus einem davon kommen.

Schnittstellen, die die Anfrage nicht tragen können, werden übersprungen: alles, was nicht
oben ist, Loopback- und Tunneladapter sowie eine Adresse, die sich die Schnittstelle selbst
gegeben hat, weil niemand auf DHCP geantwortet hat (169.254.x.x). Nur eine Antwort, die die
eigene Identitätsantwort einer Steuerung ist, wird zu einem Kandidaten für ein Gerät,
benannt mit `eip://` und seiner Adresse; alles andere, was auf dem EtherNet/IP-Port
antwortet, wird übergangen und im Journal genannt. Eine Omron-Steuerung beantwortet dieselbe
Anfrage und wird ebenfalls übergangen, mit einer eigenen Zeile im Journal: Eine NJ-, NX- oder
NY-Steuerung bietet stattdessen der Suchlauf des Treibers [Omron](driver-omron#discovery) an.
Für jeden Kandidaten liest der Suchlauf
danach die Tagliste im Gültigkeitsbereich der Steuerung und bietet ihre atomaren Tags als
Kandidaten für Kanäle an, jedes mit dem Versatz 0.
Ein Feld eines atomaren Typs wird als sein erstes Element in diesem Typ angeboten
(`Temps[0]`, bei zwei Dimensionen `Grid[0,0]`), ein BOOL-Feld als Boolean auf
seinem ersten BOOL (`Flags[0]`).

Die Gerätesuche verwirft, was der Treiber nicht zyklisch lesen kann: Tags von Strukturen
und UDTs (Logix-STRINGs eingeschlossen) fallen weg, und Einträge mit `Program:`, `Task:`
und `Map:` werden übersprungen. Eine Steuerung in einem Netz, in dem dieser Rechner nicht
ist, antwortet nicht auf den Rundruf; legen Sie sie von Hand an.
Ein Tag jedes anderen Typs, etwa eines Systemtyps, wird ebenfalls nicht
angeboten, und das Journal nennt es.

Die Identität, mit der eine Steuerung antwortet, trägt ihre Katalognummer, und die nennt
ihre Familie: Eine PLC-5, SLC 500, MicroLogix oder Micro800 kommt mit gewählter Familie
an, und ihre Adresse nennt sie (`eip://192.168.0.20?family=micrologix`). Eine PLC-5,
SLC 500 oder MicroLogix veröffentlicht keine Tag-Liste, kommt also ohne
Kandidatenkanäle an, und ihre Tags werden per Datendateiadresse eingetragen; die
Tag-Liste einer Micro800 wird wie die einer Logix gelesen.

Eine Logix- oder Micro800-Steuerung, die Sie schon haben, liest ihre Tag-Liste von ihrer eigenen Seite aus erneut: **Tags suchen** im Kopf ihrer Karte der Tags bietet nur die Steuerungs-Tags an, für die sie noch kein Tag hat, verglichen nach dem Namen ohne Rücksicht auf Groß- und Kleinschreibung. Eine Datendatei-Steuerung hat keine Liste zum Lesen und zeigt kein Tags suchen (siehe [Die Tags eines Geräts suchen](connector-discovery#discovering-a-devices-tags)).

## Gut zu wissen {#good-to-know}

- Jede Anfrage an die Steuerung läuft nach 10 Sekunden in eine Zeitüberschreitung, und das
  Zeitfenster, in dem die Gerätesuche zuhört, schließt nach 10 Sekunden Stille.
- Der Treiber öffnet jedes Tag der Steuerung einmal und hält es offen, solange das Gerät
  verbunden ist; eine Steuerung mit Dutzenden Tags wird also über die Sitzungen gelesen,
  die sie schon hat, statt pro Lesevorgang eine zu öffnen und wieder zu schließen. Ein
  fehlgeschlagener Lesevorgang gibt sein Tag frei, und der nächste öffnet es erneut über
  den Namen.
- Das Umbenennen eines Tags im Logix-Projekt bricht den Kanal stillschweigend; das Tag
  liest dann schlechte Qualität, bis der eingestellte Name wieder passt.
