Reverse Engineering des Batterie-Sensors

  • Rhein theoretisch, wenn man jetzt Sniffer mit ELM config laufen lässt mit log Ausgabe@Go4IT und z. B. Battery reset auslöst in dem Moment, würde dir das weiterhelfen bei deinem Projekt!?

    Oder welche Info wäre für dich interessant, wenn man einen Sensor von Werk aus verbaut hat?

    Einmal editiert, zuletzt von veni40 (8. Februar 2026 um 16:52)

  • Da ich aktuell noch nicht weis wie und wo sich die Daten des Batteriesensors im CAN tummeln, wäre das noch zu früh. Ich muss erstmal den Sensor auf dem LIN eindeutig identifizieren und seine Kommunikationen mitlesen. Dann kenne ich seine Daten und kann danach auf dem CAN suchen um der Sache näher zu kommen.

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Sodale, mein LIN Sniffer Code nimmt langsam Form an. Nachdem ich ein paar Bugs finden und beheben konnte scheine ich nun beliebige LIN Frames, beantwortete und unbeantwortete, sniffen zu können. Das bishere Ergebnis (mit noch ein paar Debug-Logs) sieht so aus:

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Ich habe auch mit nachgerüstetem und per CCC aktiviertem Batteriesensor keine weiteren PIDs mit im BCMii bei ForScan als ich ohne hatte.

    Seit dem Wissen um diese Info hier, dass es mit dem Batteriesensor dieses Zusatz-Steuergerät gab, ist die Annahme wahrscheinlich falsch, die Batterie-Sensor-bezogenen Daten im BCM zu finden. Nun fragt sich, wie dieses zusätzliche Modul dann aber in ForScan heißt. Oder bei Vorhandensein des zusätzlichen Moduls erscheinen dann im BCM weitere Daten.

    Mondeo Turnier 2.0 FFV Titanium, Thunder, ACC, IVDC, Bi-Xenon, KeyFree+PowerStart, Alarmanlage, Solarreflect, PDC vorn u. hinten, TPMS, Sitzklima, Luftqualitätsmesser+kühlbares Handschuhfach, Sony-6CD, Bluetooth-FSE incl. S&C, Außenspiegel anklappbar, silberfarbene Dachreling, Notrad incl. Wagenheber

    Selbsteinbau: Rückfahr- u. Front-Kamera mit 9" TFT-Monitor in der Sonnenblende, Ambiente-Beleuchtung in den Türgriffmulden, Rückstrahler an allen 4 Türen beleuchtet

    Baumonat 10/2008

  • Die ID 0x2B scheint recht sicher dem Batteriesensor zuordenbar zu sein ("AG9N-10C679-DE"):

    Code
    I (6767) LIN_SNIFFER: Valid frame (Classic) - ID: 0x2B, Data len: 8
    I (6773) LIN_SNIFFER: 02 41 47 39 4E 00 00 00                         | .AG9N...
    ...
    I (7251) LIN_SNIFFER: Valid frame (Classic) - ID: 0x2B, Data len: 8
    I (7257) LIN_SNIFFER: 03 31 30 43 36 37 39 00                         | .10C679.
    ...
    I (7689) LIN_SNIFFER: Valid frame (Classic) - ID: 0x2B, Data len: 8
    I (7695) LIN_SNIFFER: 04 44 45 00 00 00 00 00                         | .DE.....

    Wobei die ID 0x35 ganz sicher dem Regensensor gehört ("BV6T-17D547-AD"):

    Code
    I (6914) LIN_SNIFFER: Valid frame (Classic) - ID: 0x35, Data len: 8
    I (6920) LIN_SNIFFER: 02 42 56 36 54 00 00 00                         | .BV6T...
    ...
    I (7357) LIN_SNIFFER: Valid frame (Classic) - ID: 0x35, Data len: 8
    I (7363) LIN_SNIFFER: 03 31 37 44 35 34 37 00                         | .17D547.
    ...
    I (7796) LIN_SNIFFER: Valid frame (Classic) - ID: 0x35, Data len: 8
    I (7802) LIN_SNIFFER: 04 41 44 00 00 00 00 00                         | .AD.....

    Die erste Ziffer gibt also den Index an, so wie bei CAN TP (Segmentierte Nachricht, eben eine die nicht in eine Payload passt, also größer als 8 Byte ist) mit "FF - First Frame" und "CF - Consecutive Frames". Wo aber ist wohl das First-Frame welches den Index 0x01 hat?

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Mein Sniff war jetzt recht kurz (5 Sekunden) daher fehlen sicher IDs, aber hier schonmal was ich bislang finden konnte:

    IDPIDLENDATAFreq./PeriodMultiframesSENDERMEANING
    0x044FF 89 3A B5
    FF 90 3C BC
    4BAT-SENS
    0x05240 025 Hz / alle 100 bzw. 200 ms2RAIN-SENSStatus des Regensensors
    0x06200 00 2
    0x08-- -Unanswered
    0x0D498 1F C2 1E
    0E 1E BF 1E
    58 1F C0 1E
    00 20 C9 52
    4BAT-SENSVermutlich Stromfluss
    0x0E400 B2 0F FF
    00 B2 19 FF
    4BAT-SENSVermutlich Spannung
    0x0F49D 7C AE 18
    CD 8D B5 FF
    4BAT-SENS
    0x10200 2A
    00 4A
    00 0A
    2
    0x174B9 C7 E8 C3
    00 C0 00 C0
    4BAT-SENS
    0x19-- -Unanswered
    0x20 84 80 00 00
    84 80 01 00
    94 80 01 00
    94 82 03 00
    94 82 02 00
    4
    0x21-- -Unanswered
    0x22250 00 2BAT-SENS
    0x26 87 C3 6C C2
    00 C0 00 C0
    01 C0 00 C0
    4BAT-SENS
    0x27 FF FF FF FF
    00 F0 FF FF
    01 F0 FF FF
    4BAT-SENS
    0x2A-FF FF FF FF FF FF 8BAT-SENSUnanswered
    0x2B <#> <CHAR..> 8BAT-SENSBattery-Sensor, Ford-Part-Number (e.g. "AG9N-10C679-DE")
    0x358<#> <CHAR..> 8RAIN-SENSRain-Sensor, Ford-Part-Number (Original "6G9N-17D547-AD", bei Austausch ggf. auch "BV6T-17D547-AD")
    0x3C800 00 00 00 00 00 00 00-1ALL SLAVES"GO-TO-SLEEP" - Wird vom Master gesendet um alle Slaves in den Schlafmodus zu versetzen. Laut Standart ist das erste Byte 0x00 und die restlichen 0xFF, es kommt aber nur auf das erste Byte an.
    Wird vom BCM wenige Sekunden nach Zündung aus gesendet.

    SENDER gibt an, wer die Daten übermittelt, der Master oder der Slave.

    Ich weiß ja welche Module auf diesem LIN-Bus sein können:

    BCMLIN2 (=LIN8)IMSINTERIOR MOTION SENSOR - Innenraum-Bewegungsmelder der Alarmanlage
    BCMLIN8 (=LIN8)WMMSMART WIPER MOTOR MODULE MASTER - Scheibenwischermotor
    BCMLIN8 (=LIN2)RSMRAIN SENSOR MODULE - Regensensor
    BCMLIN8 (=LIN2)BBSSIREN CONTROL MODULE - Sirene der Alarmanlage
    BCMLIN2 (=LIN8)BMSBATTERY MONITOR SENSOR - Batteriesensor

    Wobei in meinem Fahrzeug keine Alarmanlage verbaut ist. Könnte aber gut sein das das BCM trotzdem danach "sucht" und die nicht beantworteten IDs die von den fehlenden Modulen sind. Die, die Antwort geben müssen also BMS, RSM und WMM sein.

    Einige IDs scheinen ihre Werte ohne außen erkennbare Aktion zu ändern, das können typische Sensorwerte sein, von Batterie und Regensensor. Die statischen könnten zum WMM gehören, das werde ich vielleicht erkennen wenn ich den Wischermotor mal gezielt auf unterschiedlichen Stufen laufen lasse.

    Ab hier muss ich dann meinen noch recht simplen Sniffer-Code mit einem Analyse-Tool paaren, ggf. kann ich einen Datenstrom für SavvyCAN erzeugen um dann einzelne IDs zu monitoren.

    Multiframe PIDs besitzen eine interne Statemachine. Die Requests müssen innerhalb von ~400ms geschehen, damit es keinen Timeout gibt und wieder mit dem First-Frame begonnen wird.

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Nun habe ich mein Sniffer-Tool verfeinert und es liefert mir über WiFi im CANDUMP Log-Format die LIN-Frames welche ich dann mit SavvyCAN laden und auswerten kann.

    Generelles zum Reverse Engineering eines LIN-Busses

    Auf dem LIN gibt es immer nur einen Master und bis zu 64 Slaves. Dabei kann nur der Master eine Kommunikation starten, die Slaves sind passiv und senden nur wenn die vom Master auf den Bus gelegte ID sie anspricht. Dementsprechend kann eine ID immer nur zu einem Slave gehören. Ein Slave kann aber mehrere IDs haben und sowohl Daten vom Master empfangen als auch welche an diesen übermitteln. Das "Wissen" darüber, welche IDs zu welchem Slave gehören, wie viele Bytes dieser auf einer ID erwartet oder sendet, steckt in einer LDF die aber von keinem Fahrzeughersteller öffentlich verfügbar gemacht wird.

    Die LIN-Kommunikationsart bedingt aber das der Master Sensoren periodisch abfragen muss um eine Zustandsänderung zu erkennen, wohingegen Aktoren nur dann angesprochen werden wenn etwas getan werden soll. Zustandsangaben die die LIN-Slaves ggf. benötigen, sowas wie "Zündung an", "Motor läuft", etc. könnten auch wie Sensoren in einem sehr kurzen Takt ausgegeben werden.

    Die Abfragefrequenz richtet sich dabei nach der zu erwartenden Wertänderung eines Sensors. Der Regensensor z.B. wird sicher recht oft abgefragt, da er blitzschnell auf auf die Scheibe auftreffendes Wasser reagieren muss. Wohingegen der Batteriesensor eher nicht so oft gefragt wird, weil sich die Parameter dort relativ langsam ändern (Strom, Spannung, Ladung, Temperatur, ...).

    Man kann also bereits anhand der Frequenz einer ID einschätzen ob es sich dabei um einen Sensor oder Aktor handelt. Hier mal über ein paar Logs die Zuordnung von LIN ID zu dem Zeitlichen Abstand zwischen zwei auftreten in den Logs:

    GruppeLIN-IDFrequenzBemerkung
    10x06~43 Hz
    20x05~21 Hz
    30x20~11 Hz
    40x0E4 Hz
    50x17, 0x19, 0x21, 0x26, 0x27, 0x2A, 0x2B~3 Hz
    60x08, 0x0D, 0x0F, 0x10~1 Hz

    Auch der Zeitpunkt des Auftretens einer ID lässt Rückschlüsse zu. Nehmen wir den Wischermotor. Der bekommt sicher nur dann einen Befehl wenn er sich in Bewegung setzen soll. D.H. wenn ich eine Aufzeichnung mache in der ich z.B. 3x bewusst den Wischer manuell aktiviere und dabei versuche ein gewisses Timing einzuhalten, dann müsste sich das widerspiegeln. z.B.: 3 Sekunden warten, einmal betätigen, wieder 3 Sekunden warten, wieder einmal betätigen, wieder warten, 3x hintereinander betätigen.

    Bei anderen IDs sind es eher die Daten im Payload die eine Änderung anzeigen, d.h. die ID selbst liegt periodisch an, aber ihre Werteänderung nicht. Beispielsweise der Regensensor. Der wird vermutlich eine "Regenmenge" als Wertebereich (von leichtem Niesel bis Wasserfall reichen) und einen Boolean für Regen/Kein Regen haben. Soweit mir bekannt wird über den Regensensor auch die Lichtautomatik gesteuert, d.H. es wird evtl. noch einen Lichtmengenwert geben. Den Regenwert könnte man mit einer Sprühflasche ändern, den Lichtwert mit einer Taschenlampe.

    Was man bei LIN wohl auch gern findet sind sog. "Rolling Counter" um verlorene Pakete zu erkennen. Dabei wird ein Byte bei jedem Frame um +1 erhöht und läuft bei erreichen von 255 -> 0 über und beginnt von vorn.


    Batteriesensor-ID ermitteln

    Der erste, einfachste Test war ein LIN-ID Vergleich mit und ohne angeschlossenen Batteriesensor (den kann ich ja einfach abziehen) durchzuführen. Das zeigte das die LIN ID 0x0D definitiv zum Batteriesensor gehört:

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Ich habe meinen LIN-Sniffer nun um eine Sendefunktion erweitert. Jetzt wird es interessant. Besonders angenehm ist, das LIN nur dann sendet wenn der Master das tut und nach Zündung aus hält das BCM auf dem LIN-Bus die Füße still. Somit kann ich ungehemmt senden. Wenn natürlich das BCM einige Module vom Strom nimmt habe ich schlechte Karten...

    Zumindest beim Batteriesensor ist das nicht möglich, denn der hängt ja direkt an der Batterie, ohne irgendwelche Kill-Switches dazwischen :) Und von dem kann ich schonmal seine Teilenummer abfragen.

    Code
    HEADER 2B
    HEADER sent for ID 0x2B - watch for RX response
    (1890.789612) lin0 02B#024147394E000000 # RX Classic
    HEADER 2B
    HEADER sent for ID 0x2B - watch for RX response
    (1891.210934) lin0 02B#0331304336373900 # RX Classic
    HEADER 2B
    HEADER sent for ID 0x2B - watch for RX response
    (1891.610417) lin0 02B#0444450000000000 # RX Classic

    Und nun "pinge" ich einfach mal alle IDs durch... mal schauen

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Ich habe meinen Sniffer um eine SCAN-Funktion erweitert, dabei sendet er als LIN-Master die IDs 0x00 - 0x3F auf den Bus. Wenn sich ein Slave angesprochen fühlt sendet er seine Daten zurück. Da der Batteriesensor ja permanent am Strom ist (anders als z.B. der Regensensor oder das BCM) ist auch sein Bus immer aktiv. Also habe ich mal nur den an meinen Sniffer gehangen und somit ist nun klar welche IDs der belegt:

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Es hat jetzt etwas gedauert, auch um div. Auswertungen zu machen, vor allem aber auch um mein Tool zu entwickeln, aber ich denke Spannung und Strom habe ich entschlüsselt.

    Für den Test-Aufbau habe ich den LIN des Batteriesensors vom Fahrzeug getrennt und direkt mit meinem Sniffer-Tool verbunden. Im Tool habe ich eine Funktion "POLL" entwickelt die eine bestimmte ID als Master in einer wählbaren Periode auf den Bus legt. Damit habe ich die ID 0x0D, welche ich in Verdacht hatte Strom und Spannung zu enthalten über fast 2 Stunden mitlaufen lassen, während ich das Fahrzeug nur am Batterieladegerät (CTEK MX5) hatte. Die Spannung habe ich zwischendurch mit einem Fluke Multimeter überprüft und bis auf 0,02V passt sie präzise zur Formel und den Messwerten des Sensors.

    LIN ID 0x0D

    Mein Tool liefert z.B. diesen Frame:

    Code
    (10657.565926) lin0 00D#2520E157 # RX Classic

    Der erste Wert in Klammern ist die Zeit in Mikrosekunden seit dem Start des Sniffers. Die "00D#" zeigt die LIN ID (nicht PID!) an, danach folgend die Bytes in HEX-Paaren. Das "RX Classic" zeigt an das die Prüfsumme des LIN-Frames mit der Classic-Methode berechnet wurde (LIN Standard 1.3). Die Bytes liegen in der Reihenfolge vor wie sie auf den Bus geschickt wurden.

    Strom (1.+2. Byte)

    Der Strom berechnet sich aus dem 1. und 2. Byte im Little-Endian Format. Also muss man aus "2520" ein "2025" machen um einen 16-Bit Wert zu erhalten. Dabei ist der Ruhezustand ("0 A", also kein Stromfluß aus/in die Batterie) mit dem Zahlenwert 0x2000 (8192 dez.) versehen, diesen muss man abziehen um einen relativen Stromfluß zu erhalten. Werte über 0x2000 zeigen also eine Ladung (Strom fließ in die Batterie) und Werte unter 0x2000 eine Entladung (Strom wird aus der Batterie entnommen) an. Die kleinste Einheit sind 10 mA.

    Die Formel lautet: I [mA] = ((b[1] << 8 | b[0]) − 0x2000) × 10

    Damit ist ein Wertebereich von -82A (Entladung) und +573A (Ladung) darstellbar.

    Spannung (3. Byte)

    Die Spannung ergibt sich aus dem 3. Byte geteilt durch 16.

    Die Formel lautet: V = b[2] / 16

    Damit ist ein Wertebereich von 0,0 bis 16,9 Volt mit einer Nachkommastelle darstellbar.

    Zähler (4. Byte)

    Der Wert erhöht sich einfach alle 11 Minuten um eins und läuft nach 0xFF wieder auf 0x00 über. Das wird vom BCM u.U. dafür verwendet die Plausibilität der Sensorwerte zu überprüfen um sicherzugehen das der Sensor nicht abgestürzt ist/hängt.

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Falls es jemand interessiert, hier ist mein Sourcecode des Sniffers zu haben https://github.com/igittigitt/esp32_lin_sniffer

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • Damit ist ein Wertebereich von -82A (Entladung) und +573A (Ladung) darstellbar.

    Ist das nicht eher 82 A Ladung (Laden mit max. 1 C)und 573 A Entladung (Anlaßvorgang mit Vorglühen)?

    Gruß aus Erfurt

    Schon der dritte vierte Ford und der Fahrer wird nicht schlau draus!

  • Ist das nicht eher 82 A Ladung (Laden mit max. 1 C)und 573 A Entladung (Anlaßvorgang mit Vorglühen)?

    Das hatte ich auch zunächst gedacht, aber wenn man das Vorzeichen wechselt, dann würde das Ladegerät Strom aus der Batterie ziehen und das ist ja eher unwahrscheinlich...

    So sieht übrigens ein Motorstart aus:

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

  • So, ich habe jetzt einfach mal die Sicherung des Regensensor gezogen (laut Sicherungsplan und Schaltplan ist das "F6" im BCM) und nochmal nen Scan gemacht und dabei kam raus das der Sensor auf ID 0x05 und 0x35 hört.

    Ein putziger Nebeneffekt ist das mit abgezogenem Sensor das BCM den Wischer in der Automatik-Stellung so bedient als hätte man die Intervallstellung eingeschaltet, vermutlich eine Schutzschaltung. Eine Anzeige im IPC bekommt man davon übrigens nicht, was ich ja echt schade finde.

    "Lernen ist Erfahrung. Alles andere ist einfach nur Information."

    Albert Einstein

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!