WRP, Wireless Railroad Protocol
Version: 0.06
Innerhalb des Funknetzwerkes z.B. mit XBEE-Modulen werden die Nutzinformationen ('Payload') byteweise eingebettet. Nachfolgendes Protokoll definiert die Nachrichten zum Steuern einer Modellbahn, wie z.B. vom Handregler verwendet wird. Dieses Protokoll ist zum einen auf Effizienz optimiert, zum anderen durch den hierarchischen und logischen Aufbau besonders leicht zu dekodieren und damit für Mikrocontroller gut geeignet.
Prinzipieller Aufbau
-
Das Protokoll WRP ist immer gemäß folgender Konvention aufgebaut: [[header][type][opcode][addr][data]]. Mehrfache Header
in einer XBEE Nachricht sind zulässig, jedoch muß eine XBEE-Nachricht immer mit einem Header beginnen. Eine einzelne
Modellbahnnachricht darf sich nicht über mehrere XBEE-Nachrichten erstrecken. Dadurch ist es möglich, bei
vielen Nachrichten den prozentualen Overhead der Verwaltungsschicht (framing und routing) signifikant zu reduzieren.
Nachrichten, welche von einem Teilnehmer nicht verstanden werden (z.B. weil sie noch nicht implementiert sind oder weil die Fähigkeiten nicht ausreichen), werden einfach ignoriert (Ausnahme: state-Nachrichten). Abfragen sind innerhalb von 200ms zu beantworten. Wenn eine Abfrage innerhalb von 400ms nicht beantwortet ist, wird die Verbindung als unterbrochen betrachtet. Die Zentrale bzw. Basisstation soll in diesem Fall bewegte Objekte (z.B. Loks) in einen konfigurierbaren Zustand (z.B. SOFT_STOP) umschalten.
Dabei bedeutet:
| WRP Protokoll | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| [header] | 8 Bit | Gibt die Größe der Nachricht in Bytes an, Bereich 0-127;
Ein gesetztes MSB bedeutet, diese Nachricht
ist bestätigt und kommt von der Zentrale. Ein gelöschtes MSB bedeutet eine
Anforderung oder Anfrage an die Zentrale.
Nachrichten an die Zentrale können (und sollen), müssen aber nicht bestätigt werden.
State-Nachrichten an die Zentrale müssen bestätigt werden, erst dann gilt der neue
State als bestätigt. Die Länge ist in Bytes angegeben, der header selbst wird nicht mitgezählt. Ein header=0 markiert das Ende einer Befehlssequenz. Wenn das Ende der Befehlssequenz durch die Art der Übertragung sicher erkannt werden kann (z.B. bei ZigBEE/XBEE wird die Zahl der übertragenen Bytes mitgeliefert), dann kann die Endemarkierung entfallen. Der Nachrichtenempfänger muß in diesem Fall das Ende selber abprüfen. | ||||||||||||||
| [type] | 4 Bit (0..3) | Gibt die Klasse der Nachricht an. Es sind folgende Klassen definiert:
| ||||||||||||||
| [opcode] | 4 Bit (4..7) | Gibt innerhalb einer Nachrichtenklasse die anforderte oder auszuführende Operation an. z.B. speed setting|function setting|... | ||||||||||||||
| [addr] | 16 Bit | Optional: Gibt innerhalb einer Nachrichtenklasse die Nummer des Objekts (z.B. Lok) an, die für diese Operation verwendet werden soll. [addr] = 0xFFFF bezeichnet i.d.R. einen Broadcast, d.h. die Nachricht gilt für alle Objekte in dieser Klasse. Dieser Wert wird 'little endian' übertragen, d.h. das niederwertige Byte kommt zuerst. | ||||||||||||||
| [data] | 0 Byte ... 64 Byte, byteweise organisiert. | Enthält die notwendigen Daten und Parameter zum Befehl. | ||||||||||||||
type: state
-
Der type state ist als 0x1 codiert. Prinzipiell wird der type 'state' von der Zentrale bestätigt, erst dann
ist er gültig. 'state'-Nachrichten von Clients sind Anfragen/Wünsche, den System-Zustand zu ändern.
Es gibt folgende Opcodes:
| type: state | ||
|---|---|---|
| Wert | opcode | Bedeutung |
| 0x0 | OFF | Das System wird abgeschaltet. |
| 0x1 | STOP | Alle Loks werden mittels Nothalt angehalten, jedoch Weichen können nach wie vor geschaltet werden. Wenn Stop von der Zentrale nicht unterstützt wird, so wird OFF ausgeführt. |
| 0x2 | SOFT-STOP | Alle Loks werden mit Fahrstufe 0 (also mit ihrer eigenen Verzögerung) angehalten, Weichen können weiterhin geschaltet werden. Wenn Soft-Stop von der Zentrale nicht unterstützt wird, so wird STOP ausgeführt. |
| 0x3 | GO | Wiederaufnahme des Betriebes |
| 0x8 | PROG | Programmiermode |
| 0xD | BUSY | Die Basestation bzw. der Funkkanal ist nicht mehr aufnahmefähig. Jeder Funkteilnehmer soll für mind. 100ms keine weiteren Nachrichten absenden. |
| 0xE | DISCONNECT | Base Station is no longer connected to a command station. |
| 0xF | QUERY | Abfrage des aktuellen Status. Wenn die Basestation dieses Kommando erhält, sendet sie den Status erneut ab. |
type: loco
-
Der type loco ist als 0x2 codiert. Es gibt folgende Opcodes:
- (1) Die Geschwindigkeit wird immer als Ganzzahl von 0 bis * kodiert, z.B. bei DCC126 also von 0 bis 126. Fahrstufe 1 bedeutet langsame Fahrt (und nicht Nothalt wie bei der Gleisausgabe); Es liegt im Ermessen der Basisstation, diese Angabe je nach verwendetem Digitalsystem und/oder Decoder in die Fahrstufen des Zieles umzurechnen, i.d.R. werden aber die Fahrstufen 1:1 durchgereicht.
- (2) Ein Client, welchem die Kontrolle über eine Lok entzogen wurde, darf erst nach einer Bedieneraktion zu dieser Lok wieder versuchen, die Lok wieder unter Kontrolle zu nehmen. Beispielsweise sind automatische Sequenzen (Massensimulation) abzubrechen. Der Client darf aber die aktuellen Parameter dieser Lok nachfragen (QUERY) um seine Anzeige aktuell zu halten, jedoch nicht öfter als 3 Anfragen/s.
- (3) Die Mechanismen zum Schützen und Freigeben sind optional.
| type: loco | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Wert | opcode | Bedeutung | ||||||||||||||||||||||
| 0x0 | ESTOP | Hält die Lok [addr] mittels Notstop (DCC Fahrbefehl mit Wert 1) an.
Es können auch mehrere Loks (jeweils Adresse als 16-Bitwort)
in einer Nachricht übermittelt werden. Diese weiteren Loks werden
als Liste von 16-Bit Werten (little endian) im Datenfeld übertragen.
ESTOP ist nur zulässig auf Adressen, welche vorher diesem Handregler zugeteilt wurden. ESTOP löst keinen Eigentümerwechsel aus, der bisherige Eigentümer erhält auch keine Benachrichtung (obwohl der Nothalt durchgeführt wird). | ||||||||||||||||||||||
| 0x1 | CONTROL | Einstellen von Speed, Dir, Licht, Funktionen F1-F28 der Lok [addr].
Die Werte sind im Datenfeld kodiert.
Wenn ein Handregler diese Nachricht an eine Zentrale senden, so heißt dass, er will
die Lok auch übernehmen.
| ||||||||||||||||||||||
| 0x2 | DRIVE | Einstellen von Speed, Dir der Lok [addr].
Die Werte sind im Datenfeld kodiert.
Wenn ein Handregler diese Nachricht an eine Zentrale senden, so heißt dass, er will
die Lok auch übernehmen.
| ||||||||||||||||||||||
| 0x4 | QUERY | Abfragen der Lokparameter. Die Zentrale antwortet mit mit einer CONTROL-Nachricht, die Lok wird dabei nicht übernommen. | ||||||||||||||||||||||
| 0x5 | STOLEN | Die Lok wurde an anderer Stelle übernommen. Diese Nachricht erhält der Client, welcher zuletzt die Lok kontrollierte. (2) | ||||||||||||||||||||||
| 0x6 | ERROR | Die Lok kann nicht gesteuert werden (Masternachricht). Normalerweise ist ein Fehler aufgetreten beim Versuch, die Lok zu steuern. (z.B. Lokbuffer voll) | ||||||||||||||||||||||
| 0x8 | RESERVE | Die Lok wird gegen Übernahme durch einen anderen Regler gesichert. Wenn diese Nachricht vom Master kommt, konnte die Lok nicht übernommen werden. (3) | ||||||||||||||||||||||
| 0x9 | FREE | Die Lokreservierung ist aufgehoben. (3) | ||||||||||||||||||||||
| 0xF | LOCATE | Die Lok [addr] wurde vom railcom Detektor SID (Sensor ID) erkannt.
| ||||||||||||||||||||||
type: accessory
-
Der type accessory ist als 0x3 codiert. Es gibt folgende Opcodes:
| type: loco | ||
|---|---|---|
| Wert | opcode | Bedeutung |
| 0x0 | A_QUERY | Abfragen der Stellung. Durch eine Abfrage der Stellung wird die Weiche automatisch in die Watchliste aufgenommen. Die Zentrale antwortet mit mit einer A_POSIT-Nachricht. |
| 0x1 | A_SET | Der Zubehördekoder mit der Adresse [addr] wird mit Begriff in data[0] angesteuert.
[addr] steht hier für die echte (DCC-)Adresse
und wird bei 0 beginnend gezählt.
Zweibegriffige Zubehördekoder werden mit (aspect 0 = red) und (aspect 1 = green) angesteuert. (Die Zentrale erzeugt den Einschaltbefehl auf dem zugehörigen (gepaartem) Spulenausgang.) |
| 0x2 | A_RESET | Der Zubehördekoder mit der Adresse [addr] wird mit Begriff in data[0] angesteuert. (Coil off, Abschaltbefehl; die Zentrale schickt den DCC-Abschaltbefehl an den Dekoder, anschließend wird eine eventuelle Stellungsrückmeldung eingelesen.) |
| 0x3 | A_POSIT | Anzeige der Stellung (Nachricht von der Zentrale). Dieser Befehl ist wie A_SET kodiert, er löst aber keine Aktion aus. (Nur Stellungsanzeige). Wenn beim Aspect das MSB (0xFF) gesetzt ist, ist die Weiche noch nicht umgelaufen bzw. die Stellung unbekannt. |
| 0x4 | WATCH | Mit diesem Kommando kann ein Client die in [addr] übergebene Weiche beobachten lassen. Er wird dann bei Zustandsänderungen dieser Weiche automatisch benachrichtigt. Eine Basisstation muß mind. 4 Beobachtungsplätze je Regler anbieten; sollte keine Beobachtungsplätze mehr frei sein, antwortet die Zentrale mit UNWATCH. |
| 0x5 | UNWATCH | Mit diesem Kommando wird die Beobachtung wieder aufgehoben. Wenn bei UNWATCH der Parameter [addr] == 0xFFFF ist, dann werden alle aktuell gesetzten Beobachtungen dieses Handreglers gelöscht. |
| 0x8 | XA_SET | Der Extended Zubehördekoder mit der Adresse [addr] wird mit Begriff in data[0] angesteuert. |
| 0x9 | XA_POSIT | Anzeige der Stellung (Nachricht von der Zentrale). Dieser Befehl ist wie XA_SET kodiert, er löst aber keine Aktion aus. |
| 0xA | XA_QUERY | Abfragen der Stellung. Die Zentrale antwortet mit mit einer XA_POSIT-Nachricht |
type: feedback
-
Der type feedback ist als 0x4 codiert. Es gibt folgende Opcodes:
| type: feedback | ||
|---|---|---|
| Wert | opcode | Bedeutung |
| 0x0 | FEVENT | Ein oder mehrere Sensorereignisse wird übermittelt. Jedes Sensorereignis ist als 16 bit kodiert, little endian. Sensorereignisse sind in ADDR und DATA[0/1] usw. kodiert. Je Meldung dürfen maximal 16 Sensorereignisse übertragen werden. |
| 0x1 | FQUERY | Abfrage von Rückmeldeereignissen. Die Databytes enthalten die Adressen der angefragten Ereignisse. Je Abfrage dürfen maximal 16 Sensorereignisse abgefragt werden. |
| 0x2 | BIDI | Meldung eines Railcomereignisses (noch genauer zu definieren) |
| 0x3 | QBIDI | Abfragen eines Railcomereignisses (noch genauer zu definieren) |
| Sensorereignis | ||
|---|---|---|
| Bit 15..12 | Bit 11..0 | Bedeutung |
| 0b0000 | ADDR | Das Rückmeldebit mit der Adresse ADDR ist nicht gesetzt. |
| 0b1000 | ADDR | Das Rückmeldebit mit der Adresse ADDR ist gesetzt. |
| ...... | reserviert. | |
type: programming
-
Der type programming ist als 0x5 codiert. Es gibt folgende Opcodes:
- Nach Absenden eines Programmiergleisbefehls kann (muß aber nicht) die Zentrale mit einem Status PROG MODE antworten. Ein Status PROG MODE zeigt an, dass jetzt eine Programmierung läuft und der normale Betrieb unterbrochen ist. Bei Programmieren auf dem Hauptgleis erfolgt kein Umschalten in den PROG MODE. Eine Multi-Mode-fähige Zentrale kann die Programmierung parallel zum normalen Betrieb durchführen, hier kann dann der normale Betrieb weiterlaufen.
| type: programming | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Wert | opcode | Bedeutung | ||||||||
| 0x0 | PROG_STAT | Statusreport beim Programmieren
| ||||||||
| 0x1 | RDCV | Lesen einer CV (Read).
| ||||||||
| 0x2 | WRCV | Schreiben einer CV.
| ||||||||
| 0x3 | PQUERY | Abfrage Programmierergebnis
Die Zentrale antwortet mit einer PROG_STAT Nachricht. | ||||||||
type: clock
-
Der type clock ist als 0xe codiert. Es gibt folgende Opcodes:
| type: clock | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Wert | opcode | Bedeutung | ||||||||
| 0x0 | CLKOFF | Die Uhr wird angehalten. | ||||||||
| 0x1 | CLKON | Die Uhr (mit bereits bekannten Parametern) wird eingeschaltet. Sie läuft bei der bisherigen Zeit weiter. | ||||||||
| 0x2 | CLKSET | Die Datenbyte data0 bis data3 enthalten die Uhrbefehl (analog zu DCC und Xpressnet)
| ||||||||
| 0x3 | CLKQRY | Abfragen der Uhrzeit. Die Zentrale antwortet mit mit einer CLKSET-Nachricht. | ||||||||
Die CLKSET-Nachricht wird zyklisch jede (Modellbahn-)Minute von der Zentrale übertragen. Beim Clockbefehl wird die [addr] als 0 übertragen.
type: system
-
Der type system ist als 0xf codiert. Es gibt folgende Opcodes:
- turnout database transfer
| type: system | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Wert | opcode | Bedeutung | |||||||||||||||
| 0x0 | IDLE | Diese Nachricht hat keinen Inhalt, sie wird von der Zentrale
zyklisch (mind. alle 2s) gesendet. IDLE wird nicht
gesendet, wenn irgendein anderes Paket (z.B. clock oder state) bereits
(innerhalb der Zykluszeit) an diesen Client gesendet wurde.
(Broadcast-)Pakete enthalten die PAN und MAC der Basisstation. Handregler können anhand dieser Parameter entscheiden, zu welcher Basisstation sie Kontakt aufnehmen. Handregler müssen sich bei der Basisstation regelmäßig melden (z.B. auch mit einer IDLE-Nachricht), ansonsten bucht die Basisstation den Handregler aus (Zustand SILENT) und hält alle Loks an, die von diesem Handregler gefahren wurden. Im Zustand SILENT ist der Handregler aber noch an der Zentrale angemeldet und wird auch mit Nachrichten versorgt. Jedoch wird allen Nachrichten des Typs State oder Clock eine weitere Nachricht SILENT mit angehängt. Die IDLE-Quittierung ist bei einem ungesicherten Funkkanal erforderlich. Ist die Verbindung zwischen Master und Client bereits durch ein Quittungsverfahren abgesichert (wie es z.B. bei ZigBEE der Fall ist), so sind die erhaltenen Empfangsquittungen des Clients ausreichend, um den Zustand ACTIVE dieses Clients zu halten. Wenn zukünftig Sleep-Modi aktiviert werden, übernimmt das IDLE auch die Funktion des Netzwerk-Beacon. | |||||||||||||||
| 0x1 | SILENT | Mit diesem Opcode teilt die Basisstation dem Handregler mit, dass er ausgebucht wurde und die von ihm kontrollierten Lokomotiven angehalten wurden. Bevor der Handregler neue Befehle absetzt, muß er sich erneut anmelden. Diese Nachricht wird anstelle von IDLE gesendet und auch an alle Clock oder Systemzustandsmeldungen angehängt. | |||||||||||||||
| 0x2 | APPLY | Mit diesem Opcode kann sich ein Client um Aufnahme an der Basisstation bewerben
oder sich abmelden.
Erst wenn der APPLY von der Zentrale bestätigt wurde, kann und darf der Client
Befehle absetzen. APPLY muß die erste und auch einzige Nachricht innerhalb eines
Paketes sein.
| |||||||||||||||
| 0x3 | GRANTED | Mit diesem Opcode bestätigt die Zentrale die An- oder Abmeldung. Erst wenn die Granted-Message eingegangen ist, dann darf der Handregler Befehle absenden. | |||||||||||||||
| 0x4 | CONNECT | Mit dem Opcode connect kann festgelegt,
ob sich weitere Handregler an das Funknetz anschließen dürfen oder nicht.
| |||||||||||||||
| 0x6 | SYSINFO |
| |||||||||||||||
| 0x7 | SYSQUERY |
| |||||||||||||||
| 0x8 | PICTURE | Es wird ein Bild einer Lok übertragen; [addr] enthält die Bildkennung (Picture-ID). Ein Bild hat typischerweise nicht innerhalb einer Nachricht Platz, hier werden also Nachrichten kaskadiert. Details folgen, wie das Bild genau kodiert wird:(Bildtyp, colors,x,y,page,store) | |||||||||||||||
| 0x9 | LOCO_DB | lok database text transfer:
| |||||||||||||||
| 0xC | FIRMWARE | Downloadpaket für Firmwareupdate. Details folgen (addr, size, (i/n), store) | |||||||||||||||
| 0xE | CS_CV_QRY | CV der Zentrale abfragen. [addr] enthält die Adresse der abzufragenden
CV. Die Zentrale antwortet mit einer CS_CV_SET Nachricht. Hinweis: die Zugriffe auf Configvariablen der Zentrale dürfen nur von einem Handregler aus zur gleichen Zeit abgesetzt werden. Treffen während der Bearbeitung weitere Anfragen (z.B. von anderen Handreglern) ein, so werden diese ignoriert. Diese Zentralenreservierung wird automatisch bei Beantwortung oder zwangsweise nach einer Sekunde wieder aufgehoben. | |||||||||||||||
| 0xF | CS_CV_SET | CV der Zentrale setzen. [addr] enthält die Adresse der zu setzenden CV, [data[0]] ist der Inhalt. Die Zentrale antwortet mit einer CS_CV_SET Nachricht. | |||||||||||||||
Beispiele:
- Verbindungsaufbau:
Ein Handregler sucht nach den Einschalten nach Broadcast-Meldungen, welche mit seiner PAN übereinstimmen. Sofern er eine solche Nachricht empfängt, sendet er an diese emittierende MAC-Adresse eine SYSTEM/APPLY Nachricht. Die Basisstation entscheidet je nach Konfiguration, ob dieser Handregler zugelassen ist. Sofern er von der Basisstation zugelassen wird (SYSTEM/GRANTED), is er fortan an diese Basisstation angekoppelt und bezieht von dieser Basisstation alle Information über den Anlagenzustand und stellt auch alle Anfragen an diese Basisstation.
Sollte für eine Zeitspanne von 2 Sekunden kein weitere Nachricht von der Basisstation eingehen, betrachtet der Handregler die Verbindung als unterbrochen.
Copyright:
- Das Copyright für dieses Protokoll liegt bei mir (Wolfgang Kufer).
Jegliche Weiterverwendung dieses Protokoll oder des Logos (sowohl kommerziell als auch nicht kommerziell) bedarf
der vorherigen schriftlichen Zustimmung. Diese Einschränkung dient vor allem der Sicherstellung von Kompatibilität, nicht
dem Aussperren von Konkurrenzsystemen.
Zur vereinfachten Erstellung von Applikationen und Wartung des Protokolls gibt es eine gemeinsame header-Datei (wrp.h) mit Typ-Definitionen (#typedef) für die einzelnen Protokollfelder.