Advamation RS-485-/I2C-Protokoll
Stand: | 2014-04-15 |
---|
Inhalt
1 Allgemeines Konzept
Das Advamation RS-485-/I2C-Protokoll ist ein schlankes und einfaches Feldbus-Protokoll, um I/Os, Sensoren, Aktoren usw. anzubinden.
Im Gegensatz zu vielen anderen Feldbus-Protokollen wurde dabei stark auf die Einfachheit des Protokolls geachtet:
- einfache Benutzbarkeit: Das Protokoll soll einfach zu verstehen und zu benutzen sein, ohne hunderte Seiten an Dokumentation lesen zu müssen.
- einfache Implementierbarkeit und geringe Rechenlast: Das Protokoll soll selbst auf sehr kleinen Mikrocontrollern (z.B. 8-Bit-Mikrocontroller mit 128 Byte Arbeitsspeicher) implementierbar sein, ohne den Mikrocontroller zu sehr auszulasten; zudem soll der Implementierungsaufwand gering bleiben.
- geringer Hardwareaufwand: Es soll nie ein separater Kommunikationscontroller notwendig sein; stattdessen soll nur 1 Mikrocontroller notwendig sein, der sowohl die eigentliche Sensor- bzw. Aktor-Funktionalität als auch die Kommunikation beinhaltet.
- geringer Overhead: Der Kommunikationsoverhead soll möglichst gering sein.
- kostengünstige Hardware: Durch die Einfachheit und den geringen Ressourcenbedarf des Protokolls können die Hardwarekosten gering gehalten werden. Zudem sind die standardmäßig vorgesehenen Bus-Steckverbinder sehr günstig (aber dennoch robust).
- offenes System und freie Dokumentation: Die Dokumentation zum Protokoll ist frei verfügbar, und das Protokoll darf von jedermann frei verwendet werden. Zudem bieten wir für das Protokoll kostenlose und frei verwendbare Programmbibliotheken und Beispielprogramme an.
- Flexibilität und einfache Erweiterbarkeit: Das Protokoll definiert primär einige Rahmenbedingungen, die alle Geräte, die am gleichen Bus angeschlossen sind, erfüllen müssen. Darüber hinaus definiert es einige häufig verwendete Funktionen (z.B. zur Adresseinstellung, zum Lesen/Schreiben von I/Os usw.), von denen jedes Gerät jedoch nur den für das Gerät passenden Teil implementiert. Weiterhin enthält das Protokoll explizit Platz für gerätespezifische Erweiterungen.
- Verständlichkeit/Nachvollziehbarkeit: Das Protokoll soll einfach zu verstehen sein, so dass jeder Anwender in der Lage ist, selbst die Details der Kommunikation zu verstehen, und durch eine einfache Analyse der Kommunikations-Rohdaten die Kommunikation nachvollziehen zu können. Dies vermeidet Fehler und erleichtert die Fehlersuche.
Um dies zu erreichen, hat das Protokoll u.a. folgende Eigenschaften:
- Single-Master-Betrieb: Pro Bus gibt es im Normalfall nur einen einzigen Master. Nur dieser Master darf eine Kommunikation initiieren.
- Interrupt: Für Fälle, in denen ein Slave eine Kommunikation initiieren können soll, oder in denen intensives Polling vermieden werden soll, ist eine Art "Interrupt" vorgesehen.
- Binäre Übertragung: Die Übertragung erfolgt üblicherweise binär, um unnötigen Overhead zu vermeiden. Eine Übertragung als ASCII ist nicht vorgesehen, es ist jedoch sehr einfach möglich, die Binärdaten als menschenlesbaren ASCII-Text darzustellen.
- Funktionsgruppen statt Geräteprofile: Statt komplizierter – und dennoch häufig doch nicht passender – Geräteprofile werden "Funktionsgruppen" definiert, damit ähnliche Funktionen auf verschiedenen Geräten ähnlich ansprechbar sind.
- Automatische Gerätesuche und Adresseinstellung: Eine Möglichkeit, alle am Bus angeschlossenen Geräte zu finden und deren Adressen kollisionsfrei einzustellen bzw. Adresskonflikte aufzulösen, ist vorgesehen. Die Adressen werden üblicherweise im Speicher der Geräte abgelegt, eine Einstellung z.B. per DIP-Schalter am Gerät ist normalerweise nicht notwendig.
Unsere langjährige Erfahrung hat dabei immer wieder gezeigt, dass ein derart einfaches Protokoll für die überwiegende Mehrheit an Automatisierungsaufgaben ausreicht, und dabei deutlich kostengünstiger, einfacher und problemloser ist, als viele komplizierte Feldbusse. Sollte dieses Protokoll in Einzelfällen nicht ausreichend sein, so kann dies üblicherweise durch die Verwendung gerätespezifischer Erweiterungen, angepasster Slaves, spezieller Master (bzw. "Zwischen-Master") oder mehrerer Busse gelöst werden.
2 Schnittstellen
Das Protokoll wurde primär für die Kommunikation mit Automatisierungskomponenten über RS-485 entwickelt. Es wird von uns in sehr ähnlicher Form jedoch auch für die Kommunikation über I2C bzw. SMBus verwendet, und kann – ggf. geringfügig abgewandelt – auch zur Kommunikation über andere Schnittstellen (z.B. SPI, RS-232) verwendet werden.
2.1 RS-485
Die RS-485-Schnittstelle ist eine störfeste Industrieschnittstelle, an die als Bus (evtl. mittels Hubs) mehrere Geräte angeschlossen werden können, und die auch für die Überbrückung langer Distanzen geeignet ist.
Sie ist somit die bevorzugte Schnittstelle für externe Automatisierungskomponenten (z.B. Sensoren, Messtaster, Motoren, Linearachsen usw., wie z.B. unseren Automatisierungs-Baukasten) und für die störfeste Überbrückung längerer Distanzen.
- Hardware:
2 Datenleitungen + Masse
ggf. zusätzliche Stromversorgungsleitungen
Verdrahtung als Bus, mit Hubs als Stern, oder gemischt
Abschlusswiderstände/Leitungs-Terminatoren: Die Bus-Enden sollten mit Abschlusswiderständen passend zum Wellenwiderstand des verwendeten Kabels abgeschlossen werden, um Reflexionen zu minimieren. Üblich ist hierbei folgender Abschlusswiderstand (für Wellenwiderstände von ca. 110 Ohm):
+5V --+ | 680 Ohm | +----- RS-P | 120 Ohm | +----- RS-N | 680 Ohm | GND --+
- Kommunikation:
- Halbduplex
- Baudrate: 115.2 kbps (optional zusätzlich höhere Baudrates)
- Datentransfer: 8 Bit + 1 Adress-Bit ("Mark / Space Parity")
RS-485-Steckverbinder: D-Sub 7W2, Buchse/Stecker
Die von uns üblicherweise verwendeten RS-485-Steckverbinder enthalten neben den Datenleitungen mehrere Stromversorgungsleitungen, so dass 1 Kabel zum Anschluss eines externen Geräts ausreicht, und keine zusätzlichen Stromkabel notwendig sind. Der Steckverbinder ist verschraubbar und kann optional wasserdicht ausgeführt werden.
RS-485-Buchse (z.B. Netzteilausgang) RS-485-Stecker (z.B. Geräteeingang) (Ansicht: Steckseite) (Ansicht: Steckseite) Netzteile sowie Kommunikations-Master und Hub-Ausgänge, die Strom liefern, besitzen eine RS-485-Buchse.
Slave-Geräte besitzen einen RS-485-Stecker. Optional können Slave-Geräte zusätzlich eine RS-485-Buchse besitzen, um mehrere Slaves direkt hintereinander hngen zu können und damit die Verkabelung zu vereinfachen.
Pin Signal Strom Beschreibung 1 +24V max. 5A 24V-Stromversorgung, bei Bedarf 2 +12V max. 5A 12V-Elektronik-Stromversorgung 3 DGND max. 5A Masse für Pin 1 + 2 4 RS-N RS-485-Datenleitung, im Ruhezustand negativere Leitung (ca. 2.3V) 5 RS-P RS-485-Datenleitung, im Ruhezustand positivere Leitung (ca. 2.7V) A1 (+12..+48V) max. 30A Leistungs-Stromversorgung, optional A2 (PGND) max. 30A Masse für Pin A1, optional
2.2 I2C
Der I2C-Bus ist mittlerweile die Schnittstelle für digitale Sensoren. Sie ist insbesondere für Peripherie geeignet, die sich im gleichen Gehäuse wie der Kommunikations-Master befindet.
Für externe Peripherie kann I2C ebenfalls verwendet werden – da der I2C jedoch nicht störsicher ist, sollten dann entsprechende Maßnahmen gegen elektrische Störungen ergriffen werden. Im Advamation-Protokoll ist hierzu die Verwendung eines CRCs ("SMBus PEC") vorgesehen.
Der Begriff I2C wird von uns als Oberbegriff für den eigentlichen I2C-Bus, den SMBus, das TWI (Two Wire Interface) und weitere ähnliche bzw. kompatible Busse verwendet.
- Hardware:
- 2 Datenleitungen (SDA, SCL) + Masse
- Stromversorgungsleitung +3.3V
- ggf. Interrupt-Leitung (SMBus Alert)
- Kommunikation:
- Geschwindigkeit: 100 kHz, höhere Geschwindigkeiten je nach Gerät möglich
- inkl. optionalem CRC (nach SMBus PEC-Definition)
- optional: 10-Bit-Adressierung
- Um mit der I2C-Implementierung möglichst vieler Mikrocontroller kompatibel zu sein, sollte das sogenannte "I2C-Clock-Stretching" entweder nicht oder nur direkt nach der ACK-Phase verwendet werden.
- I2C-Steckverbinder:
Es sind zwei verschiedene Steckverbinder vorgesehen:
Flachbandkabelsteckverbinder, 6-polig, RM 2.54mm: Insbesondere für interne Sensoren sind 6-polige Wannenstecker bzw. Pfostenbuchsen vorgesehen.
Kommunikations-Master besitzen hierbei einen Wannenstecker, Sensoren üblicherweise ein Kabel mit Pfostenbuchse. Da Pfostenbuchsen direkt auf Flachbandkabel aufgepresst werden können, können passende Kabel sehr einfach hergestellt werden.
D-Sub-Steckverbinder, 9-polig: Für externe Sensoren bzw. als robusterer Steckverbinder sind codierte 9-polige D-Sub-Steckverbinder vorgesehen. Der D-Sub-Steckverbinder ist verschraubbar und kann optional wasserdicht ausgeführt werden; zudem ist das Kabel abgeschirmt.
Kommunikations-Master besitzen hierbei eine D-Sub-Buchse, Sensoren üblicherweise ein Kabel mit D-Sub-Stecker.
Hierbei gibt es ebenfalls Varianten, die direkt auf Flachbandkabel aufgepresst werden können, wodurch sehr einfach Adapter zu den Flachbandkabelsteckverbindern hergestellt werden können.
Die Steckerbelegung wurde dabei so gewählt, dass das Übersprechen zwischen SDA, SCL und der Interrupt-Leitung möglichst gering ist. Die Reihenfolge der Signale ist auf beiden Steckverbindern identisch.
- I2C-Steckverbinder mit Flachbandkabel:
- Wannenstecker, 6-polig, RM 2.54mm:
I2C-Wannenstecker (Kommunikations-Master) I2C-Pfostenbuchse (Slaves / Sensoren) (Ansicht: Steckseite) (Ansicht: Steckseite) Pin Signal Beschreibung 1 GND Masse 2 SDA Datenleitung (serial data) 3 +3.3V Stromversorgung 4 SCL Taktleitung (serial clock) 5 +VBATT Batterieversorgung für spezielle Sensoren (optional) 6 INT/ALERT Interruptleitung (SMBus /ALERT, low-active, optional) - D-Sub Buchse, 9-polig (DB9):
I2C-D-Sub-Buchse (Kommunikations-Master) I2C-D-Sub-Stecker (Slaves / Sensoren) (Ansicht: Steckseite) (Ansicht: Steckseite) Pin Signal Beschreibung 5 GND Masse 9 SDA Datenleitung (serial data) 4 +3.3V Stromversorgung 8 SCL Taktleitung (serial clock) 3 +VBatt Batterieversorgung für spezielle Sensoren (optional) 7 ALERT Interruptleitung (SMBus /ALERT, low-active, optional) 2 NO PIN Stecker-Codierung 6 – nicht verwendet 1 – nicht verwendet
3 Protokoll
Die Protokolldefinition besteht aus mehreren Teilen:
- Rahmenbedingungen, die alle Geräte einhalten müssen, um an einem Bus gemeinsam zu funktionieren, ohne sich gegenseitig zu stören.
- Die Struktur des Protokolls, die den Kommunikationsablauf und das Format der Kommunikation festlegt.
- Einige häufig verwendete Konventionen, die sich als sehr nützlich erwiesen haben.
- Funktionsgruppen bzw. detailliert definierte Kommandos für die am häufigsten benötigten Funktionen, von denen jedes Gerät den jeweils passenden Teil implementieren kann.
3.1 Rahmenbedingungen
Alle Geräte an einem Bus müssen sich an folgende Rahmenbedingungen halten:
Master/Slave-Kommunikation mit genau 1 Master ("Single Master")
Geschwindigkeit:
- RS-485: 115.200 kbps
- I2C: standardmäßig 100 kHz; andere Geschwindigkeiten sind möglich, sofern alle angeschlossenen Geräte diese Geschwindigkeit unterstützen.
Adressierung:
RS-485: Jedes Slave-Gerät besitzt eine eigene Adresse (1..255); zudem wird die Adresse 0 als Broadcast-Adresse verwendet, um alle Geräte anzusprechen.
Das jeweils 1. Byte einer Anfrage enthält die Slave-Adresse; das 9. Bit ("Parity Bit") ist bei Adressen gesetzt (1), sonst gelöscht (0).
I2C: keine besonderen Anforderungen
Antwort:
Jedes Slave-Gerät antwortet nur auf Anfragen an die eigene Adresse sowie auf Anfragen an die Broadcast-Adresse (0).
Die Antwort sollte sofort, d.h. innerhalb 1 oder weniger Byte-Zeiten, erfolgen.
Sind zeitaufwändige Aktionen (z.B. Auslesen eines A/D-Wandlers, Schreiben des EEPROMS o.ä.) notwendig, so kann eine sofortige Antwort beispielsweise dadurch erreicht werden, indem (a) diese Aktionen ständig im Hintergrund ausgeführt wird, und eine Anfrage das "neueste" Ergebnis zurückliefert oder (b) mehrere Anfragen verwendet werden, von denen z.B. die erste die Aktion anstößt, und weitere den Status bzw. das Ergebnis abholen.
Es ist zudem erlaubt, dass Geräte auf bestimmte Anfragen an die eigene Adresse nicht antworten.
Auf fehlerhafte Anfragen (z.B. unvollständige Anfrage, fehlerhafter CRC, nicht unterstütztes Kommando) erfolgt keine Antwort. Der Master detektiert diese Fehler mittels Timeout.
Solange sich die Geräte an diese Rahmenbedingungen halten, können Geräte mit verschiedenen Protokollen gemischt an einen Bus angeschlossen werden. Insbesondere können bei I2C normale I2C-Sensoren (mit herstellerspezifischen Protokollen) und Geräte mit diesem Protokoll problemlos am gleichen Bus betrieben werden.
Ist für eine bestimmte Anwendung eine Abweichung von diesen Rahmenbedingungen notwendig, so ist dies möglich, sofern dies entsprechend dokumentiert und der Master (bzw. die Master-Software) entsprechend angepasst wird.
3.2 Aufbau
3.2.1 Anfrage/Request
RS-485:
-> ADR LEN CMD [DATA ...] CRC0 CRC1
I2C:
-> ADR_W LEN CMD [DATA ...] [PEC]
Bez. | Länge | Inhalt |
---|---|---|
[Bytes] | ||
ADR | 1 | RS-485: Adresse mit gesetztem 9. Bit |
ADR_W | 1 | I2C: Adresse mit gelöschtem R/W-Bit |
LEN | 1 | Anzahl der folgenden Bytes ohne CRC |
CMD | 1 | Kommando-Byte |
DATA | 0..N | Daten |
CRC | 2 | RS-485: CRC über alle gesendeten Bytes (ADR,LEN,CMD,DATA), |
PEC | 1 | I2C: SMBus PEC, optional |
Die Anzahl der Daten-Bytes beträgt bei vielen Geräten maximal 8 oder 16 Bytes.
3.2.2 Antwort/Response
RS-485:
<- LEN [DATA ...] CRC0 CRC1 (oder keine Antwort)
I2C:
<- ADR_R <- LEN [DATA ...] [PEC] (oder keine Antwort)
Bez. | Länge | Inhalt |
---|---|---|
[Bytes] | ||
ADR_R | 1 | I2C: Adresse mit gesetztem R/W-Bit |
LEN | 1 | Anzahl der folgenden Daten-Bytes, ggf. 0 |
DATA | 0..N | Daten |
CRC | 2 | RS-485: CRC über alle gesendeten Bytes (LEN,DATA), |
PEC | 1 | I2C: SMBus PEC |
Die Anzahl der Daten-Bytes beträgt bei vielen Geräten maximal 8 oder 16 Bytes.
Die Antwort soll "unmittelbar", d.h. innerhalb 1 oder weniger Byte-Zeiten erfolgen. Falls zeitintensive Aktionen (z.B. Abfrage eines Sensors, Schreiben des EEPROMs) notwendig sind, so kann dies z.B. dadurch gelöst werden, dass die Aktion in mehrere nicht-blockierende Anfragen aufgeteilt wird (z.B. "Start", "Statusabfrage", "Ergebnis lesen").
Bei I2C kann die Antwort direkt nach einem "repeated-start" auf die Anfrage folgen.
3.2.3 Daten
Die Bedeutung der "Daten" (DATA) der Kommunikation hängt vom jeweiligen Kommando sowie vom Slave ab. Folgende Konventionen werden jedoch meist eingehalten:
Die niederwertigen Bytes werden zuerst übertragen (LSB-first).
Soll von einem größeren Datenblock ein Ausschnitt gelesen werden, so wird üblicherweise ein Offset, gefolgt von der Anzahl an Daten mit übertragen.
Für das variable Lesen bzw. Schreiben von Daten ergibt sich somit häufig folgende Struktur:
Daten schreiben, N Byte:
-> ADR LEN CMD DATA0 DATA1 DATA2 ...
Daten schreiben, N Byte ab Offset:
-> ADR LEN CMD OFFSET DATA0 DATA1 ...
bzw. bei großen Daten-Blöcken:
-> ADR LEN CMD OFFSET0 OFFSET1 DATA0 DATA1 ...
Daten lesen, N Byte:
-> ADR LEN CMD N
Daten lesen, N Byte ab Offset:
-> ADR LEN CMD OFFSET N
bzw. bei großen Daten-Blöcken:
-> ADR LEN CMD OFFSET0 OFFSET1 N
Werden zu viele Daten oder Daten mit zu großem Offset geschrieben, so werden die zusätzlichen Daten-Bytes ignoriert.
Werden zu viele Daten oder Daten mit zu großem Offset gelesen, so wird für die nicht-existierenden Daten-Bytes 0xFF zurückgeliefert.
3.2.4 CRC / PEC
Um Kommunikationsfehler zu erkennen, wird bei jeder Kommunikation ein CRC verwendet. Die Details des CRC sind schnittstellenabhängig:
- RS-485: 16-Bit CRC, ähnlich CCITT [1]
Polynom: 0x1021 (x^16 + x^12 + x^5 + 1)
Initialisierungswert: 0x1D0F - I2C: 8-Bit CRC, entsprechend der SMBus-"PEC"-Definition
Polynom: 0x07 (x^8 + x^2 + x + 1)
Initialisierungswert: 0x00
Unsere Softwarebibliotheken enthalten Funktionen, um diese CRCs zu berechnen.
Beispiele RS-485:
gesendete Bytes | CRC | CRC0 | CRC1 |
---|---|---|---|
– | 0x1D0F | 0x0F | 0x1D |
0x00 | 0xCC9C | 0x9C | 0xCC |
0x00 0x01 | 0x94E1 | 0xE1 | 0x94 |
1 2 3 4 5 6 7 8 9 | 0xF777 | 0x77 | 0xF7 |
"123456789" | 0xE5CC | 0xCC | 0xE5 |
Beispiele I2C / PEC:
gesendete Bytes | CRC |
---|---|
– | 0x00 |
0x00 | 0x00 |
0x00 0x01 | 0x07 |
1 2 3 4 5 6 7 8 9 | 0x85 |
"123456789" | 0xF4 |
[1] | Der häufig verwendete Begriff "CRC-CCITT" ist leider nicht eindeutig.
Zwar verwenden alle mit "CRC-CCITT" (bzw. CRC-16-CCITT) bezeichneten
CRCs das Polynom 0x1021, es sind jedoch 3 verschiedene
Initialisierungswerte gängig: 0x0000, 0xFFFF und 0x1D0F.
Letzterer erscheint am sinnvollsten, da damit Daten der Länge 0 einen von 0x0000 / 0xFFFF verschiedenen CRC bestitzen, und damit "offene Leitungen" (die dauerhaft einen Low- oder High-Pegel liefern) nie einen "gültigen CRC" liefern können. Weitere Informationen zum CRC-CCITT: http://srecord.sourceforge.net/crc16-ccitt.html |
3.2.5 Fehlererkennung
Die Kommunikations-Fehlererkennung erfolgt per Timeout. Als Kommunikations- bzw. Protokollfehler gelten hierbei:
- Verfälschungen der Daten auf dem Weg zwischen Master und Slave.
- Kollision auf dem Bus
- Fehlerhafte Anfragen / Antworten, z.B.:
- Verwendung einer nicht-existierenden Adresse
- Verwendung einer für den Slave ungültigen Länge
- Verwendung eines im Slave nicht implementierten Kommandos
- Verwendung eines falschen CRCs
Master und Slave verhalten sich folgendermaßen:
Empfängt ein Master innerhalb dieses Timeouts keine Antwort, so ist ein Kommunikations- oder Protokollfehler aufgetreten. Der Master wird ggf. daraufhin die Anfrage wiederholen.
Empfängt ein Master eine Antwort mit falschem CRC, so verwirft er die Antwort, und sendet die Anfrage ggf. erneut.
Optional sind bestimmte Kommandos bzw. Slave-Konfigurationen möglich, so dass der Slave auch im Normalfall (ohne Fehler) nicht antwortet. In diesen Fällen sollte der Master nicht auf eine Antwort bzw. auf einen Timeout warten. Genaueres hierzu findet sich in der Dokumentation der jeweiligen Kommandos bzw. Slaves.
Stellt ein Slave einen Kommunikationsfehler fest oder empfängt er eine fehlerhafte Anfrage, so ignoriert er diese Anfrage und antwortet nicht.
3.3 Kommunikations-Ablauf
Eine Kommunikation läuft im Normalfall folgendermaßen ab:
- Master:
- Master sendet eine Anfrage (Adresse, Kommando, Daten, CRC).
- Master wartet auf eine Antwort oder einen Timeout.
- Master empfängt die Slave-Antwort oder stellt einen Fehler (per Timeout) fest. Falls Timeout: -> 1.
- Master prüft den CRC und verarbeitet die Daten.
- -> 1.
- Slave:
- Slave wartet auf den Empfang eines Adress-Bytes.
- Slave empfängt die Adresse und vergleicht sie mit der eigenen Adresse bzw. der Broadcast-Adresse. Falls eine fremde Adresse empfangen wurde: -> 1.
- Slave empfängt die Daten und prüft den CRC.
Bei falschem CRC bzw. fehlerhafter Anfrage: -> 1.
Empfängt der Slave ein weiteres Adress-Byte, so verwirft er die aktuelle Anfrage verworfen, und beginnt wieder bei Punkt 2. - Slave verarbeitet die Daten und startet ggf. weitere Aktionen.
- Slave antwortet.
- -> 1.
3.4 Software
Wir bieten Programmbibliotheken und Beispielprogramme an, die zur Kommunikation mit dem Advamation RS-485-/I2C-Protokoll verwendet werden können. Diese Software ist kostenlos, kann frei verwendet und in eigene Software integriert werden:
- AdvaBoard RPi1-Software: zur Kommunikation mit RS-485- (demnächst) und I2C-Geräten mittels Raspberry Pi.
- Linux-Software zur Kommunikation mit RS-485-Geräten mittels PC und einem entsprechenden Umsetzer von RS-232 bzw. USB auf RS-485.
- Grafische Benutzeroberflächen für einige RS-485-/I2C-Geräte (demnächst).
4 Konzepte / Konventionen
Das Advamation RS-485-/I2C-Protokoll enthält einige Konzepte bzw. Konventionen, die sich über viele Jahre als äußerst nützlich erwiesen haben, und von denen einige im Folgenden genauer erklärt werden sollen.
Bei vielen Geräten ist es sinnvoll, sich an diese Konventionen zu halten; es kann hiervon jedoch abgewichen werden, falls dies entsprechend dokumentiert wird.
4.1 Scan, Geräte-Identifikation
Jedes Gerät, das das Advamation RS-485-/I2C-Protokoll verwendet, besitzt eine Adresse (die üblicherweise im EEPROM des Geräts abgelegt ist).
Zusätzlich sollte jedes Gerät eine eindeutige 32-Bit lange Nummer (UID) besitzen. Diese Nummer kann verwendet werden, um alle angeschlossenen Geräte zu finden, den Geräten Adressen zuzuweisen bzw. Adresskonflikte aufzulösen. Dadurch ist eine automatische, kollisionsfreie Einstellung der Adressen möglich. Sollten Sie selbst Geräte mit dem Advamation RS-485-/I2C-Protokoll entwickeln, so können Sie von uns kostenfrei einen eindeutigen UID-Nummernbereich erhalten.
Zudem enthalten die meisten Geräte einige weitere Geräte-Informationen (z.B. Hersteller, Produktname/Produktnummer, Firmwareversion), die über das Protokoll abgefragt und zur Identifikation des Geräts verwendet werden können.
4.2 LED
Viele Geräte besitzen eine Geräte- bzw. Diagnose-LED, die folgenden Zwecken dienen kann:
- Power-ON-Anzeige: Anzeige, dass das Gerät Strom hat bzw. prinzipiell betriebsbereit ist.
- Kommunikations-Test: Indem der Blinkcode einer LED verändert wird, kann die Kommunikation zu einem Gerät getestet werden.
- Identifikations-Anzeige: Werden z.B. die LEDs aller Geräte ausgeschaltet, und nur die LED eines bestimmten Geräts eingeschaltet, so kann diese LED verwendet werden, um ein bestimmtes Gerät zu identifizieren bzw. um mehrere angeschlossene Geräte zu unterscheiden.
- Diagnose-Anzeige: z.B. für Fehlermeldungen/Fehlercodes usw.
Das Protokoll enthält einen Befehl, um diese LED ein-/auszuschalten bzw. blinken zu lassen.
4.3 Rohdaten
Die Slaves liefern üblicherweise immer die Rohdaten ihrer Sensoren, teils inkl. Informationen zur Umrechnung oder zur Kalibrierung. Ggf. notwendige Daten-Umrechnungen bzw. -Kalibrierungen übernimmt im Normalfall der Master.
Dies hat folgende Vorteile:
- Der Hardwareaufwand, die Rechenlast und insgesamt die Komplexität der Slaves wird reduziert.
- Die Auflösung der Daten ist klar ersichtlich, Umrechnungsfehler und Umrechnungs-Datenverluste werden vermieden.
- Der Master ist immer über die Quantisierung, Umrechnung, Kalibrierung usw. der Daten informiert. Umrechnungen und Kalibrierungen können zudem meist besser ausgeführt werden, da der Master über deutlich mehr Rechenleistung verfügt.
- Die Fehlermöglichkeiten werden reduziert und die Transparenz erhöht.
4.4 Kommandogruppen
Um die Kommunikation mit verschiedenen Geräten zu vereinheitlichen, wurden für häufig verwendete Funktionen bestimmte Kommandos und Kommandogruppen definiert.
Geräte können hierbei sowohl komplette Kommandogruppen, als auch nur einzelne Kommandos einer Gruppe unterstützen. Informationen zu den unterstützten Kommandos finden sich in der jeweiligen Geräte-Dokumentation.
4.5 Virtuelle I/Os
In vielen Geräten existieren geräteinterne I/Os bzw. verschiedene Sensordaten, auf die per Advamation-Protokoll zugegriffen werden soll.
Statt diesen I/Os bzw. Daten eigene Kommandos zuzuordnen, werden ihnen üblicherweise "virtuelle I/Os" zugeordnet:
- Internen digitalen I/Os sowie Sensoren, deren Daten aus nur 1 Bit oder mehreren unabhängigen Bits bestehen (z.B. Schalter), werden dabei virtuelle digitale I/Os zugeordnet.
- Internen analogen I/Os, sowie Sensoren, deren Daten aus mehreren zusammenhängenden Bits bzw. Bytes bestehen (z.B. Inkrementalgeber, Temperatursensoren, PWMs, RTC-Uhrzeit usw.), werden virtuelle analoge I/Os zugeordnet.
Damit kann auf alle I/Os und Sensordaten auf eine einheitliche Art und Weise und ohne sensorspezifische Kommandos zugegriffen werden.
4.6 Ereignisgesteuerte Automatisierung
Häufig ist es praktisch, wenn RS-485- bzw. I2C-Geräte einige Aktionen selbständig ausführen können, z.B. das Initialisieren aller Ausgänge nach einem Geräte-Reset, das Abschalten eines Motors bei Erreichen des Endschalters, das Einlesen eines Sensors bzw. A/D-Wandlers sobald ein Schalter gedrückt wird, oder das Starten einer Aktion zu einer bestimmten Uhrzeit bzw. in bestimmten Intervallen.
Dadurch können die Echtzeitanforderungen (=schnelle Reaktionszeiten auf ein Ereignis) an den Kommunikations-Master deutlich reduziert und viele Aufgaben vereinfacht werden.
Im Advamation RS-485-/I2C-Protokoll ist hierfür deshalb eine "ereignisgesteuerte Automatisierung" vorgesehen, die Slave-Geräte verwenden können. Diese besteht aus mehreren Teilen:
Events: Ein Gerät besitzt eine bestimmte Anzahl an konfigurierbaren "Events", z.B. 8 Digital-I/O-Events und 4 Analog-I/O-Events. Ein Event kann dabei je nach Konfiguration z.B. ein Geräte-Reset, ein sich ändernder Digital-Eingang oder ein Alarm der Echtzeituhr sein.
Für jedes Event kann dabei eingestellt werden, welchen "Handler" es aufrufen soll.
Handler: Ein Gerät besitzt eine bestimmte Anzahl an konfigurierbaren "Handlern". Für jeden Handler kann eingestellt werden, welche Aktionen dieser auslösen soll, z.B. das Setzen eines Digital-Ausgangs, das Einlesen eines Analog-Eingangs oder das Aktivieren oder Deaktivieren eines Events.
Ein Geräte-Reset löst hierbei immer Handler 0 aus, d.h. durch die Konfiguration des Handlers 0 kann der initiale I/O-Zustand des Geräts eingestellt werden.
Flags: Zu jedem Handler existiert ein Flag, das angibt, ob dieser Handler aufgerufen wurde. Diese Flags können per Software gelöscht werden.
Da das Flag 0 (=Flag des Reset-Handlers) bei jedem Software-Reset des Geräts gesetzt wird, kann dieses zur Reset-Erkennung verwendet werden, indem es gelöscht und nachfolgend überwacht wird.
5 Funktionsgruppen
Das Advamation-Protokoll definiert mehrere Funktions- bzw. Kommando-Gruppen für häufig verwendete Funktionen. Für jedes Kommando ist hierbei die Bedeutung und die Struktur der Daten-Bytes definiert.
Slaves können mehrere Kommandogruppen bzw. Teile von Kommandogruppen implementieren. Welche Kommandos bei welchem Slave existieren, sowie die genaue Bedeutung der zugehörigen Daten finden Sie in der Dokumentation der jeweiligen Geräte.
Funktions-/Kommando-Gruppen:
CMD-Bereich | Funktions-Gruppe |
---|---|
0x00..0x0F | Kommunikation |
0x10..0x17 | Geräte-Information |
0x18..0x1F | EEPROM |
0x20..0x2F | Gerät / Diagnose |
0x30..0x4F | Digital-I/O |
0x50..0x6F | Analog-I/O |
0x70..0x8F | Motor |
... | ... |
0xF0..0xFF | gerätespezifische Befehle |
5.1 Kommunikation
Diese Kommandos dienen der Adressierung und Kommunikationseinstellung, und sollten von allen Geräten unterstützt werden.
Befehl | Anfrage | Antwort | |||
---|---|---|---|---|---|
LEN | CMD | Daten | LEN | Daten | |
(reserved) | 0x00 | ||||
Adresse lesen | 1 | 0x01 | – | 1 | Adresse |
Adresse setzen | 2 | 0x02 | neue Adresse | 0 | – |
Adresse ins EEPROM sichern | 1 | 0x03 | – | 1 | ERRORCODE |
Scan | 9 | 0x04 | MIN[0..3], MAX[0..3] | 0 | – |
bei UIN/Nummer: Adresse lesen | 5 | 0x05 | UIN[0..3] | 1 | Adresse |
bei UIN/Nummer: Adresse setzen | 6 | 0x06 | UIN[0..3], neue Adresse | 0 | – |
UIN lesen | 1 | 0x07 | – | 4 | UIN[0..3] |
Kommunikations-Parameter lesen | 3 | 0x08 | Offset, N | N | Config[Offset+0..N-1] |
Kommunikations-Parameter setzen | N+2 | 0x09 | Offset, Config[Offset+0..N-1] | 0 | – |
Kommando-Status lesen | 1|N | 0x0A | [N] | 1|N | Status[0..N-1] |
(reserved) | 0x0B | ||||
(reserved) | 0x0C | ||||
(reserved) | 0x0D | ||||
(reserved) | 0x0E | ||||
(reserved) | 0x0F |
- Adresse lesen (0x01, ADDRESS_GET):
-> ADR 1 0x01 <- 1 Adresse
Liest die aktuelle Adresse des Geräts.
Dieser Befehl kann z.B. als "ping" verwendet werden, um festzustellen, ob ein Gerät mit einer bestimmten Adresse existiert bzw. ansprechbar ist. Ist insgesamt nur 1 Gerät am Bus angeschlossen, so kann dieses Kommando zusammen mit der Broadcast-Adresse verwendet werden, um die Adresse des Geräts zu ermitteln.
- Adresse setzen (0x02, ADDRESS_SET):
-> ADR 2 0x02 neue_Adresse <- 0
Ändert die aktuelle Adresse des Geräts. Danach ist das Gerät bis zum Neustart oder der nächsten Änderung unter der neuen Adresse ansprechbar.
Adressbereiche:
- RS485: 0x00 - 0xFF (0x00=Broadcast)
- I2C: 0x00 - 0x7F (0x00=Broadcast)
Bei der Adressänderung via I2C ist darauf zu beachten, dass als Adresse für die Antwort (ADR_R) bereits die neue Adresse verwendet werden sollte. Andernfalls erhält man keine Antwort des Slaves.
- Adresse ins EEPROM sichern (0x03, ADDRESS_STORE):
-> ADR 1 0x03 <- 1 ERRORCODE
Speichert die aktuelle Adresse im EEPROM, so dass sie auch beim Neustart erhalten bleibt. Ob die Speicherung erfolgreich war, muss durch Abfrage des EEPROM-Statuses geprüft werden (siehe EEPROM).
ERRORCODE: 0x00 = Schreibvorgang gestartet, 0xF1 = BUSY
- Scan (0x04, SCAN):
-> ADR 9 0x04 MIN0 MIN1 MIN2 MIN3 MAX0 MAX1 MAX2 MAX3 <- 0
Jedes Gerät besitzt üblicherweise eine eindeutige 32-Bit-Nummer ("UIN"), die verwendet werden kann, um z.B. Adresskonflikte aufzulösen oder Geräte eindeutig zu identifizieren.
Der "Scan" sucht Geräte in einem UIN-Nummernbereich. Alle Geräte innerhalb des angegebenen Nummernbereichs (d.h. falls NO_MIN <= UIN <= NO_MAX) antworten. Dies ermöglicht es, festzustellen, ob Geräte in einem bestimmten Nummernbereich angeschlossen sind, und somit eine effiziente Suche nach allen angeschlossen Geräten (unabhängig von ihrer aktuellen Adresse).
Als Adresse wird dabei üblicherweise die Broadcast-Adresse verwendet.
Daten:
MIN0 MIN1 MIN2 MIN3 MAX0 MAX1 MAX2 MAX3 MIN: untere Bereichsgrenze (32 Bit) MAX: oberer Bereichsgrenze (32 Bit)
- bei UIN-Nummer: Adresse lesen (0x05, UID_ADDRESS_GET):
-> 0x00 5 0x05 UIN0 UIN1 UIN2 UIN3 <- 1 Adresse
Gibt die aktuelle Adresse des Geräts zurück, falls die UIN-Nummer übereinstimmt.
- bei UIN-Nummer: Adresse setzen (0x06, UID_ADDRESS_SET):
-> 0x00 6 0x06 UIN0 UIN1 UIN2 UIN3 neue_Adresse <- 0
Ändert die aktuelle Adresse des Geräts, falls die UIN-Nummer übereinstimmt. Dies ermöglicht es, Adresskonflikte aufzulösen.
Daten:
UIN0 UIN1 UIN2 UIN3 neue_Adresse UIN: eindeutige Gerätenummer, 32 bit
- UIN lesen (0x07, UID):
-> ADR 1 0x07 <- 4 UIN0 UIN1 UIN2 UIN3
Liest die UIN-Nummer des Geräts.
- Kommunikations-Parameter lesen (0x08, COMMPARAM_READ):
-> ADR 3 Offset N <- N Config[Offset + 0..N-1]
Liest die aktuellen Kommunikations-Parameter aus. Die Bedeutung der Parameter ist geräteabhängig und kann z.B. die Kommunikationsgeschwindigkeit, verschiedene Kommunikations-Modifikationen, eine Verschlüsselung o.ä. beinhalten.
- Kommunikations-Parameter setzen (0x09, COMMPARAM_WRITE):
-> ADR N+2 Offset Config[Offset + 0..N-1] <- 0
Schreibt neue Kommunikations-Parameter. Die Bedeutung der Parameter ist geräteabhängig.
Eine persistente Speicherung der Parameter im EEPROM ist per Kommando 0x1D (siehe EEPROM) möglich.
- Kommando-Status lesen (0x0A, CMDSTATUS)
-> ADR 1 0x0A <- 1 STATUS0 oder -> ADR 2 0x0A N <- N STATUS[0..N-1]
Liest den Kommando-Status.
Im Normalfall lesen bzw. schreiben Kommandos lediglich einige Register des Geräts oder starten eine Aktion; sie warten aber nicht, bis die Aktion beendet ist bzw. bis die geänderten Registerwerte (z.B. Digital-Ausgangs-Werte) wirklich aktiv werden.
Mit diesem Kommando kann deshalb abgefragt werden, ob die zu den Kommandos gehörenden Aktionen bereits erledigt wurden bzw. alle geänderten Registerwerte nun aktiv sind. Da die Kommandos in den Slave-Geräten üblicherweise sehr schnell abgearbeitet werden, ist dies v.a. dann sinnvoll, wenn kurz hintereinander aufeinander aufbauende Kommandos an das Gerät geschickt werden (z.B. Setzen und nachfolgendes Zurücklesen eines Ausgangs, oder Konfigurieren und nachfolgendes Lesen eines Eingangs).
Status Bedeutung 0x00 alle Kommandos abgearbeitet ("idle") andere Kommandos werden derzeit verarbeitet Die einzelnen Bits des Status-Bytes geben an, aus welcher Kommandogruppe derzeit noch Kommandos verarbeitet werden:
Bit Kommando-Gruppe mögliche Kommandos 0 Kommunikation 0x03, 0x09 1 Geräte-Information – 2 EEPROM 0x1B, 0x1C, 0x1D 3 Gerät / Diagnose 0x21, 0x2B 4 Digital-I/O 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x41, 0x43 5 Analog-I/O 0x5A, 0x5B, 0x61, 0x63 6 Motor 7 (reserved) Hinweis: Dieses Kommando wird nur von neueren Geräten (Geräte- bzw. Firmwaredatum ab 20140217) unterstützt.
5.2 Geräte-Information
Befehl | Anfrage | Antwort | |||
---|---|---|---|---|---|
LEN | CMD | Daten | LEN | Daten | |
Seriennummer lesen | 1 | 0x10 | – | 5 | Seriennummer[0..4] |
Identifikation lesen | 3 | 0x11 | Offset, N | N | Daten[Offset+0..N-1] |
Geräteinformationen lesen | 3 | 0x12 | Offset, N | N | Daten[Offset+0..N-1] |
(reserved) | 0x13 | ||||
(reserved) | 0x14 | ||||
(reserved) | 0x15 | ||||
(reserved) | 0x16 | ||||
(reserved) | 0x17 |
- Seriennummer lesen (0x10, SERNO):
-> ADR 1 0x10 <- 5 SERNO0 SERNO1 SERNO2 SERNO3 SERNO4
Gibt die Seriennummer des Geräts in BCD zurück.
- Identifikation lesen (0x11, DEVID):
-> ADR 3 0x11 Offset N <- N Daten[Offset + 0..N-1]
Liest einige Standardinformationen des Geräts:
[VENDOR];PRODUCT/HARDWARE;SOFTWARE/FIRMWARE;[...]
Feld Bedeutung VENDOR Hersteller-Name in ASCII (optional) PRODUCT/HARDWARE Produkt-/Hardware-Nummer oder -Kurzname in ASCII SOFTWARE/FIRMWARE Software-/Firmware-Version in ASCII weitere Felder (reserved) Beispiel:
Advamation;1160-f353;20140213;
- Geräteinformation lesen (0x12, DEVINFO):
-> ADR 3 0x12 Offset N <- Daten[Offset + 0..N-1]
Liest Geräteinformationen als Name-/Wert-Paare aus. Die Paare sind durch ;, Name und Wert durch : getrennt:
KEY:VALUE;KEY2:VALUE2;...
Beispiel:
VENDOR:Advamation;PRODUCT:AdvaBoard RPi1;REVISION:1;PART:F353;FIRMWARE:20140213;
5.3 EEPROM
Jedes Gerät enthält normalerweise ein EEPROM, in dem alle Konfigurationswerte (Geräte-Adresse, Geräte-Einstellungen, usw.) abgespeichert sind.
Befehl | Anfrage | Antwort | |||
---|---|---|---|---|---|
LEN | CMD | Daten | LEN | Daten | |
EEPROM-Status lesen | 1 | 0x18 | – | 1 | EEPROM-Status |
EEPROM-Größe lesen | 1 | 0x19 | – | 2 | EEPROM-Größe[0..1] |
EEPROM lesen | 4 | 0x1A | Offset[0..1], N | N+1 | ERRORCODE, Daten[Offset+0..N-1] |
EEPROM schreiben | N+3 | 0x1B | Offset[0..1], Daten[...] | 1 | ERRORCODE |
Einstellungen aus EEPROM laden | 2 | 0x1C | SELECT | 1 | ERRORCODE |
Einstellungen ins EEPROM sichern | 2 | 0x1D | SELECT | 1 | ERRORCODE |
(reserved) | 0x1E | ||||
(reserved) | 0x1F |
Alle Befehle mit EEPROM-Zugriff beinhalten einen ERRORCODE in der Antwort, der immer geprüft werden sollte.
ERRORCODE Bedeutung 0x00 OK / kein Fehler 0x01 / 0xF1 Fehler: EEPROM derzeit beschäftigt
- EEPROM-Status lesen (0x18, EEPROM_STATUS):
-> ADR 1 0x18 <- 1 EEPROM_Status
Gibt den momentanen EEPROM-Status bzw. das Ergebnis der letzten EEPROM-Aktion zurück. Nach jedem EEPROM-Schreiben sollte dieser Status geprüft werden.
Status:
Bit Name Bedeutung 0 BUSY EEPROM derzeit noch beschäftigt 1 ERROR Nur gültig falls BUSY=0.0: kein Fehler1: Fehler7 WRITE_START Nur gültig falls BUSY=0.1: anstehende EEPROM-Schreibanfrage
- EEPROM-Größe lesen (0x19, EEPROM_SIZE):
-> ADR 1 0x19 <- 2 SIZE0 SIZE1
Gibt die EEPROM-Größe in Bytes zurück.
- EEPROM lesen (0x1A, EEPROM_READ):
-> ADR 4 0x1A Offset0 Offset1 N <- N+1 ERRORCODE Daten[Offset + 0..N-1]
Liest Daten aus dem EEPROM und gibt diese zurück.
ERRORCODE: 0x00 = OK, 0xF1 = BUSY
- EEPROM schreiben (0x1B, EEPROM_WRITE):
-> ADR N+3 0x1B Offset0 Offset1 Daten[Offset + 0..N-1] <- 1 ERRORCODE
Schreibt Daten ins EEPROM. Es ist jedoch zu beachten, dass dieser Befehl den Schreibvorgang nur startet, und nicht wartet, bis er beendet ist. Ob die Speicherung abgeschlossen ist und erfolgreich war, muss deshalb durch Abfrage des EEPROM-Statusbytes (BUSY, ERROR) geprüft werden.
Warnung: Das Beschreiben des EEPROMS kann evtl. die komplette Konfiguration des Geräts verändern; dieser Befehl sollte deshalb nur mit entsprechender Vorsicht verwendet werden!
ERRORCODE: 0x00 = OK, 0xF1 = BUSY
- Einstellungen aus EEPROM laden (0x1C, EEPROM_CFG_LOAD):
-> ADR 2 0x1C SELECT <- 1 ERRORCODE
Lädt bestimmte Einstellungen aus dem EEPROM. SELECT gibt hierbei an, welcher Teil der Einstellungen geladen werden soll:
SELECT geladene Einstellungen 0x00 alle Einstellungen 0x01 Kommunikations-Parameter (ohne Adresse) 0x02 allgemeine Geräteeinstellungen 0x03 Digital-I/O-Einstellungen 0x04 Analog-I/O-Einstellungen Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob das Laden der Einstellungen erledigt ist und diese nun aktiv sind.
- Einstellungen ins EEPROM sichern (0x1D, EEPROM_CFG_STORE):
-> ADR 2 0x1D SELECT <- ERRORCODE
Speichert bestimmte Einstellungen ins EEPROM. SELECT gibt hierbei an, welcher Teil der Einstellungen gespeichert werden soll:
SELECT gespeicherte Einstellungen 0x00 alle Einstellungen 0x01 Kommunikations-Parameter (ohne Adresse) 0x02 allgemeine Geräteeinstellungen 0x03 Digital-I/O-Einstellungen 0x04 Analog-I/O-Einstellungen Ob die Speicherung abgeschlossen ist und erfolgreich war, muss durch Abfrage des EEPROM-Statusbytes (BUSY, ERROR) geprüft werden.
5.4 Gerät / Diagnose
Befehl | Anfrage | Antwort | |||
---|---|---|---|---|---|
LEN | CMD | Daten | LEN | Daten | |
Echo | N+1 | 0x20 | N*Echo-Byte | N | N*Echo-Byte |
LED | 2 | 0x21 | BLINKCODE | 0 | – |
(reserved) | 0x22 | ||||
(reserved) | 0x23 | ||||
(reserved) | 0x24 | ||||
(reserved) | 0x25 | ||||
(reserved) | 0x26 | ||||
(reserved) | 0x27 | ||||
Reset | 1 | 0x28 | – | – | |
Handler-Flags lesen | 1-2 | 0x29 | [N] | 1|N | FLAGS |
Handler-Flags löschen | N+1 | 0x2A | FLAGS[0..N-1] | 0 | – |
Handler auslösen | 2 | 0x2B | Handler-Nummer | 1 | Fehlercode |
(reserved) | 0x2C | ||||
(reserved) | 0x2D | ||||
(reserved) | 0x2E | ||||
(reserved) | 0x2F |
- Echo (0x20, ECHO):
-> ADR N+1 0x20 Daten[0..N-1] <- N Daten[0..N-1]
Sendet die empfangenden Daten-Bytes zurück.
- LED (0x21, LED):
-> ADR 2 0x21 BLINKCODE <- 0
Setzt den Blinkcode der Geräte- bzw. Diagnose-LED (siehe LED).
Blinkcodes:
Wert LED 0x00 aus 0xff an 0x01 blinkend, ca. 0.32s / 3-mal pro Sekunde 0x02 blinkend, ca. 0.64s / 1.5-mal pro Sekunde 0x04 blinkend, ca. 1.28s / 0.8-mal pro Sekunde 0x08 blinkend, ca. 2.56s / 0.4-mal pro Sekunde ... Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt, und der neue Blinkcode somit nun aktiv ist.
- Reset (0x28, RESET):
-> ADR 1 0x28 <- --
Löst einen Software-Reset aus. Es erfolgt keine Antwort.
- Handler-Flags lesen (0x29, HANDLER_FLAGS):
-> ADR 1 0x29 <- 1 FLAGS0 -> ADR 2 0x29 N <- N FLAGS[0..N-1]
Liest aus, welche Handler ausgelöst wurden. Die Anzahl der unterstützten Handler ist geräteabhängig.
Siehe auch: Ereignisgesteuerte Automatisierung
Byte.Bit Bedeutung 0.0 Flag für Handler 0 (=Reset-Handler) 0.1 Flag für Handler 1 0.2 Flag für Handler 2 0.3 Flag für Handler 3 0.4 Flag für Handler 4 0.5 Flag für Handler 5 0.6 Flag für Handler 6 0.6 Flag für Handler 7 N.7..0 Flags für Handler 8..15 (optional) Da das Flag 0.0 bei jedem Software-Reset des Geräts gesetzt wird, kann dieses zur Reset-Erkennung verwendet werden, indem es gelöscht und nachfolgend überwacht wird.
- Handler-Flags löschen (0x2A, HANDLER_CLEAR):
-> ADR N+1 0x2A FLAGS[0..N-1] <- 0
Löscht bestimmte Handler-Flags.
Byte.Bit Bedeutung 0.0 Handler-Flag 0 löschen 0.1 Handler-Flag 1 löschen ... usw. - Handler auslösen (0x2B, HANDLER_TRIGGER):
-> ADR 2 0x2B Handler_Nummer <- 1 Fehlercode
Löst einen Handler manuell aus. Die Anzahl der unterstützten Handler ist geräteabhängig.
Siehe auch: Ereignisgesteuerte Automatisierung
Wurde bereits vorher ein Handler manuell ausgelöst, und wurde dieser noch nicht abgearbeitet, so wird der Handler nicht ausgelöst und ein Wert ungleich 0 zurückgegeben. Andernfalls wird 0x00 zurückgegeben.
Handler Bedeutung Nr. Name 0 Reset Reset/Einschalten 1 z.B. "Aus" nutzerdefiniert, z.B. "Aus" 2 z.B. "Ein" nutzerdefiniert, z.B. "Ein"/"Start" 3 z.B. "Stop" nutzerdefiniert, z.B. "Stop" 4 ... optional 5 ... optional 6 ... optional 7 ... optional 8 ... optional 9 ... optional 10 ... optional 11 ... optional 12 ... optional 13 ... optional 14 ... optional 15 ... optional Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob die Ausführung des Handlers bereits erledigt ist.
5.5 Digital-I/O
Liest, schreibt und konfiguriert Digital-I/Os.
Als "Digital-I/Os" gelten hierbei nicht nur echte I/Os des Geräts, sondern auch geräteinterne I/Os und Sensoren, die Digital-I/Os ähneln (siehe Virtuelle I/Os). Allen Ein-/Ausgängen, geräteinternen I/Os, Rohwerten von Sensoren (die Digital-I/Os ähneln) usw., auf die von Außen zugegriffen werden soll, sollte deshalb ein Digital-I/O-Bit zugeordnet werden.
Werden nichtexistierende Eingangs-Bytes gelesen, so liefern diese 0xFF zurück; Schreibversuche auf nichtexistierende Ausgangs-Bytes werden (ohne Fehlermeldung) ignoriert.
Befehl | Anfrage | Antwort | |||
---|---|---|---|---|---|
LEN | CMD | Daten | LEN | Daten | |
Eingang lesen, 1 Byte | 1 | 0x30 | – | 1 | Input[0] |
Eingang lesen, 2 Bytes | 1 | 0x31 | – | 2 | Input[0..1] |
Eingang lesen, 4 Bytes | 1 | 0x32 | – | 4 | Input[0..3] |
Eingang lesen, 8 Bytes | 1 | 0x33 | – | 8 | Input[0..7] |
Eingang lesen, Offset + N | 3 | 0x34 | Offset, N | N | Input[Offset+0..N-1] |
Ausgang zurücklesen, 1 Byte | 1 | 0x35 | – | 1 | Output[0] |
Ausgang zurcklesen, 2 Bytes | 1 | 0x36 | – | 2 | Output[0..1] |
Ausgang zurücklesen, 4 Bytes | 1 | 0x37 | – | 4 | Output[0..3] |
Ausgang zurücklesen, 8 Bytes | 1 | 0x38 | – | 8 | Output[0..7] |
Ausgang zurücklesen, Offset + N | 3 | 0x39 | Offset, N | N | Output[Offset+0..N-1] |
Ausgang schreiben | N+1 | 0x3A | Output[0..N] | 0 | – |
Ausgang schreiben, Offset + N | N+2 | 0x3B | Offset, Output[Offset+0..N-1] | 0 | – |
Ausgangs-Bit setzen | 2 | 0x3C | Bytenr. + Bitnr. | 0 | – |
Ausgangs-Bit löschen | 2 | 0x3D | Bytenr. + Bitnr. | 0 | – |
I/O Update | 2 | 0x3E | Output[0] | 2 | Input[0..1] |
(reserved) | (0x3F) | ||||
Konfiguration lesen | 3 | 0x40 | Offset, N | N | Config[Offset+0..N-1] |
Konfiguration schreiben | N+2 | 0x41 | Offset, Config[Offset+0..N-1] | 0 | – |
Status lesen | 3 | 0x42 | Offset, N | N | Status[Offset+0..N-1] |
Control schreiben | N+2 | 0x43 | Offset, Control[Offset+0..N-1] | 0 | – |
Handler: Control-Änderung lesen | 4 | 0x44 | Handler, Offset, N | N | Control[Offset+0..N-1] |
Handler: Control-Änderung schreiben | N+3 | 0x45 | Handler, Offset,Control[Offset+0..N-1] | 0 | – |
Handler: Ausgangs-nderung lesen | 4 | 0x46 | Handler, Offset,N | N | MaskOut[Offset+0..N-1] |
Handler: Ausgangs-Änderung schreiben | N+3 | 0x47 | Handler, Offset,MaskOut[Offset+0..N-1] | 0 | – |
Event: Konfiguration lesen | 4 | 0x48 | Event, Offset,N | N | CFG[Offset+0..N-1] |
Event: Konfiguration schreiben | N+3 | 0x49 | Event, Offset,CFG[Offset+0..N-1] | 0 | – |
(reserved) | 0x4A | ||||
(reserved) | 0x4B | ||||
(reserved) | 0x4C | ||||
(reserved) | 0x4D | ||||
(reserved) | 0x4E | ||||
(reserved) | 0x4F |
- Eingang lesen, 1 Byte (0x30, INPUT_READ1):
-> ADR 1 0x30 <- 1 INPUT0
Liest das erste Digital-Eingangs-Byte.
- Eingang lesen, 2 Bytes (0x31, INPUT_READ2):
-> ADR 1 0x31 <- 2 INPUT0 INPUT1
Liest die zwei ersten Digital-Eingangs-Bytes.
- Eingang lesen, 4 Bytes (0x32, INPUT_READ4):
-> ADR 1 0x32 <- 4 INPUT0 INPUT1 INPUT2 INPUT3
Liest die vier ersten Digital-Eingangs-Bytes.
- Eingang lesen, 8 Bytes (0x33, INPUT_READ8):
-> ADR 1 0x33 <- 8 INPUT0 INPUT1 INPUT2 INPUT3 INPUT4 INPUT5 INPUT6 INPUT7
Liest die acht ersten Digital-Eingangs-Bytes.
- Eingang lesen, Offset + N (0x34, INPUT_READ):
-> ADR 3 0x34 Offset N <- N Input[Offset + 0..N-1]
Liest N Digital-Eingangs-Bytes ab einem Offset.
- Ausgang zurücklesen, 1 Byte (0x35, OUTPUT_READ1):
-> ADR 1 0x35 <- 1 OUTPUT0
Liest das erste Digital-Ausgangs-Byte zurück.
- Ausgang zurücklesen, 2 Bytes (0x36, OUTPUT_READ2):
-> ADR 1 0x36 <- 2 OUTPUT0 OUTPUT1
Liest die zwei ersten Digital-Ausgangs-Bytes zurück.
- Ausgang zurücklesen, 4 Bytes (0x37, OUTPUT_READ4):
-> ADR 1 0x37 <- 4 OUTPUT0 OUTPUT1 OUTPUT2 OUTPUT3
Liest die vier ersten Digital-Ausgangs-Bytes zurück.
- Ausgang zurücklesen, 8 Bytes (0x38, OUTPUT_READ8):
-> ADR 1 0x38 <- 8 OUTPUT0 OUTPUT1 OUTPUT2 OUTPUT3 OUTPUT4 OUTPUT5 OUTPUT6 OUTPUT7
Liest die acht ersten Digital-Ausgangs-Bytes zurück.
- Ausgang zurücklesen, Offset + N (0x39, OUTPUT_READ):
-> ADR 3 0x39 Offset N <-N Output[Offset + 0..N-1]
Liest N Digital-Ausgangs-Bytes ab einem Offset zurück.
- Ausgang schreiben (0x3A, OUTPUT_WRITEN):
-> ADR N+1 0x3A Output[Offset + 0..N-1] <- 0
Schreibt die N ersten Digital-Ausgangs-Bytes.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Ausgangs-Pins bereits entsprechend gesetzt wurden.
- Ausgang schreiben, Offset + N (0x3B, OUTPUT_WRITE):
-> ADR N+2 0x3B Offset, Output[Offset + 0..N-1] <- 0
Schreibt N Digital-Ausgangs-Bytes ab einem Offset.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Ausgangs-Pins bereits entsprechend gesetzt wurden.
- Ausgangs-Bit setzen (0x3C, OUTBIT_SET):
-> ADR 2 0x3C ByteBitNr <- 0
Setzt ein Ausgangs-Bit.
Parameter:
Bit Inhalt 7..4 Byte-Nummer, 0..15 3..0 Bit-Nummer, 0..7 z.B. 0x23 für das 3. Bit des 2. Bytes
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit der Ausgang-Pin bereits entsprechend gesetzt wurde.
- Ausgangs-Bit löschen (0x3D, OUTBIT_CLR):
-> ADR 2 0x3D ByteBitNr <- 0
Löscht ein Ausgang-Bit.
Parameter:
Bit Inhalt 7..4 Byte-Nummer, 0..15 3..0 Bit-Nummer, 0..7 z.B. 0x23 für das 3. Bit des 2. Bytes
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit der Ausgang-Pin bereits entsprechend gelöscht wurde.
- I/O Update (0x3E, IO_UPDATE):
-> ADR 2 0x3E OUTPUT0 <- 2 INPUT0 INPUT1
Schreibt das erste Ausgangs-Byte und liest die ersten beiden Ausgang-Bytes zurück. Dieses Kommando ist dafür gedacht, bei einfacheren I/Os die Ein- und Ausgänge schnell und mit nur 1 Kommunikation zu aktualisieren.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Ausgangs-Pins bereits entsprechend gesetzt wurden.
- Konfiguration lesen (0x40, IO_CFG_READ):
-> ADR 3 0x40 Offset N <- N Config[Offset + 0..N-1]
Liest die Digital-I/O-Konfiguration.
Die Bedeutung der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
- Konfiguration schreiben (0x41, IO_CFG_WRITE):
-> ADR N+2 0x41 Offset Config[Offset + 0..N-1] <- 0
Schreibt die Digital-I/O-Konfiguration.
Dies kann z.B. verwendet werden, um bestimmte I/Os als Eingang, Open-Collector-Ausgang oder Push-Pull-Ausgang zu konfigurieren, oder den I/Os bestimmte Funktionen zuzuweisen.
Die Bedeutung der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt wurde und somit die neue Konfiguration bereits aktiv ist.
- Status lesen (0x42, IO_STATUS):
-> ADR 3 0x42 Offset N <- N Status[Offset + 0..N-1]
Liest den Digital-I/O-Status.
Dies kann verwendet werden, um den Status bestimmter I/O-Funktionen abzufragen.
Siehe auch: Kommando "Control schreiben (0x43)"
Die Bedeutung der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
- Control schreiben (0x43, IO_CONTROL):
-> ADR N+2 0x43 Offset Control[Offset + 0..N-1] <- 0
Aktiviert bzw. deaktiviert Digital-I/O-Funktionen.
Dieses Kommando ist dazu gedacht, bestimmte Digital-I/O-Funktionen ein- bzw. auszuschalten (z.B. Digital-I/O-Events oder gerätespezifische Funktionen wie z.B. einen Keyboard-Scan). Jede Funktion besitzt hierbei üblicherweise 2 Bits:
- 1.Bit: Deaktiviert die entsprechende Funktion.
- 2.Bit: Aktiviert die entsprechende Funktion.
Ob eine bestimmte Funktion derzeit aktiv ist, kann üblicherweise über den Status (0x42) abgefragt werden.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Digital-I/O-Funktionen bereits entsprechend (de)aktiviert wurden.
Werden gleichzeitig mehrere Digital-I/O-Funktionen aktiviert bzw. deaktiviert, so hängt die Reihenfolge von der Software des Geräts ab. Werden kurz hintereinander mehrere "Control"-Kommandos an ein Gerät gesendet, so kann die Abarbeitungs-Reihenfolge von der Kommando-Reihenfolge abweichen. Soll eine bestimmte Reihenfolge sichergestellt werden, so muss vor dem Absenden weiterer Control-Kommandos durch eine Abfrage des Statuses (0x42 oder 0x0A) sichergestellt werden, dass die vorherigen Control-Kommandos bereits abgearbeitet wurden.
Die Bedeutung der einzelnen Bits der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
- Handler: Control-Änderung lesen (0x44, IO_HANDLER_CONTROL_READ):
-> ADR 4 0x44 Handlernummer Offset N <- N Control[Offset + 0..N-1]
Liest aus, welche Control-Bits gesetzt werden, falls ein bestimmter Handler aufgerufen wird.
Siehe auch: Kommando "Handler: Control schreiben (0x45)", Ereignisgesteuerte Automatisierung
- Handler: Control-Änderung schreiben (0x45, IO_HANDLER_CONTROL_WRITE):
-> ADR N+3 0x45 Handlernummer Offset Control[Offset + 0..N-1] <- 0
Legt fest, welche Control-Bits gesetzt werden sollen, falls ein bestimmter Handler aufgerufen wird. Der Handler 0 definiert hierbei den Zustand nach einem Geräte-Reset.
Parameter:
- Handler: Handler-Nummer
- Offset: Control-Byte-Offset
- Control: Control-Bytes
Siehe auch: Ereignisgesteuerte Automatisierung, Kommando "Control schreiben (0x43)"
- Handler: Ausgangs-Änderung lesen (0x46, IO_HANDLER_OUTPUT_READ):
-> ADR 4 0x46 Handlernummer Offset N <- N MaskOut[Offset + 0..N-1]
Liest aus, welche Ausgänge verändert werden, falls ein bestimmter Handler aufgerufen wird.
Siehe auch: Kommando "Handler: Ausgang schreiben (0x45)", Ereignisgesteuerte Automatisierung
- Handler: Ausgangs-Änderung schreiben (0x47, IO_HANDLER_OUTPUT_WRITE):
-> ADR N+3 0x47 Handlernummer Offset MaskOut[Offset + 0..N-1] <- 0
Legt fest, welche Ausgänge verändert werden sollen, falls ein bestimmter Handler aufgerufen wird. Der Handler 0 definiert hierbei den Zustand nach einem Geräte-Reset.
Parameter:
Handler: Handler-Nummer
Offset: "MaskOut"-Offset
MaskOut: Bitmasken und Ausgangswerte je Ausgangs-Byte:
BITMASK0 OUTPUT0 BITMASK1 OUTPUT1 ...
Ist ein Bit in der Bitmaske gesetzt, so wird das Ausgangs-Bit auf den Wert des entsprechenden OUTPUT-Bits gesetzt, d.h.:
- BITMASK-Bit = 0: Ausgangs-Bit wird nicht geändert
- BITMASK-Bit = 1, OUTPUT-Bit = 0: Ausgangs-Bit wird gelöscht
- BITMASK-Bit = 1, OUTPUT-Bit = 1: Ausgangs-Bit wird gesetzt
Siehe auch: Ereignisgesteuerte Automatisierung
- Event: Konfiguration lesen (0x48, IO_EVENT_READ):
-> ADR 4 0x48 Eventnummer Offset N <- N CFG[Offset + 0..N-1]
Liest eine Digital-I/O-Event-Konfiguration aus.
Siehe auch: Kommando "Event: Konfiguration schreiben (0x49)", Ereignisgesteuerte Automatisierung
- Event: Konfiguration schreiben (0x49, IO_EVENT_WRITE):
-> ADR N+3 0x49 Eventnummer Offset CFG[Offset + 0..N-1] <- 0
Konfiguriert ein Digital-I/O-Event.
Parameter:
Event: Digital-I/O-Event-Nummer (Die Anzahl der Digital-I/O-Events ist geräteabhängig.)
Offset: CFG-Offset
CFG: Event-Konfiguration: Handler-Nummer und Eingangs-Werte je Eingangs-Byte:
HANDLER BITMASK0 INPUT0 BITMASK1 INPUT1 ...
HANDLER gibt die Nummer des auszulösenden Handlers an.
Die Bit-Masken und INPUT-Bytes geben an, wann das Event ausgelöst werden soll. Es wird dann ausgelöst, wenn alle Eingangs-Bits gleichzeitig den konfigurierten Werten entsprechen:
- BITMASK-Bit = 0: Eingangs-Bit wird ignoriert
- BITMASK-Bit = 1, INPUT-Bit = 0: Event wird ausgelöst, wenn das Eingangs-Bit = 0 ist
- BITMASK-Bit = 1, INPUT-Bit = 1: Event wird ausgelöst, wenn das Eingangs-Bit = 1 ist
Siehe auch: Ereignisgesteuerte Automatisierung
5.6 Analog-I/O
Liest, schreibt und konfiguriert Analog-I/Os.
Als "Analog-I/Os" gelten hierbei nicht nur echte I/Os des Geräts, sondern auch PWMs, geräteinterne I/Os und Sensoren bzw. Sensor-Werte die mehr als 1 Bit umfassen. Allen analogen Ein-/Ausgängen, geräteinternen I/Os, Rohwerten von Sensoren (z.B. Inkremental- oder Absolutgeber) usw., auf die von Außen zugegriffen werden soll, sollten deshalb Analog-I/O-Bytes zugeordnet werden.
Werden nichtexistierende Eingangs-Bytes gelesen, so liefern diese 0xFF zurück. Schreibversuche auf nichtexistierende Ausgangs-Bytes werden (ohne Fehlermeldung) ignoriert.
Befehl | Anfrage | Antwort | |||
---|---|---|---|---|---|
LEN | CMD | Daten | LEN | Daten | |
Eingang lesen, 1 Byte | 1 | 0x50 | – | 1 | Analog_In[0] |
Eingang lesen, 2 Bytes | 1 | 0x51 | – | 2 | Analog_In[0..1] |
Eingang lesen, 4 Bytes | 1 | 0x52 | – | 4 | Analog_In[0..3] |
Eingang lesen, 8 Bytes | 1 | 0x53 | – | 8 | Analog_In[0..7] |
Eingang lesen, Offset + N | 3 | 0x54 | Offset, N | N | Analog_In[Offset+0..N-1] |
Ausgang (zurück)lesen, 1 Byte | 1 | 0x55 | – | 1 | Analog_Out[0] |
Ausgang (zurück)lesen, 2 Bytes | 1 | 0x56 | – | 2 | Analog_Out[0..1] |
Ausgang (zurück)lesen, 4 Bytes | 1 | 0x57 | – | 4 | Analog_Out[0..3] |
Ausgang (zurück)lesen, 8 Bytes | 1 | 0x58 | – | 8 | Analog_Out[0..7] |
Ausgang (zurück)lesen, Offset+N | 3 | 0x59 | Offset, N | N | Analog_Out[Offset+0..N-1] |
Ausgang schreiben | N+1 | 0x5A | Analog_Out[0..N-1] | 0 | – |
Ausgang schreiben, Offset + N | N+2 | 0x5B | Offset, Analog_Out[Offset+0..N-1] | 0 | – |
(reserved) | (0x5C) | ||||
(reserved) | (0x5D) | ||||
(reserved) | (0x5E) | ||||
(reserved) | (0x5F) | ||||
Konfiguration lesen | 3 | 0x60 | Offset, N | N | Config[Offset+0..N-1] |
Konfiguration schreiben | N+2 | 0x61 | Offset, Config[Offset+0..N-1] | 0 | – |
Status lesen | 3 | 0x62 | Offset, N | N | Status[Offset+0..N-1] |
Control schreiben | N+2 | 0x63 | Offset, Control[Offset+0..N-1] | 0 | – |
Handler: Control-Änderung lesen | 4 | 0x64 | Handler, Offset, N | N | Control[Offset+0..N-1] |
Handler: Control-Änderung schreiben | N+3 | 0x65 | Handler, Offset,Control[Offset+0..N-1] | 0 | – |
Handler: Ausgangs-Änderung lesen | 4 | 0x66 | Handler, Offset,N | N | MaskOut[Offset+0..N-1] |
Handler: Ausgangs-Änderung schreiben | N+3 | 0x67 | Handler, Offset,MaskOut[Offset+0..N-1] | 0 | – |
Event: Konfiguration lesen | 4 | 0x68 | Event, Offset,N | N | CFG[Offset+0..N-1] |
Event: Konfiguration schreiben | N+3 | 0x69 | Event, Offset,CFG[Offset+0..N-1] | 0 | – |
(reserved) | 0x6A | ||||
(reserved) | 0x6B | ||||
(reserved) | 0x6C | ||||
(reserved) | 0x6D | ||||
(reserved) | 0x6E | ||||
(reserved) | 0x6F |
- Eingang lesen, 1 Byte (0x50, ANALOGIN_READ1):
-> ADR 1 0x50 <- 1 ANALOG_IN0
Liest das erste Analog-Eingangs-Byte.
- Eingang lesen, 2 Bytes (0x51, ANALOGIN_READ2):
-> ADR 1 0x51 <- 2 ANALOG_IN0 ANALOG_IN1
Liest die zwei ersten Analog-Eingangs-Bytes.
- Eingang lesen, 4 Bytes (0x52, ANALOGIN_READ4):
-> ADR 1 0x52 <- 4 ANALOG_IN0 ANALOG_IN1 ANALOG_IN2 ANALOG_IN3
Liest die vier ersten Analog-Eingangs-Bytes.
- Eingang lesen, 8 Bytes (0x53, ANALOGIN_READ8):
-> ADR 1 0x53 <- 8 ANALOG_IN0 ANALOG_IN1 ANALOG_IN2 ANALOG_IN3 ANALOG_IN4 ANALOG_IN5 ANALOG_IN6 ANALOG_IN7
Liest die acht ersten Analog-Eingangs-Bytes.
- Eingang lesen, Offset + N (0x54, ANALOGIN_READ):
-> ADR 3 0x54 Offset N <- N ANALOG_IN[Offset + 0..N-1]
Liest N Analog-Eingangs-Bytes ab einem Offset.
- Ausgang zurücklesen, 1 Byte (0x55, ANALOGOUT_READ1):
-> ADR 1 0x55 <- 1 ANALOG_OUT0
Liest das erste Analog-Ausgangs-Byte zurück.
- Ausgang zurücklesen, 2 Bytes (0x56, ANALOGOUT_READ2):
-> ADR 1 0x56 <- 2 ANALOG_OUT0 ANALOG_OUT1
Liest die zwei ersten Analog-Ausgangs-Bytes zurück.
- Ausgang zurücklesen, 4 Bytes (0x57, ANALOGOUT_READ4):
-> ADR 1 0x57 <- 4 ANALOG_OUT0 ANALOG_OUT1 ANALOG_OUT2 ANALOG_OUT3
Liest die vier ersten Analog-Ausgangs-Bytes zurück.
- Ausgang zurücklesen, 8 Bytes (0x58, ANALOGOUT_READ8):
-> ADR 1 0x58 <- 8 ANALOG_OUT0 ANALOG_OUT1 ANALOG_OUT2 ANALOG_OUT3 ANALOG_OUT4 ANALOG_OUT5 ANALOG_OUT6 ANALOG_OUT7
Liest die acht ersten Analog-Ausgangs-Bytes zurück.
- Ausgang zurücklesen, Offset + N (0x59, ANALOGOUT_READ):
-> ADR 3 0x39 Offset N <-N ANALOG_OUT[Offset + 0..N-1]
Liest N Analog-Ausgangs-Bytes ab einem Offset zurück.
- Ausgang schreiben (0x5A, ANALOGOUT_WRITEN):
-> ADR N+1 0x5A ANALOG_OUT[Offset + 0..N-1] <- 0
Schreibt die N ersten Analog-Ausgangs-Bytes.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Ausgänge bereits entsprechend aktualisiert wurden.
- Ausgang schreiben, Offset + N (0x5B, ANALOGOUT_WRITE):
-> ADR N+2 0x5B Offset, ANALOG_OUT[Offset + 0..N-1] <- 0
Schreibt N Analog-Ausgangs-Bytes ab einem Offset.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Ausgänge bereits entsprechend aktualisiert wurden.
- Konfiguration lesen (0x60, ANALOG_CFG_READ):
-> ADR 3 0x60 Offset N <- N Config[Offset + 0..N-1]
Liest die Analog-I/O-Konfiguration.
Die Bedeutung der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
- Konfiguration schreiben (0x61, ANALOG_CFG_WRITE):
-> ADR N+2 0x61 Offset Config[Offset + 0..N-1] <- 0
Schreibt die Analog-I/O-Konfiguration.
Dies kann z.B. verwendet werden, um bestimmte I/Os als Eingang, Open-Collector-Ausgang oder Push-Pull-Ausgang zu konfigurieren, oder den I/Os bestimmte Funktionen zuzuweisen.
Die Bedeutung der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
- Status lesen (0x62, ANALOG_STATUS):
-> ADR 3 0x62 Offset N <- N Status[Offset + 0..N-1]
Liest den Analog-I/O-Status.
Dies kann verwendet werden, um den Status bestimmter I/O-Funktionen abzufragen.
Siehe auch: Kommando "Control schreiben (0x63)"
Die Bedeutung der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt wurde und somit die neue Konfiguration bereits aktiv ist.
- Control schreiben (0x63, ANALOG_CONTROL):
-> ADR N+2 0x63 Offset Control[Offset + 0..N-1] <- 0
Aktiviert, deaktiviert bzw. konfiguriert Analog-I/O-Funktionen.
Dieses Kommando ist dazu gedacht, bestimmte Analog-I/O-Funktionen ein- und auszuschalten bzw. ihren Modus einzustellen (z.B. A/D-Wandler, PWM-Modus, Echtzeituhr).
Jede Funktion besitzt hierbei mindestens 2 Bits:
- 1.Bit: Deaktiviert die entsprechende Funktion.
- ab 2.Bit: Aktiviert die entsprechende Funktion bzw. einen bestimmten Modus.
Ob eine bestimmte Funktion derzeit aktiv ist, und welchen Modus sie verwendet, kann üblicherweise über den Status (0x62) abgefragt werden.
Über den Kommunikations-Status (Kommando 0x0A) kann abgefragt werden, ob dieses Kommando erledigt und somit die Digital-I/O-Funktionen bereits entsprechend (de)aktiviert wurden.
Werden gleichzeitig mehrere Analog-I/O-Funktionen aktiviert bzw. deaktiviert, so hängt die Reihenfolge von der Software des Geräts ab. Werden kurz hintereinander mehrere "Control"-Kommandos an ein Gerät gesendet, so kann die Abarbeitungs-Reihenfolge von der Kommando-Reihenfolge abweichen. Soll eine bestimmte Reihenfolge sichergestellt werden, so muss vor dem Absenden weiterer Control-Kommandos durch eine Abfrage des Statuses sichergestellt werden, dass die vorherigen Control-Kommandos bereits abgearbeitet wurden.
Bei Funktionen, die mehr als 2 Control-Bits besitzen, muss immer darauf geachtet werden, dass das vorherige Control-Kommando abgearbeitet wurde, bevor ein neues Control-Bit für diese Funktion gesetzt wird!
Die Bedeutung der einzelnen Bits der Daten-Bytes ist geräteabhängig und findet sich in der jeweiligen Geräte-Dokumentation.
- Handler: Control-Änderung lesen (0x64, ANALOG_HANDLER_CONTROL_READ):
-> ADR 4 0x64 Handlernummer Offset N <- N Control[Offset + 0..N-1]
Liest aus, welche Control-Bits gesetzt werden, falls ein bestimmter Handler aufgerufen wird.
Siehe auch: Kommando "Handler: Control schreiben (0x65)", Ereignisgesteuerte Automatisierung
- Handler: Control-Änderung schreiben (0x65, ANALOG_HANDLER_CONTROL_WRITE):
-> ADR N+3 0x65 Handlernummer Offset Control[Offset + 0..N-1] <- 0
Legt fest, welche Control-Bits gesetzt werden sollen, falls ein bestimmter Handler aufgerufen wird. Der Handler 0 definiert hierbei den Zustand nach einem Geräte-Reset.
Parameter:
- Handler: Handler-Nummer
- Offset: Control-Byte-Offset
- Control: Control-Bytes
Siehe auch: Ereignisgesteuerte Automatisierung, Kommando "Control schreiben (0x63)"
- Handler: Ausgangs-Änderung lesen (0x66, ANALOG_HANDLER_OUTPUT_READ):
-> ADR 4 0x66 Handlernummer Offset N <- N MaskOut[Offset + 0..N-1]
Liest aus, welche Ausgänge verändert werden, falls ein bestimmter Handler aufgerufen wird.
Siehe auch: Kommando "Handler: Ausgang schreiben (0x65)", Ereignisgesteuerte Automatisierung
- Handler: Ausgangs-Änderung schreiben (0x67, ANALOG_HANDLER_OUTPUT_WRITE):
-> ADR N+3 0x67 Handlernummer Offset MaskOut[Offset + 0..N-1] <- 0
Legt fest, welche Ausgänge verändert werden sollen, falls ein bestimmter Handler aufgerufen wird. Der Handler 0 definiert hierbei den Zustand nach einem Geräte-Reset.
Parameter:
Handler: Handler-Nummer
Offset: "MaskOut"-Offset
MaskOut: Byte-Maske und Ausgangswerte je Ausgangs-Byte:
BYTEMASK0 OUTPUT[0..7] BYTEMASK1 OUTPUT[8..15] ...
Ist ein Bit in der Bitmaske gesetzt, so wird das entsprechende Ausgangs-Byte auf den Wert des OUTPUT-Bytes gesetzt, d.h.:
- BYTEMASK: Bit 0 = OUTPUT-Byte 0, Bit 1 = OUTPUT-Byte 1, ...
- BYTEMASK-Bit = 0: Ausgangs-Byte wird nicht geändert
- BYTEMASK-Bit = 1: Ausgangs-Byte wird auf OUTPUT-Wert geändert
Siehe auch: Ereignisgesteuerte Automatisierung
- Event: Konfiguration lesen (0x68, ANALOG_EVENT_READ):
-> ADR 4 0x68 Eventnummer Offset N <- N CFG[Offset + 0..N-1]
Liest eine Analog-I/O-Event-Konfiguration aus.
Siehe auch: Kommando "Event: Konfiguration schreiben (0x69)", Ereignisgesteuerte Automatisierung
- Event: Konfiguration schreiben (0x69, ANALOG_EVENT_WRITE):
-> ADR N+3 0x69 Eventnummer Offset CFG[Offset + 0..N-1] <- 0
Konfiguriert ein Analog-I/O-Event.
Parameter:
- Event: Analog-I/O-Event-Nummer (Die Anzahl der Analog-I/O-Events ist geräteabhängig.)
- Offset: CFG-Offset
- CFG: Event-Konfiguration: Handler-Nummer und Eingangs-Konfiguration
Die Bedeutung der CFG-Bytes ist geräteabhängig.
Siehe auch: Ereignisgesteuerte Automatisierung
5.7 Motor
(folgt demnächst)
5.8 gerätespezifische Befehle
Die Kommandos im Bereich 0xF0 bis 0xFF sind gerätespezifisch. Informationen zu den unterstützten Kommandos und ihrer Bedeutung finden Sie in der jeweiligen Geräte-Dokumentation.