www.blafusel.de

  Home  |   Privat  |   Impressum  |   Bücher  |   Computer  |   Misc  |   OBD  |   Forum translatetraduiretraducirtradurrevertalentraduzir??????????µetaf??????
tip FAQ
KFZ-Diagnose mit OBD
Das OBD III Märchen
Fahrzeugliste
K²L901 USB KKL Interface
WBH BT5
WBH-Diag Pro
WBH-Diag Software
NEU WBH-Diag STG-Liste
Modifikationen
K-Leitung Signalqualität
KW 1281 Protokoll
VAG KW 2000 Protokoll
VAG Protokollkompatibilität
Besonderheiten
PIDs (OBD II)
NEU VAG Fehlercodes
Softwareverzeichnis
LKW Adapter 24 V
▼ Ältere Projekte [+]
▼ Plug & Play / Testcenter [+]
Fremdprojekte

zonak

OBD KW 1281 Protokoll

Inhalt

Einführung
Informationsquellen
Protokolltyp
Testumgebung
KW1281 - Initialisierung
KW1281 - Timing
KW1281 - Gerätedaten
KW1281 - Sensordaten
KW1281 - Kommunikationsende
KW1281 - Kommunikationsfehler
KW1281 - Fehlerspeicher auslesen/löschen

Einführung

Hinweis: Die folgenden Informationen sind teilweise nicht mehr auf dem letzten Stand des Wissens. Mehr Infos bietet mein o. g. Buch.

Die bisherigen Informationen zeigen, wie mit Hilfe des Interface von Jeff und dem ELM323 Daten aus dem Bordcomputer via OBD2 ausgelesen werden können. Bei Jeffs Interface wird die Software VAG-COM benutzt und beim ELM323 ScanTool. Beide Lösungen haben ihre bereits erläuterten Vor- und Nachteile. Nach dem ich bereits erfolgreich einen µC mit dem ELM323 verbunden habe, sollte noch der µC mit Jeffs Interface realisiert werden. Dies vor allem, da ich an speziellen Daten interessiert bin, die der ELM nicht liefert, sehr wohl aber per VAG-COM aus meinem VW T4 ausgelesen werden können.

Während die Kommunikation via ELM323 relativ einfach realisierbar ist, erfordert Jeffs Interface einen wesentlich höheren Aufwand, da das Interface lediglich eine Anpassung der Signalpegel vornimmt und kein Protokoll unterstützt, so daß man die gesamte Kommunikation mit dem Bordcomputer selber programmieren muß. Dafür stehen einem dann auch viel mehr Daten zur Verfügung.

Um die immer wieder auftauchende gleiche Frage vorwegzunehmen: Jeffs Interface und somit auch meine µC-Lösung funktionieren nur mit VAG-Fahrzeugen, die auch von VAG-COM ausgelesen werden können. Wer will, kann mein Forum nutzen, in dem ich interessante Fragen auch ggf. beantworte - Standardfragen, die man auch per Google lösen kann, ignoriere ich.

Informationsquellen

Vom Kauf der SAE Dokumentation J2818 kann nur dringend abgeraten werden! Für US$ 61 bekommt man so gut wir gar nichts geboten. Auf den zehn Seiten stehen nur allgemeine Infos, wie sie hier bei mir und in meinem Buch auch zu finden sind.

Im Web findet man nur spärliche Informationen zu dem Protokoll, um mit den Steuergeräten des Autos Daten auszutauschen. Zum Teil liegt das daran, daß nicht viel existiert, aber auch daran, daß viele Chip-Tuner sich zwar in die Materie eingearbeitet haben, aber nichts von ihren Betriebsgeheimnissen preisgeben wollen. Deshalb diese Seite, auf der ich mein erarbeitetes Wissen zusammenfassen möchte.

Bei der Recherche habe ich folgende Quellen gefunden, die mir weitergeholfen haben:

  • Hex Microsystems. Ausführliche Informationen zur Kommunikation - besonders zur Initialisierung. Alternativer Link: VW info page
  • AUDI-COM. Informationen vor allem zur Abfrage von Meßwerten (group reading).
  • Yahoo! Group opendiag. Kostenlose Anmeldung erforderlich. Wird immer wieder als Geheimtip angepriesen, ist aber nicht der ultimative Tip. Ein paar Infos finden sich im Ordner 'Files'.

Einige nicht so wichtige Links, die Infos bieten, die teilweise noch im weiteren Verlauf benötigt werden:

Protokolltyp

Die Steuergeräte im Auto nutzen verschiedene Protokolle. Da ich nur KW1281 bzw. KWP1281 (KW steht für KeyWord) benötige, beschränken sich alle Ausführungen auf dieses Protokoll. Andere Protokolle sind teilweise ähnlich oder auch ganz anders. Gerne wird KW1281 und ISO 9141-2 zusammen geworfen. Es handelt sich aber dabei um zwei getrennte Protokolle, die lediglich die gleichen Anschlüsse an der OBD-Buchse benutzen. Wer VAG-COM besitzt (Demoversion reicht), kann das Protokoll des Steuergerätes links oben im Programm ablesen, sobald ein Controller ausgelesen wird.

VAG-COM

Testumgebung

Das Hauptproblem bei der Protokoll-Analyse und Programmierung besteht darin, daß das Auto auf der Straße parkt und der Computer weit weg davon in der Wohnung steht. Also muß man das Auto irgendwie auf den Schreibtisch holen, wenn man nicht im Winter im Auto programmieren will (meine Standheizung respektive die Batterie hat dabei schon einmal leiden müssen). Zum Glück wird nicht das ganze Auto benötigt, sondern nur ein Steuergerät. Im Auto sind zahlreiche dieser Controller verbaut. Das interessanteste ist das Motorsteuergerät (ECM - Engine Control Module), aber auch für ABS, Airbag, Instrumente usw. gibt es separate Einheiten, die unter dem Begriff ECU (Electronic Control Unit) zusammengefaßt werden. Hat man so ein Steuergerät, kann man es auf dem Schreibtisch mit Spannung versorgen und Jeffs Interface anschließen (ein paar nette Fotos von Bastlern). Problematisch ist nur: Welches Steuergerät und wie wird es angeschlossen?

Bei ebay werden Steuergeräte, die neu bis über 1.000 Euro kosten können, haufenweise angeboten. Motorsteuergeräte sind recht beliebt. In Deutschland natürlich vor allem die von VAG (und hier vor allem vom Golf - welch Wunder). Meist sind es vermutlich Chip-Tuner, die die Geräte haben wollen, um entweder ein zerschossenes zu ersetzen oder, um Experimente zu machen. Dumm, das wir ja auch ein VAG-Gerät wollen, nicht aber bereit sind, die hochgeschraubten Preise zu bezahlen. Ideal wäre natürlich genau das gleiche Gerät, das auch im eigenen Fahrzeug verbaut ist. Die Typenbezeichnung zeigt VAG-COM bei VAG Number an (s. o.). Nun, für meinen T4 absolut unrealistisch, da selten und teuer. Also erst einmal ein Modell für die ersten Gehversuche suchen. Auch wenn die eigentlich spannenden Daten alle aus dem ECM stammen, so reicht ein ABS oder Airbag Controller erst einmal aus, um wenigstens die ersten Protokollklippen zu umschiffen. Diese sind meist wesentlich billiger (bis ca. € 20,-), denn wer baut eine gebrauchte Lebensversicherung schon in seinen eigenen Wagen ein. Da diese Geräte aber tweilweise keine Meßwerte liefern, wird später auf jeden Fall ein ECM fällig.

ECU im Testaufbau

Jetzt fehlen nur noch Informationen über den Anschluß des Controllers, also die Pinbelegung der an die 100 Pins. Im Web ist hier wieder wenig zu finden. Ein paar Pinouts habe ich gefunden. Diese werde ich im Forum veröffentlichen und hoffe, daß weitere von Euch hinzukommen. Diese Controller waren mir aber bei ebay immer zu teuer. Meinen herzlichen Dank deshalb an Wladimir von WGSoft, der mir einen Tip gab und auch die passende Pinbelegung zur Hand hatte. Inzwischen habe ich auch herausgefunden, daß das Programm Autodata die Pinbelegung für die meisten ECUs (aber keines ABS-Steuergeräte etc.) kennt. Da die relevanten Steuergeräte nicht brandneu sind, reicht auch eine ältere Version aus. Sobald man weiß, für welches Fahrzeug das Motorsteuergerät verwendet wurde, kann man sich die Pins anzeigen lassen.

Autodata

Kennt man die bei VAG-COM (s. o.) als Component bezeichnete Typenbezeichnung, hilft vielleicht auch die Liste bei EVC weiter.

Was jetzt benötigt wird, ist ein Lötkolben und ein Netzteil. Das Steuergerät muß mit ca. 12V versorgt werden. Es ist notwendig alle der oft zahlreich vorhandenen Anschlüsse für Masse (GND) und Vcc (Plus) zu verbinden. Der Anschluß für die K-Leitung des OBD-2-Steckers von Jeffs Adapter wird mit dem Diagnosesignal des Steuergerätes verbunden.

Wurde alles richtig angeschlossen, dann muß es möglich sein, Jeffs Adapter mit dem Steuergerät wie gewohnt an den PC anzuschließen und das Steuergerät mit VAG-COM auszulesen. Je nach Modell werden verschiedene Geräteinformationen angezeigt. Außerdem können Meßwerte und Fehlercodes ausgelesen werden. Da das Steuergerät nicht an irgendwelche Meßfühler angeschlossen ist, werden immer wieder neue Fehler aufgezeichnet (eventuell Versorgungsspannung zum Steuergerät kurz unterbrechen), auch wenn man die bisherigen löscht. Der Versuchaufbau auf dem Schreibtisch ist nun komplett und es kann an die Protokoll-Analyse gehen.

Um unterschiedliche Meßwerte abfragen zu können und die Anzahl der von der ECU gespeicherten auftretenden Fehler zu reduzieren, kann man relativ einfach einige Meßfühler simulieren. Die meisten Sensoren liefern eine Widerstandsänderung. Lediglich die Geschwindigkeit und die Motordrehzahl wird aus einem Taktsignal abgeleitet, welches aufweniger ist. Wird an die Anschlüsse eines Sensors (die Pins und die Widerstandswerte kann man mit Autodata in Erfahrung bringen) ein Widerstand angeschlossen, läßt sich der entsprechende Fehler nachhaltig aus dem Speicher löschen. Anstatt eines Festwiderstandes kann man auch ein Potentiometer anschließen, um änderbare Meßwerte zu simulieren. Folgende Tabelle zeigt exemplarisch drei Sensoren für die ECU 030 906 032 E:

Sensor Pin 1 Pin 2 Widerstand Meßwert
Einlaß Lufttemperatur 54 56 2,2KΩ 24°C
Motor Kühlmitteltemperatur 54 74 330Ω 79°C
Einlaß Luftdruck 54 70 1KΩ ca. 590mbar
62 70 10KΩ

KW1281 - Initialisierung

Um mit dem Controller zu kommunizieren sind zwei Phasen wichtig:
  1. Der Controller muß aufgeweckt werden, so daß er weiß, man will mit ihm kommunizieren. Niedrige Baudrate 5Bd, 7O1.
  2. Die eigentliche Kommunikation mit üblicherweise 4800, 9600 oder 10400 Baud, 8N1

Bei KW1281 erfolgt die Initialisierung, also das wake up, etwas ungewöhnlich: Mit einer Übertragungsgeschwindigkeit von lediglich 5 Baud wird an den Controller dessen Adresse geschickt. Die Adressen sind analog zu den Controller-Nummern in VAG-COM. Zu beachten ist dabei, daß in VAG-COM die Zahlenangaben für die Module in hexadezimaler schreibweise stehen. Also 1 für das Motorsteuergerät, 3 für ABS, 15 (Hex) (21 Dezimal) für Airbags usw. Nach dem aufwecken werden alle weiteren Daten mit einer wesentlich höheren Baudrate übermittelt. Problematisch ist aber die niedrige Baudrate. Auf dem PC gibt es nur wenige Programme, die so langsame Baudraten unterstützen. Auf dem ATmega8 µC ist sie nicht über den internen USART möglich. Auf dem PC kommt wohl noch das Problem hinzu, daß der Umschaltvorgang von 5Bd zu 9600 etc. zu lange dauert, so daß Daten in der Zwischenzeit verloren gehen. Ein Umstand, der für mein µC Projekt nicht relevant aber interessant ist.

Aus den genannten Gründen wird ein Trick genutzt, um das 5Bd wake up zu durchlaufen. Um das Protokoll zu analysieren gibt es zwei Möglichkeiten, bei denen die Kommunikation vom Diagnosegerät (bspw. VAS1551) mit dem Steuergerät belauscht wird:

  1. Mit einem Datenlogger (z. B. Portmon) wird die serielle Schnittstelle des PCs bzw. die Datenleitung zwischen Werkstattdiagnosegerät (VAS1551) und KFZ protokolliert. Portmon verliert bei mir allerdings Daten, da der Puffer scheinbar nicht groß genug ist. Sehr gute Ergebnisse liefert Free Serial Port Monitor. Allerdings führt das Programm auf einem meiner Rechner zum Totalabsturz - also Vorsicht. Dafür ist der Puffer groß genug.
  2. Mit einem Oszilloskop werden die Signalpegel an der K-Leitung abgegriffen.
Die erste Methode ist einfach, hat aber den Nachteil, daß sie nicht hundertprozentig akkurat ist. Ich hatte teilweise den Verdacht, daß nicht alle Daten protokolliert wurden. Allerdings findet man so heraus, wie die 5Bd Initialisierung abgewickelt wird: Statt die Geschwindigkeit an der Schnittstelle zu wechseln, wird diese gleich auf die gewünschte Datenrate für die folgende Kommunikation eingestellt (bspw. 9600Bd) und dann wird mit SET_BREAK die Übertragung simuliert:

IOCTL_SERIAL_SET_BREAK_ON
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_CLR_DTR
IOCTL_SERIAL_SET_BREAK_OFF   -> Start-Bit?
IOCTL_SERIAL_CLR_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_ON    -> 0
IOCTL_SERIAL_SET_RTS
IOCTL_SERIAL_SET_BREAK_OFF   -> 1
IOCTL_SERIAL_CLR_RTS
IOCTL_SERIAL_SET_DTR

Zwischen den einzelnen Umschaltungen liegen genau 200ms, woraus sich dann die 5Bd (1000ms/5bps) ergeben. Im Beispiel wird die Adresse 1 angesprochen. Dezimal 1 entspricht Binär 000 0001.

Meine anfängliche Vermutung, daß die Behauptung, die Initialisierung findet mit 7O1 statt (also 7 Daten-Bit, einer ungeraden (Odd) Parität und einem Stop-Bit), nicht stimmt, hat sich bei genauer Anaylse als falsch erwiesen. Die für die jeweiligen Adressen benötigte Signalform wird genau eingehalten, wobei bei der seriellen Übertragung zuerst das niederwertige Bit des Datenwortes gesendet wird. Beispielsweise für Adresse 1:
1->0 1000 000 0 1 = 1 Start-Bit (Wechsel von 1 auf 0), 7 Daten-Bits; 0 weil ungerade Parität erfüllt ist; 1 Stop-Bit

Auf der sicheren Seite ist, wer ein Oszilloskop nutzen kann. Vorteilhaft ist ein Speicheroszilloskop, da man bei der extrem niedrigen Übertragungsrate und des nur einmalig anliegenden Signals sonst nichts erkennt. Die Abbildung zeigt den Signalverlauf auf meinem Hameg 205-3. Das Signal wurde direkt an der K-Line, also hinter Jeffs Interface abgegriffen, da die verschiedenen seriellen Schnittstellen unterschiedlich saubere Signale liefern, die bei der Analyse irritieren, wenn man das Signal am Eingang von Jeffs Interface abgreift. Die Initialisierungsphase wurde rot hervorgehoben:

Signalverlauf

Die darauf folgenden Signalspitzen sind auf die anschließende Kommunikation mit höherer Baudrate nach dem wake up zurückzuführen. Deutlich ablesbar sind die Signallängen: Der kurze Wechsel ist je 200ms lang und die längere Phase 1400ms. Die erste Signalflanke High->Low dient als Start-Bit. Um also das Steuergerät sauber zu initialisieren, lohnt es sich, den Signalverlauf zu analysieren und darauf zu achten, daß man die Signalzeiten genau einhält, wenn man die Datenübertragung nicht einem Schnittstellenbaustein überläßt.

Genau das wird auch von meinem Programm im µC gemacht (vergl. Schaltbild): Statt die Adresse des Steuergerätes mit 5Bd über den integrierten seriellen USART Schnittstellenbaustein zu generieren, wird die TxD Datenleitung (PD1), die an den T1IN des MAX232 angeschlossen ist, direkt angesteuert, so daß der MAX232 die jeweiligen Signale ausgibt. Zu beachten ist bei der Programmierung noch, daß man vor der Initialisierung eine kurze Wartezeit einlegt, da durch das einschalten des Steuergerätes (Spannungsversorgung) oder vorherige Kommunikationen, noch Daten vom Controller gesendet werden, die man nicht nutzen will.

Die Kommunikation zur Initialisierung sieht folgendermaßen aus:

vom µC von ECU Beschreibung
0x01   5 Baud Adresse des Steuergerätes
  0x55 Sync Byte zum festlegen der Baudrate
  0x01 key word LSB (low significant byte)
  0x8A key word HSB (high significant byte)
0x75   Komplement zur 0x8A

Ein paar Anmerkungen:

  • In dieser und folgenden Tabellen werden Zahlen stets in hexadezimaler schreibweise angegeben. Um dies zu verdeutlichen wird die C-Schreibweise 0x?? gewählt. Zahlen in normaler schrweibweise sind Dezimalzahlen. Der Windows Taschenrechner kann in der wissenschaftlichen Ansicht zwischen Dezimal, Hexadezimal und Binär umrechnen.
  • Um dem sendenden Gerät den korrekten Empfang eines Bytes zu signalisieren wird häufig dessen Komplement zu 0xFF zurückgeschickt. Dazu wird von 0xFF der empfangene Wert abgezogen. Beispielsweise 0xFF - 0x8A = 0x75 (255 - 138 = 117).
  • Bereits das erste Byte welches vom Steuergerät (im folgenden oft der einfachheithalber ECU genannt) gesendet wird, wird mit der hohen Baudrate und 8N1 gesendet.
  • Die Kommunikation findet meist im Wechsel statt. Der eine sendet, der andere bestätigt den korrekten Empfang mit dem Komplement. Nach dem ein Kommunikationsblock abgearbeitet wurde, beginnt der andere die Kommunikation.
  • Jedes vom µC gesendete Zeichen wird mit einem ECHO quittiert. Das bedeutet, das gesendete Zeichen wird automatisch an den Sender zurück geschickt. Dabei hat das Steuergerät nicht die Finger im Spiel und die Echos gehen stets sofort nach dem Abschicken ein, noch bevor Daten vom Steuergerät kommen. Diese Echos sind einfach zu ignorieren.

Großes Kopfzerbrechen hat mit die Baudrate nach der Initialisierungsphase gemacht. Ich ging davon aus, daß dies stets 9600 Baud ist. Dem ist nicht so. 9600 ist wohl nur weit verbreitet aber prompt nutzte meine ECU 10400 Baud. Da ich die falsche Baudrate gewählt hatte, kam nur Datenschrott statt der drei Bytes 0x55, 0x01 und 0x8A an. Erst als ich nach Tagen 10400Bd ausprobierte, klappte alles auf Anhieb. Deshalb ist es unumgänglich, die Baudrate zu ermitteln. Das geht sehr gut, in dem man die 5Bd Adresse an die ECU schickt und dann die Antwort bei 4800Bd empfängt. Ist es nicht 0x55, 0x01 und 0x8A, dann noch mal die Adresse mit 5Bd schicken und mit 9600Bd warten und ggf. anschließend noch mit 10400 Bd. Es kann auch sein, daß es weitere Baudraten gibt - über Infos freue ich mich.

KW1281 - Timing

Noch mehr Kopfzerbrechen als die Baudrate, hat mir das Timing bereitet. Wie erwähnt, traten bei mir verstärkt Kommunikationsprobleme auf, die ich nicht in den Griff bekam. Meine Tisch-ECU nutzt 10400Bd und zeigte keine Fehler. Nur die im Auto (9600Bd) produzierte Fehler. Wie ich schon mal bemerkte, ist der µC mit 8MHz relativ schnell im Vergleich zu einem modernen PC, der mehr damit beschäftigt ist, Windows-Elemente neu zu malen. Deshalb wurde die Problematik bisher auch meines Wissens nach nirgends dokumentiert.

Die Lösung ist trivial: Ich empfange ein Byte von der ECU und sende sofort eine Antwort oder ein anderes Anforderungs-Byte. Das ist zu schnell. Ich habe leider keine genauen Angaben über die Zeitabstände. Nach dem ich aber vor jedem zu sendenden Byte eine Pause von 5ms einlege, steht die Verbindung absolut fehlerfrei. Der Interrupt-gesteurte Puffer sorgt dafür, daß keine Daten verloren gehen. Wie es aussieht ist die ECU mit 10400Bd also schnell genug gewesen, um die Daten von meinem µC abzunehmen, was die 9600er nicht schaffte.

Andererseits darf die Pause auch nicht zu groß werden. Nach einer mir unbekannten Zeit (schätzungsweise <500ms) wird die Verbindung zur ECU abgebrochen.

KW1281 - Gerätedaten

Nach dem das Steuergerät bereit ist, startet die Übertragung der Gerätespezifikation. Hierbei meldet sich der Controller mit der VAG Nummer, der Gerätebezeichnung usw. VAG-COM stellt teilweise mehr Daten da, als das Gerät anscheinend liefert. Die gelieferten Daten sind meiner Meinung nach auch nicht ganz so spannend, so daß kleine Unstimmigkeiten ignoriert werden können. Wichtig ist, daß die Kommunikation zügig abläuft, da das Steuergerät nicht gerne wartet. Da zuvor der µC die Kommunikation begonnen hatte, ist nun die ECU dran und der µC ist nur damit beschäftigt, die Daten anzunehmen und mit dem Komplement zu bestätigen.

Zuerst wird die VAG-Nummer bzw. Controller ID übertragen (in diesem Fall "030906032E  "):

vom µC von ECU Beschreibung
  0x0F block length (s. u.); ECU ist Master
0xF0   Komplement
  0x01 block counter (s. u.)
0xFE    
  0xF6 block title (s. u.)
0x09    
  0x30 ASCII Wert für "0"
0xCF    
  0x33 "3"
0xCC    
  0x30 "0"
0xCF    
  0x39 "9"
0xC6    
  0x30 "0"
0xCF    
  0x36 "6"
0xC9    
  0x30 "0"
0xCF    
  0x33 "3"
0xCC    
  0x32 "2"
0xCD    
  0x45 "E"
0xBA    
  0x20 " " (Leerzeichen)
0xDF    
  0x20 " "
0xDF    
  0x03 block end (s. u.)

Ein paar Hinweise zu einzelnen Werten:

  • block length gibt die Anzahl der folgenden Daten-Bytes an. Inklusive des Bytes block length aber ohne das Byte block end.
  • block counter wird mit jedem Kommunikationsblock (egal, ob von der ECU oder dem µC) um eins inkrementiert. Nach 0xFF wird er auf 0x00 gesetzt.
  • block title signalisiert, um was für Daten es sich in diesem Kommunikationsblock handelt.
    • 0x05 - clear errors, alle Fehler löschen
    • 0x06 - end output, Ende der Kommunikation
    • 0x07 - get errors, alle Fehler ausgeben
    • 0x09 - ack command
    • 0x29 - group reading
    • 0xE7 - Antwort auf group reading Aufforderung
    • 0xF6 - ASCII Daten
    • 0xFC - Antwort auf get errors Aufforderung
  • block end ist das einzige Byte, das nicht mit einem Komplement beantwortet wird und welches das Ende eines Kommunikationsblocks anzeigt.
Nun ist der µC wieder an der Reihe. Er hat keine andere Wahl, als einen Bestätigungsblock (ack command) zu schicken und die ECU bestätigt die einzelnen Bytes mit dem Komplement:

vom µC von ECU Beschreibung
0x03   block length; µC ist Master
  0xFC Komplement
0x02   block counter
  0xFD  
0x09   ack command
  0xF6  
0x03   block end

Jetzt ist wieder die ECU an der Reihe. Genau wie zuvor schon schickt sie jetzt den nächsten Datenblock (block counter = 3). In diesem Datenblock wird die Bauteilbezeichnung angegeben. Dies kann z. B. "ME7.5.10            " sein.

Anschließend schickt der µC wieder einen ack block (block counter = 4).

Dieses Spiel wiederholt sich so lange, wie das Steuergerät Daten preis geben will. In der Regel sind es insgesamt vier Datenblöcke: VAG-Nummer, Bauteilbezeichnung, Software Version (z. B. "3013") und Händlerbezeichnung. Eventuell folgen aber noch weitere Zusatzdaten.

Bei all diesen Angaben kann es sein, daß einzelne Bytes geliefert werden, die keinem ASCII-Zeichen entsprechen, so daß die Infos von denen von VAG-COM abweichen, zudem ich davon ausgehe, daß VAG-COM die empfangenen Daten auswertet und etwas aufbereitet, was man schon an der Darstellung der VAG-Nummer erkennen kann.
Unter anderem kann die ECU anstatt eines ASCII-Wertes 0x00 liefern, was als cut-off signal bezeichnet wird. Was es damit auf sich hat, weiß ich nicht. Ich ersetze einfach alle empfangenen Zeichen-Werte außerhalb des ASCII-Bereiches von 0x21-0x7A durch 0x3F ("?").

Auf den letzten Kommunikationsblock der ECU reagiert der µC wie gewohnt mit einem ack block. Wenn die ECU dann keine weiteren Daten senden will, schickt sie nun selber einen ack block:

vom µC von ECU Beschreibung
  0x03 block length; ECU ist Master
0xFC   Komplement
  0x?? block counter (Wert je nach Anzahl der bisher ausgetauschten Blöcke)
0x??   Komplement des block counter (Wert je nach Anzahl der bisher ausgetauschten Blöcke)
  0x09 ack command
0xF6    
  0x03 block end

Jetzt ist die Reihe wieder am µC. Dieser schickt einfach einen ack block, um die Datenverbindung aufrecht zu halten. Die ECU sendet dann wieder einen ack block, dann der µC usw. bis in alle Ewigkeit. Schickt der µC keinen ack block bricht die ECU die Verbindung alsbald ab und es muß wieder mit einer 5Bd Initialisierung begonnen werden. Während der folgenden Phasen kann der µC auch jederzeit statt einer Datenanforderung o. ä. einen ack block senden, woraufhin die ECU mit einem ack block antwortet.

KW1281 - Sensordaten

Anstatt die Datenverbindung durch den endlosen Austausch von ack blocks aufrecht zu erhalten, kann der µC auch die Initiative ergreifen und Meßwerte bzw. Sensordaten anfordern. Anstatt eines ack blocks sendet er dann, wenn er an der Reihe wäre, ein group reading.

Bevor wir einen Blick auf das Protokoll werfen, zuerst einmal ein paar Infos zum Verständnis: Per group reading wird das Steuergerät aufgefordert vier Meßwertblöcke zu liefern. Dabei gibt es Gruppen von 1 bis 255. Welche vier Meßwerte in einer Gruppe geliefert werden ist unterschiedlich und je nach Modell des Steuergerätes anders. Es kann vorkommen, daß ein Meßwertblock keine Angaben enthält und in einer Gruppe können die gleichen Meßwerte geliefert werden, wie in einer anderen. Das kann praktisch sein, denn so kann man schauen, ob es eine Gruppe gibt, in der vier gewünschte Meßwerte geliefert werden. Ansonsten ist es aber kein Problem, beliebig viele Gruppen abzufragen. Vor den Meßwerten wird immer die Kennzahl für den Meßwerttyp übermittelt. Die Kennzahl hat abhängig vom Steuergerät (und eventuell auch der Gruppe (noch nicht geprüft)) in der sie vorhanden ist, eine andere Bedeutung hat. So kann zum Beispiel die gleiche Kennzahl einmal für die Außentemperatur und einmal für die Öl-Temperatur stehen. Die Meßwerte sind stets in zwei Bytes aufgeteilt. Erst durch eine Rechenoperation wird aus den zwei Bytes der tatsächliche Meßwert. Je nach Sensortyp ist die Rechenoperation eine andere.
Dies ist deshalb auch der "spaßige" Teil: Es gilt für jedes Steuergerät individuell herauszufinden, welche Daten je Gruppe geliefert werden und wie diese zu berechnen sind.

Wie immer gibt es ein paar Infos im Netz, die lückenhaft sind und von mir so weit wie möglich ergänzt sind - über Zusatzinfos freue ich mich mal wieder! Die folgende Tabelle (basierend auf der Datei Value-calculation.txt aus der Yahoo! Gruppe opendiag) zeigt die Kennzahlen für die Sensordaten (1. Byte) und deren Umrechnung, wobei a für das erste Meßwert-Byte (2. Byte) steht und b für das zweite Byte (3. Byte). Alle Angaben sind noch unbestätigt. Lediglich die mit einem √ in der Spalte Bedeutung versehenen sind von mir geprüft.

Kennzahl Bedeutung Berechnung Einheit
1: ECU 23: Instruments
1 Motordrehzahl √ Motordrehzahl √ 0.2*a*b rpm
2 Absolute Drosselklappenstellung (???)   a*0.002*b %
3     0.002*a*b Deg
4     abs(b-127)*0.01*a "ATDC" if Value >127, else"BTDC"
5 Öl-Temperatur √ Außentemperatur √ a*(b-100)*0.1 oder 0.1*a*b - 10*a °C (beide Formeln scheinen OK zu sein)
6 Versorgungsspannung ECU (= Batterie) √ Versorgungsspannung ECU (= Batterie) √ 0.001*a*b V
7 Fahrzeuggeschwindigkeit √ Fahrzeuggeschwindigkeit √ 0.01*a*b km/h
8 Bit Value Cruise Control???    0.1*a*b (no units)
9     (b-127)*0.02*a Deg
10     if b==0 then "COLD", else"WARM"  
11     0.0001*a*(b-128)+1 -
12     0.001*a*b Ohm
13     (b-127)*0.001*a mm
14     0.005*a*b bar
15 CAN Bus Status???   0.01*a*b ms
16 Bin. Bits   ??? bitvalue
17 ???   chr(a) chr(b) -
18 Absolute Pressure, Atmospheric,Pressure, Intake Manifold,Pressure   0.04*a*b mbar
19   Tankinhalt √ a*b*0.01 l
20     a*(b-128)/128 %
21 Modul. Piston,Movement Sender (???) Voltage   0.001*a*b V
22     0.001*a*b ms
23 EGR Valve, Duty Cycle / Inj. Timing ???   b/256*a %
24     0.001*a*b A
25     (b*1.421)+(a/182) g/s
26     b-a C
27 Ign. Timing Calculated/Actual ???   abs(b-128)*0.01*a ° ("ATDC" if Value <128, else"BTDC" ???)
28     b-a -
29 Kennfeld   if b<a then "1.Kennfeld"else "2.Kennfeld"  
30     b/12*a Deg k/w
31 Preheating,Time ???   b/2560*a °C
32 ???   if b>128 : b-256 else b -
33 Stellung Gaspedal √   100*b/a  (if a==0 then 100*b) %
34     (b-128)*0.01*a kW
35 Treibstoff-Verbrauch √   0.01*a*b l/h
36   Ges. Laufleistung (letzte Stelle gerundet) √ a*2560+b*10 km
37   Öldruck (???) ??? "Oil Pr. 2 < min"
38     (b-128)*0.001*a Deg k/w
39 Inj. Quantity Driver Request/Torque Limitation/Smoke Limitation [bei T4 5,8mg/h im Leerlauf]   b/256*a mg/h
40     b*0.1+(25.5*a)-400 A
41     b+a*255 Ah
42     b*0.1+(25.5*a)-400 Kw
43     b*0.1+(25.5*a) V
44   Uhrzeit √ a : b h:m
45     0.1*a*b/100  
46     (a*b-3200)*0.0027 Deg k/w
47     (b-128)*a ms
48     b+a*255 -
49 Mass Air/Rev. oder Air Mass,Calculated oder Air Mass,Actual???   (b/4)*a*0,1 mg/h
50 ???    (b-128)/(0.01*a), if a==0 (b-128)/0.01 mbar
51 ???   ((b-128)/255)*a mg/h
52     b*0.02*a-a Nm
53 Luftdurchfluß Luftmassenmesser (???)   (b-128)*1.4222+0.006*a g/s
54     a*256+b Count
55     a*b/200 s
56     a*256+b WSC
57     a*256+b+65536 WSC
58     1.0225*b, if b>128 then 1.0225*(256-b) \s
59     (a*256+b)/32768 -
60     (a*256+b)*0.01 sec
61     (b-128)/a, if a==0 (b-128) -
62     0.256*a*b S
63 Text   chr(a) + chr(b) + "?" -
64   Widerstand √ a+b Ohm
65     0.01*a*(b-127) mm
66     (a*b)/511.12 V
67     (640*a)+b*2.5 Deg
68     (256*a+b)/7.365 deg/s
69     (256*a +b)*0.3254 Bar
70     (256*a +b)*0.192 m/s2

Will man nun wissen, welche Meßwerte in welcher Gruppe geliefert werden, kann man einfach nacheinander alle 256 Gruppen auslesen und die Kennzahlen notieren. Hilfreich kann aber auch VAG-COM sein. Liest man das Steuergerät mit VAG-COM aus, kann man auf die Schaltfläche Meas. Blocks - 08 klicken und dann nacheinander genau die Gruppen durchklicken und die jeweiligen vier Sensordaten ablesen. Alternativ kann man auch die Labelfiles studieren, die sich auch im Unterordner Labels befinden. Anhand der VAG-Nummer kann man die entsprechende Datei identifizieren. Dabei gibt es aber mir teilweise unklare Konventionen, denn zum einen gibt es redirects für Steuergerätenummern und für meine getesteten Steurgeräte gab es keine Labelfiles, obwohl VAG-COM die Bezeichner kannte. Hat man aber das passende Labelfile, findet man in dieser Textdatei Angaben über die Gruppen und die gelieferten Daten. Beispielsweise 022-906-032-AYL.lbl:

002,0,Basic Functions (Mass Air Flow)
002,1,Engine Speed,,Specification: 650...750 RPM
002,2,Engine Load,,Specification: 12.0...26.0 %
002,3,Injection,Timing,Specification: 1.0...4.0 ms
002,4,Intake Air Mass,,Specification: 2.5...5.0 g/s
Hierbei handelt es sich um die Gruppe mit der Kennzahl 2. Nach dem Komma werden die vier Datenblöcke unterteilt. 0 gibt es nicht und ist nur eine Kategoriebezeichnung für VAG-COM. Das erste Byte liefert die Engine Speed (Motordrehzahl), das zweite Byte dann den Ladedruck usw.

Die Kennzahl 16 liefert einen Binärwert. Teilweise findet man in den Labelfiles die Bedeutung der einzelnen Bits. Beispielsweise für die zweite Gruppe in 074-906-018.lbl:

; Measuring block 002 - Idle
2,1,Engine,Speed
2,2,Accelerator,Position
2,3,Operating,Condition 1)
2,4,Coolant,Temperature
;
;	1) 010-OK
; 	   011-Air Conditioning switched on
Der dritte Datenblock liefert einen Bytewert, der in der Binärdarstellung u. a. angibt, ob die Klimaanlage an ist.

Wenn die Reihe wieder am µC ist, kann dieser wie gesagt auch ein group reading statt des ack blocks schicken:

vom µC von ECU Beschreibung
0x04   block length; µC ist Master
  0xFB Komplement
0x??   block counter
  0x?? Komplement
0x29   block title (group reading)
  0xD6  
0x02   group Kennzahl (0x01 bis 0xFF) die gelesen werden soll
  0xFD  
0x03   block end

Hierauf antwortet die ECU beispielsweise (ECU 030-906-032E):

vom µC von ECU Beschreibung
  0x0F block length; ECU ist Master
0xF0   Komplement
  0x?? block counter
0x??   Komplement
  0xE7 block title (Antwort auf group reading)
0x18    
  0x01 Kennzahl für 1. Datenblock
0xFE    
  0xC8 1. Sensordaten-Byte = Meßwert a
0x37    
  0x00 2. Sensordaten-Byte = Meßwert b
0xFF    
  0x21 Kennzahl für 2. Datenblock
0xDE    
  0x85 1. Sensordaten-Byte = Meßwert a
0x7A    
  0x85 2. Sensordaten-Byte = Meßwert b
0x7A    
  0x0F Kennzahl für 3. Datenblock
0xF0    
  0x29 1. Sensordaten-Byte = Meßwert a
0xD6    
  0x00 2. Sensordaten-Byte = Meßwert b
0xFF    
  0x12 Kennzahl für 4. Datenblock
0xED    
  0xFA 1. Sensordaten-Byte = Meßwert a
0x05    
  0x5A 2. Sensordaten-Byte = Meßwert b
0xA5    
  0x03 block end

Anschließend kann der µC ein weiteres group reading für eine beliebige Gruppe anfordern.
Völlig zur Verzweifelung hat mich getrieben, daß die ECU aus meinem Bus während des group readings nach einigen (unterschiedlich häufigen) erfolgreichen group readings ein Byte 0x0F schickt, nach dem der µC an der Reihe war und das Byte für die block length geschickt hat. Scheint ein Fehler zu sein, denn es trat nur auf, wenn der Motor lief und nicht, wenn nur die Zündung ein war. Anschließend ist die Kommunikation beendet und man muß wieder mit der Initialisierung beginnen. Inzwischen habe ich das als Timing-Problem erkannt.

Im Beispiel sendete die ECU folgende Daten für die zweite Gruppe, die dann umgerechnet werden können:

Kennzahl Meßwert a Meßwert b Berechnung (vgl. oben) Ergebnis
1 200 0 a*0.2*b 200*0,2*0 = 0 rpm
33 133 133 100*b/a (if a==0 then 100*b) 100*133/133 = 100%
15 41 0 0.01*a*b 0,01*41*0 = 0ms
18 250 90 0.04*a*b 0,04*250*90 = 900Mbar

Als Beispiel eine Auflistung der ersten 26 groups, wie sie die ECU (074 906 018 A) aus meinem T4 111KW liefert:

group # 1. Kennzahl 2. Kennzahl 3. Kennzahl 4. Kennzahl
1 1 39 21 5
2 1 33 16 5
3 1 49 49 23
4 1 27 27 23
5 1 39 27 5
6 7 16 16 8
7 5 17 5 5
8 1 39 39 39
9 1 39 39 17
10 49 18 18 33
11 1 18 18 23
12 16 31 6 5
13 51 51 51 51
14 51 17 17 17
15 1 39 35 39
16 2 16 16 6
17 17 17 17 17
18 7 16 7 7
19 21 21 17 17
20 1 39 21 33
21 49 49 23 16
22 27 27 23 7
23 18 18 23 18
24 5 5 5 8
25 17 17 17 17
26 63 50 53 17

Eine Gesamtübersicht der ersten 128 Byte liegt als Textdatei vor. Es können also die Meßwerte für die Kennzahlen 1, 2, 5, 6, 7, 8, 15, 16, 17, 18, 21, 23, 27, 31, 32, 33, 35, 39, 49, 50, 51, 53, 63 abgefragt werden.

Interessant ist auch der Umstand, daß andere Steuergeräte die gleiche obige Tabelle mit den Kennzahlen verwenden. Liest man beispielsweise mein T4 Steuergerät Kombiinstrument (7D0 920 823 C) aus (Adresse 0x17), bekommt man für die ersten beiden groups die Kennzahlen 7, 1, 37, 44 und 36, 19, 64, 5 geliefert. Textdatei mit allen Werten.

KW1281 - Kommunikationsende

Soll die Datenverbindung beendet werden, weil der µC die Kommunikation einstellen möchte, sollte man einen sauberen end output block schicken:

vom µC von ECU Beschreibung
0x03   block length; µC ist Master
  0xFC Komplement
0x??   block counter
  0x?? Komplement
0x06   block title (end ouput)
  0xF9  
0x03   block end

Anschließend kann ein Steuergerät bei Bedarf wieder mit der gewohnten 5Bd Initialisierung aufgeweckt werden.

KW1281 - Kommunikationsfehler

Wie schon geschildert, kann es während der Kommunikation seitens der ECU zu Fehler kommen. Noch nicht ganz sicher bin ich mir beim Ablauf, wie auf einen solchen Fehler reagiert wird. Ich habe zwei Arten von Fehlern protokollieren können, die beide nur bei wiederholten group readings auftraten. Der Fehler wird wohl durch zwei gleiche Bytes zur Fehlersignalisierung markiert. Allerdings werden unterschiedliche Bytes gesendet. Bisher scheint sich folgendes Bild abzuzeichnen:

vom µC von ECU Beschreibung
  0x?? beliebiges Byte
  0x0F oder 0x27 1. Byte zur Fehlerkennzeichnung (?). 0x0F nach dem zuvor 0x05 gesendet wurde. 0x27 nach 0x57
  0x0F oder 0x27 2. Byte zur Fehlerkennzeichnung (?)
0x??   Komplement zum letzten Byte (2. Fehlerbyte)
  0x55 Sync Byte zum festlegen der Baudrate (Bedeutung unklar)
  0x01 key word LSB (low significant byte) (Bedeutung unklar)
  0x8A key word HSB (high significant byte) (Bedeutung unklar)
0x75   Komplement zu 0x8A

Wie man sieht, schickt die ECU nach Signalisierung des Fehlers die drei Bytes wie bei der Initialisierung. Durch diese Aktion wird der block counter auf Null zurückgesetzt. Der nächste von der ECU gesendete Block beginnt mit dem block counter Wert 1.

Es folgt eine ähnliche Phase wie nach der Initialisierung:

  1. Die ECU schickt einen 0xF6 ASCII Daten Block mit der Controller ID und weiteren ASCII Zeichen, deren Bedeutung ich noch nicht untersucht habe.
  2. Der µC bestätigt mit einem ACK block
  3. Die ECU schickt einen weiteren 0xF6 ASCII Daten Block mit weiteren ASCII Zeichen.
  4. Der µC bestätigt mit einem ACK block
  5. Die ECU schickt einen weiteren 0xF6 ASCII Daten Block mit weiteren ASCII Zeichen.
  6. Der µC bestätigt mit einem ACK block
  7. Die ECU schickt einen weiteren 0xF6 ASCII Daten Block mit weiteren ASCII Zeichen.

Jetzt kommt etwas merkwürdiges. Statt eines ACK block schickt der µC:

vom µC von ECU Beschreibung
0x03   block length; µC ist Master
  0xFC Komplement
0x08   block counter
  0xF7 Komplement
0x00   Was auch immer dies bedeutet
  0xFF Komplement
0x03   block end

Anschließend sendet die ECU wieder einen 0xF6 ASCII Daten Block mit weiteren ASCII Zeichen. Dies scheint dann der letzte zu sein, denn jetzt beginnt wieder das Wechselspiel, bei dem zuerst der µC einen ACK block und dann die ECU einen sendet, bis der µC einen anderen Befehl schickt.

KW1281 - Fehlerspeicher auslesen/löschen

Folgend noch die Vorgehensweise zum Auslesen von Fehlern und das Löschen. Zuerst fordert der µC alle Fehlercodes an. Eine Möglichkeit, nur die Anzahl der gespeicherten Fehler zu erfragen, scheint es nicht zu geben.

vom µC von ECU Beschreibung
0x03   block length; µC ist Master
  0xFC Komplement
0x??   block counter
  0x?? Komplement
0x07   block title (get errors)
  0xF8  
0x03   block end

Nun sendet die ECU alle gespeicherten Fehlercodes. In der ersten Antwort werden maximal vier Fehlercodes gesendet.

vom µC von ECU Beschreibung
  0x0F block length; ECU ist Master
0xF0   Komplement
  0x?? block counter
0x??   Komplement
  0xFC block title (Antwort auf get errors)
0x03    
  0x46 1. Fehlercode High Byte
0xB9    
  0x5A 1. Fehlercode Low Byte
0xA5    
  0xA3 1. Fehlercode Status-Byte
0x5C    
  0x40 2. Fehlercode High Byte
0xBF    
  0x71 2. Fehlercode Low Byte
0x8E    
  0x23 2. Fehlercode Status-Byte
0xDC    
  0x46 3. Fehlercode High Byte
0xB9    
  0x1E 3. Fehlercode Low Byte
0xE1    
  0x23 3. Fehlercode Status-Byte
0xDC    
  0x46 4. Fehlercode High Byte
0xB9    
  0x20 4. Fehlercode Low Byte
0xDF    
  0x23 4. Fehlercode Status-Byte
0xDC    
  0x03 block end

Die jeweils beiden ersten Bytes eines jeden Fehlercodes werden hintereinander gesetzt und interpretiert. Aus beispielsweise 0x46 und 0x5A ergibt sich 0x465A. Dies entspricht Dezimal 18010 und gibt den Volkswagen Diagnostic Trouble Code (DTC) an.

Das dritte Fehler-Byte (Status-Byte) beschreibt den Fehler näher und gibt z. B. an, ob der Fehler nur sporadisch auftritt oder in welcher Form das Signal abweicht.

Für obiges Beispiel kann man so feststellen, daß der zweite gemeldete Fehler 0x4071 (16497) heißt und dies bedeutet Intake Air Temp.Circ High Input (Einlaß Lufttemperatur Schaltkreis zu hoher Eingang).

Nach dem der erste Block mit den Fehlern geschickt wurde, antwortet der µC mit dem üblichen ack block. Wenn weitere Fehler vorliegen, schickt die ECU dann einen weiteren Block mit dem block title 0xFC. Dieser kann kürzer sein, wenn z. B. nur noch drei Fehler folgen (0x0C für block length). Darauf reagiert der µC wieder mit einem ack block und die ECU schickt ggf. weitere Fehler oder antwortet selber mit einem ack block, wenn keine weiteren Fehler vorliegen.

Sind keine gespeicherten Fehler vorhanden sieht die Antwort der ECU folgendermaßen aus:

vom µC von ECU Beschreibung
  0x06 block length; ECU ist Master
0xF9   Komplement
  0x?? block counter
0x??   Komplement
  0xFC block title (Antwort auf get errors)
0x03    
  0xFF kein Fehler vorh. (1. Fehlercode High Byte)
0x00    
  0xFF kein Fehler vorh. (1. Fehlercode Low Byte)
0x00    
  0x88 kein Fehler vorh. (1. Fehlercode Daten-Byte)
0x77    
  0x03 block end

Ist man sich sicher, daß die gespeicherten Fehler gelöscht werden können, ist dies ebenfalls möglich:

vom µC von ECU Beschreibung
0x03   block length; µC ist Master
  0xFC Komplement
0x??   block counter
  0x?? Komplement
0x05   block title (clear errors)
  0xFA  
0x03   block end

Darauf reagiert die ECU mit einem normalen 0x09 ACK block. Daraufhin kann dann der µC wieder wie gewohnt Befehle senden. Sinnvoll könnte es zum Beispiel sein, anschließend noch einmal den Fehlerspeicher auszulesen, um zu überprüfen, ob das Löschen geklappt hat.