VBus-Decoder: Unterschied zwischen den Versionen

Aus Hobbyelektronik.org
(Die Seite wurde neu angelegt: „In unserer Solaranlage arbeitet ein Viessmann Vitosolic 200, der die Regelung der Anlage übernimmt. Nach kurzer Recherche stellte sich heraus, dass es sich um ei…“)
 
Zeile 62: Zeile 62:
 
An diese sendet der Regler alle von ihm gemessenen Werte. Neben der Regler-Identität hat der Vitosolic 200 noch die Identitäten WMZ1 und WM2 (Wärmemengenzähler).
 
An diese sendet der Regler alle von ihm gemessenen Werte. Neben der Regler-Identität hat der Vitosolic 200 noch die Identitäten WMZ1 und WM2 (Wärmemengenzähler).
  
(to be continued...)
+
=Software=
 +
Die Software ist, wie immer, in C geschrieben.
 +
Über den Befehl Vbus_ProcessChar() kann ein Zeichen von der seriellen Schnittstelle übergeben werden. Im einfachsten Fall kann die ISR-Routine wie folgt aussehen:
 +
 
 +
<pre>
 +
ISR (USART_RXC_vect) {
 +
Vbus_ProcessChar(UDR);
 +
}
 +
</pre>
 +
 
 +
Vorher muss noch der UART initialisiert werden (9600 8N1, sei() nicht vergessen!).
 +
 
 +
Die empfangenen und dekodierten Daten werden in der Variable vbus_outdata gespeichert.
 +
In dieser Variable muss auch angegeben werden, ob ein Paket gelesen werden soll:
 +
<pre>
 +
vbus_outdata.update = 1;
 +
</pre>
 +
 
 +
Ist ein Paket vollständig angekommen, wird die valid-Eigenschaft auf 1 gesetzt. Im Demo-Code wird nach erfolgreichem Empfang das komplette Datenpaket am UART ausgegeben (bitte nicht an den Regler zurückschicken, sondern möglichst an den PC!):
 +
 
 +
<pre>
 +
int main() {
 +
 
 +
  ...
 +
 
 +
  while(1) {
 +
    if(vbus_outdata.valid == 1) {
 +
      vbus_outdata.valid = 0;
 +
      VBus_Show_Values();
 +
      vbus_outdata.update = 1;
 +
    }
 +
  }
 +
}
 +
</pre>
 +
 
 +
Der Debug in der Software schreibt einige Informationen zur Dekodierung auf einem LC-Display. Über UART macht das kaum Sinn, da man den Empfang der Daten verpasst.
 +
Zugegebermaßen: ich habe einen richtigen Exoten mit LC7980-Controller und einer Auflösung von 240x40 Pixel verwendet. Die Routinen lassen sich aber halbwegs einfach auf einen anderen Displaycontroller anpassen.
 +
Die Ausgabe auf dem Display sieht wie folgt aus:
 +
 
 +
==Debug-Ausgabe==
 +
Bei jedem Sync wird "Sync" angezeigt.
 +
 
 +
Wurde der Head empfangen, kommt es zu folgender Ausgabe:
 +
 
 +
<pre>
 +
D:<Ziel-Adresse> S:<Quell-Adresse> V:<Protokoll-Version> C:<Befehl> F:<Anzahl Frames> C:<Prüfsumme ok|nok>
 +
</pre>
 +
 
 +
Danach wird, wenn die Prüfsumme ok ist jedoch das falsche Protokoll angegeben wurde, die Meldung "!V1.0->dropped " ausgegeben.
 +
Hat das Paket das "falsche" Adress-Pärchen, wird "Wrong addr->dropped " angezeigt.
 +
 
 +
Kommen diese beiden Meldungen nicht, werden Informationen über die dekodierten Frames ausgegeben:
 +
 
 +
<pre>
 +
F<Frame-Index><Prüfsumme ok|nok>
 +
</pre>
 +
 
 +
Im Ganzen kann solch eine Ausgabe wie folgt aussehen:
 +
<pre>
 +
Sync [Display wird geleert]
 +
D:0x0010 S:0x7321 V:1 C:0x0100 F:18 S:ok F0ok F1ok F2ok F3ok F4ok F5ok F6ok F7ok F8ok F9nok F10ok F11ok F12ok F13ok F14nok F15ok F16ok F17ok
 +
</pre>
 +
 
 +
Gleiches Beispiel mit meinen Testdaten, nur dass hier (im Gegensatz zu den Daten!!) Frame 9 und 14 ungültig sind.
 +
 
 +
==Bekannte Fehler/Macken==
 +
 
 +
Manche Felder sind falsch oder an der falschen Stelle. Im Vergleich zum Resol ServiceCenter (in Klammern) ergibt sich folgendes:
 +
*Temperatursensor 12 zeigt 0.0 an (888.8 - unbelegt)
 +
*Sensorbruchsmaske ist 0 (4024)
 +
*Sensorkurzschlussmaske und Sensorbenutzungsmaske sind vertauscht
 +
 
 +
Folgendes wurde noch nicht getestet/ist unbekannt:
 +
*Negative Temperaturen
 +
*Einstrahlung
 +
*Werte hinter der Fehler- & Warnungsmaske (muss ich noch in den XML-Dateien nachlesen)
 +
*Unbekannt-Felder
 +
*Woher kommt der Wochentag bei der Systemzeit
 +
 
 +
Verbesserungswürdig an der Software:
 +
*RAM-Belegung
 +
*Ziel der Daten (vbus_outdata) durch Pointer definierbar
 +
*Unterstützung der weiteren Protokolle (Parametrisierung - werde ich aber vermutlich nicht in absehbarer Zeit implementieren)
 +
*Es ist nicht ersichtlich, welche Daten durch Prüfsummenfehler ungültig sind
 +
 
 +
=Download=
 +
 
 +
*[[Datei:VBus-Protokollspezifikation.pdf]] Stand: 20.04.2009
 +
*[[Datei:VbusDecode.zip]] Version 0.1beta vom 04.03.2010 ATmega32 @ 12MHz
 +
 
 +
An dieser Stelle noch einmal vielen Dank an Resol für die Bereitstellung der Informationen und die Erlaubnis, diese hier weiter zu verteilen!
 +
 
 +
=Weblinks=
 +
* [http://www.mikrocontroller.net/topic/96431 Diskussion auf Mikrocontroller.net] (gleicher Link wie oben)
 +
* [http://www.resol.de RESOL - Elektronische Regelungen GmbH]
 +
* [http://www.resol.de/index/produktdetail/kategorie/1/id/9/sprache/de DeltaSol® M] Regler, der der Viessmann Vitosolic 200 "alt" in ziemlich genau entspricht
 +
 
 +
 
 +
[[Kategorie:AVR]]
 +
[[Kategorie:Maschinen]]

Version vom 4. März 2010, 20:52 Uhr

In unserer Solaranlage arbeitet ein Viessmann Vitosolic 200, der die Regelung der Anlage übernimmt. Nach kurzer Recherche stellte sich heraus, dass es sich um eine etwas angepasste Version des RESOL DeltaSol® M handelt.

Statt der RS232-Schnittstelle hat das Teil einen Anschluss für den Viessmann-eigenen KM-Bus, zu dem es keinerlei Informationen gibt.

Beim VBus sieht es schon ein wenig anders aus. In der Diskussion auf Mikrocontroller.net bin ich auf den Beitrag von Daniel Wippermann gestoßen, woraufhin ich an die angegebene Adresse eine E-Mail geschickt habe.

Keine zweieinhalb Stunden später habe ich die Dokumentation (inklusive der Erlaubnis zur Veröffentlichung, siehe Download) zum Protokolls erhalten.

Hardwareschnittstelle

Wo Rx und Tx ist, muss erraten werden ;)

Bei dem VBus handelt es sich um eine bidirektionale halbduplex Zweidrahtschnittstelle, die zwar Ähnlichkeiten zu RS485 hat, diesem aber nicht entspricht.

Der Master (Regel-Einheit) versorgt den Bus mit etwa 8,2V und 35mA (S. 4 in der Doku). Die Daten werden durch Spannungsabsenkung auf dem Bus übertragen. Mit der Schaltung auf Seite 5 des PDFs kann auf dem Bus sowohl gelesen, als auch geschrieben werden. Im Bild rechts meine Interpretation der Schaltung (in der noch die Abblockkondensatoren fehlen).

Über die Buchse links kann man sich mit UART (nicht RS232!) mit 9600 Baud, 8 Datenbits, 1 Stoppbit ohne Parität mit dem Master unterhalten.

Protokoll

Das Protokoll des VBus ist in seiner Version 1.0 ziemlich gut handzuhaben.


Folgendes Daten habe ich zum Testen verwendet:

0xAA, 0x10, 0x00, 0x21, 0x73, 0x10, 0x00, 0x01, 0x12, 0x38, 
0x5E, 0x04, 0x5E, 0x01, 0x05, 0x39 
0x45, 0x01, 0x38, 0x22, 0x04, 0x5B 
0x38, 0x22, 0x38, 0x22, 0x05, 0x46 
0x6C, 0x01, 0x38, 0x22, 0x05, 0x33 
0x38, 0x22, 0x38, 0x22, 0x05, 0x46 
0x38, 0x22, 0x38, 0x22, 0x05, 0x46 
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F 
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F 
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
0x38, 0x0F, 0x00, 0x00, 0x01, 0x37 
0x47, 0x00, 0x00, 0x00, 0x00, 0x38 
0x64, 0x64, 0x00, 0x00, 0x00, 0x37 
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F 
0x00, 0x00, 0x00, 0x00, 0x00, 0x7F 
0x00, 0x00, 0x43, 0x00, 0x00, 0x3C 
0x00, 0x00, 0x02, 0x00, 0x00, 0x7D 
0x01, 0x03, 0x60, 0x02, 0x04, 0x15 
0x02, 0x00, 0x00, 0x00, 0x00, 0x7D

Zu allererst wird ein 10 Byte langer Kopf gesendet, der mit einem eindeutigen Sync-Wort (0xAA) beginnt. Eindeutig heißt: An keiner anderen Stelle im Protokoll wird das MSB belegt. Man kann sich also zu jedem beliebigen Zeitpunkt in den Bus einklinken!

Gefolgt vom Sync-Wort kommen Ziel- und Quelladresse (0x0010 <= 0x7321), die Protokollversion (0x10), der ausgeführte Befehl (0x0100) und die Anzahl der danach folgenden Nutzpakete (0x12). Abschließend wird eine Prüfsumme (0x38) der zuvor gesendeten Daten übertragen.

Im Anschluss des Headers werden n Datenframes mit je 6 Byte Länge geschickt. Die ersten 4 enthalten Nutzdaten, im 5. wird ein Septett geschickt und abschließend erfolgt wieder eine Checksum.

Das Septett ist eine Ergänzung der zuvor gesendeten Nutzdaten. Da, wie oben erwähnt, das MSB nur im Sync-Wort vorkommen kann, dürfen folgende Daten kein höchstwertiges Bit enthalten. Dieses findet sich jeweils im Septett.

Das ist auch schon das gröbste. Mit Protokollversion 2.0 und 3.0 habe ich mich noch nicht auseinandergesetzt, da diese zum Erfassen der Messwerte nicht benötigt werden.

Hintergrund

Noch eine kleine Hintergrundinformation, worum es sich bei der Ziel- und Quell-Adresse handelt.

Die Quelladresse ist selbstverständlich der Regler (0x7321 = Vitosolic 200 [Regler]), die Zieladresse (0x0010) wird in der kompletten Dokumentation nur als DFA beschrieben. Dabei handelt es sich nicht um eine komische Umschreibung für einen Broadcast, sondern um die Daten für ein zusätzliches Gerät, der Datenfernanzeige.

An diese sendet der Regler alle von ihm gemessenen Werte. Neben der Regler-Identität hat der Vitosolic 200 noch die Identitäten WMZ1 und WM2 (Wärmemengenzähler).

Software

Die Software ist, wie immer, in C geschrieben. Über den Befehl Vbus_ProcessChar() kann ein Zeichen von der seriellen Schnittstelle übergeben werden. Im einfachsten Fall kann die ISR-Routine wie folgt aussehen:

ISR (USART_RXC_vect) {
	Vbus_ProcessChar(UDR);
}

Vorher muss noch der UART initialisiert werden (9600 8N1, sei() nicht vergessen!).

Die empfangenen und dekodierten Daten werden in der Variable vbus_outdata gespeichert. In dieser Variable muss auch angegeben werden, ob ein Paket gelesen werden soll:

vbus_outdata.update = 1;

Ist ein Paket vollständig angekommen, wird die valid-Eigenschaft auf 1 gesetzt. Im Demo-Code wird nach erfolgreichem Empfang das komplette Datenpaket am UART ausgegeben (bitte nicht an den Regler zurückschicken, sondern möglichst an den PC!):

int main() {

  ...

  while(1) {
    if(vbus_outdata.valid == 1) {
      vbus_outdata.valid = 0;
      VBus_Show_Values();
      vbus_outdata.update = 1;
    }
  }
}

Der Debug in der Software schreibt einige Informationen zur Dekodierung auf einem LC-Display. Über UART macht das kaum Sinn, da man den Empfang der Daten verpasst. Zugegebermaßen: ich habe einen richtigen Exoten mit LC7980-Controller und einer Auflösung von 240x40 Pixel verwendet. Die Routinen lassen sich aber halbwegs einfach auf einen anderen Displaycontroller anpassen. Die Ausgabe auf dem Display sieht wie folgt aus:

Debug-Ausgabe

Bei jedem Sync wird "Sync" angezeigt.

Wurde der Head empfangen, kommt es zu folgender Ausgabe:

D:<Ziel-Adresse> S:<Quell-Adresse> V:<Protokoll-Version> C:<Befehl> F:<Anzahl Frames> C:<Prüfsumme ok|nok>

Danach wird, wenn die Prüfsumme ok ist jedoch das falsche Protokoll angegeben wurde, die Meldung "!V1.0->dropped " ausgegeben. Hat das Paket das "falsche" Adress-Pärchen, wird "Wrong addr->dropped " angezeigt.

Kommen diese beiden Meldungen nicht, werden Informationen über die dekodierten Frames ausgegeben:

 F<Frame-Index><Prüfsumme ok|nok>

Im Ganzen kann solch eine Ausgabe wie folgt aussehen:

Sync [Display wird geleert]
D:0x0010 S:0x7321 V:1 C:0x0100 F:18 S:ok F0ok F1ok F2ok F3ok F4ok F5ok F6ok F7ok F8ok F9nok F10ok F11ok F12ok F13ok F14nok F15ok F16ok F17ok

Gleiches Beispiel mit meinen Testdaten, nur dass hier (im Gegensatz zu den Daten!!) Frame 9 und 14 ungültig sind.

Bekannte Fehler/Macken

Manche Felder sind falsch oder an der falschen Stelle. Im Vergleich zum Resol ServiceCenter (in Klammern) ergibt sich folgendes:

  • Temperatursensor 12 zeigt 0.0 an (888.8 - unbelegt)
  • Sensorbruchsmaske ist 0 (4024)
  • Sensorkurzschlussmaske und Sensorbenutzungsmaske sind vertauscht

Folgendes wurde noch nicht getestet/ist unbekannt:

  • Negative Temperaturen
  • Einstrahlung
  • Werte hinter der Fehler- & Warnungsmaske (muss ich noch in den XML-Dateien nachlesen)
  • Unbekannt-Felder
  • Woher kommt der Wochentag bei der Systemzeit

Verbesserungswürdig an der Software:

  • RAM-Belegung
  • Ziel der Daten (vbus_outdata) durch Pointer definierbar
  • Unterstützung der weiteren Protokolle (Parametrisierung - werde ich aber vermutlich nicht in absehbarer Zeit implementieren)
  • Es ist nicht ersichtlich, welche Daten durch Prüfsummenfehler ungültig sind

Download

An dieser Stelle noch einmal vielen Dank an Resol für die Bereitstellung der Informationen und die Erlaubnis, diese hier weiter zu verteilen!

Weblinks