Hallo zusammen,
bislang konnte mir hier schon immer die Suchfunktion weiter helfen, mein
jetziges Problem scheint dafür aber leider zu speziell.
Und zwar möchte ich das LCD-Display eines Gerätes durch einen Arduino
ersetzten, der die darzustellenden Daten zunächst ausliest/auswertet, um
sie dann an ein eigenes Display senden zu können. Das Problem bei der
Sache ist nun, dass es sich bei dem Gerät um das Instrumentenpanel eines
Toyota iQ handelt und es (natürlich) kein Datenblatt zu dem Display
gibt. Freilich habe ich schon ein wenig experimentiert, bin nun aber mit
meinem Latein am Ende.
Wenn jemand sich auf die folgenden Infos einen Reim machen und mir
einen Tipp geben kann, in welche Richtung weiter probiert werden könnte,
wäre ich sehr dankbar!
Zum LCD-Display:
- 5 Pins (Belegung: Kommunikation | Kommunikation. |+ 5V | Masse |
Ground)
- wenn einer der beiden Komm-Kanäle unterbrochen wird, fängt das Display
an zu flackern, zeigt die Daten weiterhin an, wird aber nicht mehr
aktualisiert
- integrierten Controller (leider eingegossen und ohne erkennbare
Kennzeichnung)
- keine Hintergrundbeleuchtung
Auf der Platine des Instrumentenpanels sind die beiden
Kommunikations-Kanäle mit Pull-ups versehen, ich habe daher erst mal auf
I²C getippt und das Display an einen Arduino angeschlossen und das
Programm I²C-Scanner laufen lassen und dabei wurde tatsächlich auch an
der Adresse 0x38 angeblich ein Device gefunden. Ich habe darauf das
slave_receiver Programm aus den Beispielen der Wire-Bibliothek auf den
Arduino gespielt, die Adresse angepasst und an die Panel-Platine
angeschlossen – in der naiven Hoffnung, dass Controller des
Instrumentenpanels nur an die Adresse sendet und mein Arduino nun
zumindest irgendetwas über die seriellen Monitor ausspuckt. Aber es kam
natürlich nichts….
Nun kann es sein, dass das Programm nicht stimmt und ich zu blöd bin es
zu sehen:
1
#include<Wire.h>
2
voidsetup()
3
{Wire.begin(56);// Wire will die Adresse meines Wissens nach dezimal haben?!
4
Wire.onReceive(receiveEvent);
5
Serial.begin(9600);
6
}
7
8
voidloop()
9
{
10
delay(100);
11
}
12
13
voidreceiveEvent(inthowMany)
14
{
15
while(1<Wire.available())// loop through all but the last
16
{
17
charc=Wire.read();// receive byte as a character
18
Serial.print(c);// print the character
19
}
20
intx=Wire.read();// receive byte as an integer
21
Serial.println(x);// print the integer
22
}
… oder das LCD-Display kommuniziert gar nicht über I²C. Leider kenne ich
mich in dem Kommunikationsbereich leider nur ganz ungenügend aus, daher
fiel mir nichts Besseres ein, als den Arduino zum Logic Analyzer
umzufunktionieren (https://github.com/gillham/logic_analyzer) und in die
Kommunikation reinzuhören.
In LogicSniffer habe ich die mitgelieferten Analyzer für die
verschiedenen Protokolle drüber laufen lassen, leider ohne großen
Erfolg:
Der I²C-Analyzer spuckt bei der Interpretation ziemlich viele Bus-Fehler
aus, das Gleiche gilt für UART oder SPI (wenngleich ich beiden nicht
sicher bin, welcher Kanal was ist).
Wenn es I²C sein sollte, sieht das Taktsignal (siehe Bild) auch etwas
unregelmäßig aus – hier stellt sich natürlich auf die Frage, ob dies
nicht an dem behelfsmäßigen Logic Analyzer liegen könnte.
Soweit zu dem, was ich versucht habe. Wie gesagt, wenn jemand eine
weiterführende Idee hat, würde ich mich sehr darüber freuen!
Viele Grüße
Philipp
Ich tippe auf irgendwas mit Clock Data.
Oben Clock unten Data.
die ersten 8 bit passen da gut.
Das 9. Bit ist etwa merkwürdig mit dem Flankenwechsel der Datenleitung.
Das wieder hot sich dan ja.
8 gute Bits und dieser merkwürdige Wechsel.
Ich tippe mal das ist kein Bit sondern der Sender schaltet seine Pins
auf Hochohmig.
Ob da jetzt immer im Wechsel gesendet wird kann man schlecht sagen.
Da müsste man z.B. ein Widerstand in die Leitung schalten und die Pegel
der Bits messen.
Danke für die Antwort!
Jürgen D. schrieb:> Ich tippe auf irgendwas mit Clock Data.> Oben Clock unten Data.
Sieht das nicht eher unten nach Clock aus?
> die ersten 8 bit passen da gut.> Das 9. Bit ist etwa merkwürdig mit dem Flankenwechsel der Datenleitung.> Das wieder hot sich dan ja.> 8 gute Bits und dieser merkwürdige Wechsel.> Ich tippe mal das ist kein Bit sondern der Sender schaltet seine Pins> auf Hochohmig.
Oder es liegt an einer unsauberen Erfassung? Einen besseren Logic
Analyzer habe ich leider nicht, die Messkabel habe ich schon möglichst
kurz gewählt
> Ob da jetzt immer im Wechsel gesendet wird kann man schlecht sagen.> Da müsste man z.B. ein Widerstand in die Leitung schalten und die Pegel> der Bits messen.
Was würde denn der Widerstand bringen? (Ich bin nur Laien-Programmierer
und nicht in der Elektronik aufgewachsen ^^)
Stimmt natürlich, hatte mich verschrieben mit Oben/Unten.
Durch den Widerstand wird ja der Pegel des signales etwas reduziert.
Wenn du jetzt auf den Pegel des Signales auf einer Seite des
Widerstandes mist hast du da ein höheren Pegel wenn das Signal von der
Seite kommt auf der man mist als wenn es erst von der anderen Seite
durch den Widerstand muß.
Hallo Phillip,
ja das sollte normales I2C sein. Die analyse mit dem Arduino ist
natürlich nicht optimal da manche flanken etwas versetzt gesampelt
werden wodurch hier wohl die Busanalyse nicht funktioniert.
Zumindest geben die Daten etwas auskunft darüber das es was von NXP sein
könnte.
NXP scheint hier sich das leben aller einfach zu machen und nutzt die
gleichen Adressen/Befehle bei diversen LCD Treibern. und das Kurze
Framesegment passt da recht gut.
http://www.nxp.com/documents/data_sheet/PCA85132.pdfhttp://www.nxp.com/documents/data_sheet/PCF8532.pdf
Da du wohl eine Funktionsfähige Platine hast die das Display ansteuert
ist das Reverse Engineering recht einfach. Dazu bräuchte man aber ein
paar mehr Aufzeichnung zB. nach Poweron der Platine (Wichtig für die
Initialisierung)
Datenframes wenn sich der vor/nach einer Aktualisierung des Displays.
Und der Rest ist dann nur noch die LCD Segmentzuordnung herausfinden.
Sowas ähnliches hab ich erst am Wochenende bei einem Textlcd in Chip on
Glas Technik erfolgreich durchgeführt.
Gruß Kai
Danke für die Infos und den Verweis auf die Modelle/Datenblätter, da bin
ich nun ja schon um Einiges weiter! Es scheint ja nun gesichert, dass es
sich um I²C handelt. Nun stellt sich mir die Frage, warum der Arduino
als Slave keine Daten empfängt bzw. was ich dort falsch mache.
An vielen Stellen finden sich Infos, dass die Standardtaktrate der
mitgelieferten I²-Library auf 400kHz hochgeschraubt werden kann, also
nehme ich an, dass es mit dieser Library/Hardware auch im Slave-Modus
bis 400 kHz klappen sollte – und mehr würden die von Euch genannten
LCD-Driver auch nicht unterstützen.
Auf weitere Problemursachen komme ich im Moment nicht, da an den
LCD-Driver keine Requests gestellt werden und so mein Austausch dem
Controller auf der Platine nicht auffallen dürfte.
> Du benutzt Open Logic Sniffer, oder?> Tools -> I2C protocol analyser.
Das Tool habe ich schon probiert, leider kommt dabei nicht viel rum, da
- wie Kai schon angemerkt hat - die Flanken versetzt aufgenommen werden.
Letztlich will ich ja die Daten auslesen, um daraus die darzustellenden
Zahlen zu rekonstruieren. In dem Sinne brauche ich ja ohnehin eine
Lösung, die mir nicht nur Grafiken liefert (die man dann manuell
analysieren muss), sondern direkt die gesendeten Bytes ausspuckt.
>Schon mal hier rein geschaut?>Beitrag "I2C (TWI) Sniffer mit AVR">Damit sollte sich das Protokoll auch analysieren lassen.
Den I²C-Sniffer von Peter Dannegger habe ich mir auch schon angeschaut
und womöglich sind Controller mit USI auch besser für den Empfang
geeignet. Das ist für mich dann aber ganz neues Terrain, mal sehen ob es
klappt...
Noch eine wahrscheinlich blöde Frage: Kann man aus dem geposteten
Ausschnitt der Übertragung die Taktrate ablesen bzw. was zählt als eine
'Amplitude'?
Die Zahlen, die ich davon abgelesen habe, ergeben bei mir Taktraten im
MHz-Bereich, aber das wäre ja zu hoch?!
Bei einer Darstellung mit Skala > 1 us kann die Frequenz ja nicht im
MHz-Bereich sein ;)
(1 us = 1 Millionstel Sekunde ~ Pediodendauer von 1 MHz muss eine
Million mal in eine Sekunde passen… ;)
Nochmals vielen Dank für die Hinweise!
Mit Hilfe das Arduino als Logic Analyzer habe ich mir die Kommunikation
zwischen Controller und LCD-Driver inzwischen nochmals genau angeschaut
und es handelt sich bei dem Driver tatsächlich um einen PCA85132 (oder
einen Klon); mit einem Arduino als Master kann ich nun das LCD auch
problemlos steuern.
Nur möchte ich ja leider das umgekehrte bewerkstelligen: Meinen
Controller als Slave anstatt des LCDs anschließen. Inzwischen habe ich
mir aus Frust einen Teensy 3 zugelegt, da es dafür eine überarbeitete
Wire-Library gibt, nachdem alle meine Versuche mit Auruino Uno und Mega
gescheitert sind. Der Teensy 3 erkennt nun zumindest, dass er
angesprochen wird, dann bricht die Verbindung aber sofort ab und wird
neu gestartet (unten auf der Grafik).
Auf dem Bild habe ich die Kommunikation vom Master alleine, zwischen
Master und LCD-Driver und zwischen Master und Teensy 3 zusammengestellt.
Was im letzten Fall passiert, da kann ich bei meinem Wissen nur leider
nur raten. Kann einer von Euch vllt. mehr daraus deuten?
Komisch kommen wir indes die Pull-ups vor, da auf der Platine des
Instrumentenpanels nur die SDA-Leitung mit einem 4,7K versehen ist, an
der SCL-Leitung ist dagegen kein externer Pull-up angeschlossen. Da aber
beide Leitungen im Solo-Betrieb HIGH sind, nehme ich an, dass der
Controller die SCL-Leitung intern hoch zieht. Beide Leitungen sind mit
einem Serienwiderstand von 1k bestückt.
Darüber hinaus befindet sich Controller (5V) und Teensy (3V) ein Level
Shifter, ich habe den hier exakt nachgebaut:
https://www.sparkfun.com/datasheets/BreakoutBoards/Level-Converter-v10.pdf
(und natürlich die beiden bidirektionalen TX-Leitungen belegt.)