Hallo,
ich versuche über I2C mit einem Fuel Gauge (LC709203F) zu kommunizieren.
Der Master ist dabei momentan ein Arduino Uno, die Software damit auch
Arduino.
Um zu testen, ob die Kommandos richtig ankommen will ich die
"Alarm-Voltage" in Register 0x14 auf 0x11FF, also 4,607V setzen. Damit
wird bei Unterschreitung dieser am VDD-Pin der ALARM-Pin LOW gesetzt. Da
ich einen 3,7V Li-Ion Akku angeschlossen habe sollte die Bedingung immer
erfüllt und der Pin LOW sein.
Das ist bisher nicht der Fall und um die Fehlerquelle in der
Datenübertragung auszuschließen wollte ich fragen ob das übertragene
Kommando für diese Funktion vom Prinzip her stimmt. Angehängt habe ich
die Beschreibung des Protokolls aus dem Datenblatt, sowie eine
Übersichtstabelle der Register und mein Oszilloskop-Shot der
Übertragung.
Hier der Teil meines Codes für den Befehl:
1
Wire.beginTransmission(0x0B);
2
Wire.write(0x14); //Set Voltage Threshold
3
Wire.write(0xFF); //Data Byte Low
4
Wire.write(0x11); //Data Byte High
5
Wire.endTransmission();
Start-Bedingung, Slave-Address + Write Befehl, ACK, Command Code, ACK,
Data Byte Low, ACK, Data Byte High, ACK kann ich erkennen, dann ein
kurzes HIGH an SDA (?) und wenig später die Stop-Bedingung.
Im Datenblatt steht beim Protokoll aber noch CRC-8. Das ist die
Check-Sum oder? Ich vermute, dass dieser letzte Teil fehlt und das der
Grund ist warum es nicht klappt. Stimmt das und wenn ja, kann dieser
Teil automatisch mit der Wire.h Library erstellt werden? Außerdem:
stimmt der Code an sich und die Übertragung von 0x11FF?
Gruß
Daniel
Hallo,
Schreiben auf den Slave bedeutet, Senden von 5 Bytes:
Startcondition
Slaveadresse 0x16,
Kommando z.B. 0x14,
Low Byte,
High Byte,
CRC, die Dein Programm aus den ersten 4 Bytes ausrechnet.
Stopcondition
Danach kannst Du lesen, wie im anderen Schema vorgegeben.
Also ein ACK kann ich im Oszifoto nicht wirklich erkennen, aber
vielleicht gucke ich falsch. Du hast ja eine ganz andere Slaveadresse
verwendet.
mfG
Hallo,
ja, die Adresse ist im Datenblatt mit 0x16 falsch angegeben. Sie ist
0x0B und dann kommt das Bit für Read oder Write noch hinzu. Das ergibt
dann erst 0x16 bzw. 0x17.
ACK müsste ja jeweils das LOW am 9. Clock-Signal sein.
Gibt es dann eine Möglichkeit die CRC automatisch ausrechnen zu lassen
oder muss ich die manuell für jeden Befehl ausrechnen?
Gruß
Daniel
Daniel U. schrieb:> ja, die Adresse ist im Datenblatt mit 0x16 falsch angegeben. Sie ist> 0x0B und dann kommt das Bit für Read oder Write noch hinzu. Das ergibt> dann erst 0x16 bzw. 0x17.
Nein, das ergibt auf keinen Fall 0x16 oder 0x17.
Das bit fürs Lesen oder Schreiben ist bit 0, also kann die Adresse
nur 0x0B oder 0x0A sein.
Irgendwie glaube ich das aber nicht, es wird doch 0x16 sein.
Meistens werden Adressen als gerade Zahlen angegeben, also dient
die angegebene Adresse (0x16) zum schreiben, 0x17 ist zum lesen.
Du hast auch ein Beispiel unten im ersten Bild, versuche doch:
0x16-0x09-0x55-0xAA und als CRC 0x3B
Daniel U. schrieb:> die Adresse ist im Datenblatt mit 0x16 falsch angegeben
Es gibt mehrere unterschiedliche Arten, wie I2C-Adressen angegeben
werden. Manche Hersteller bevorzugen die 7 Bit-Adresse, aber gefühlt die
Mehrheit gibt die 8 Bit-Adresse an. Dazu kommt noch, dass manche
Hersteller die 8 Bit-Adresse angeben, aber dazu schreiben, dass I2C nur
7 Bit-Adressen verwendet. Gleiches gilt für Bibliotheken und
I2C-Hardware.
In deinem Fall ist das dank der Bits eindeutig beschrieben:
Die 8 Bit-Adresse ist 0x16 (die 7 Bit-Adresse wäre 0x0B).
Du adressierst also korrekt mit 0x16 (00010110) und 0x17 (00010111).
Ich habe übrigens einen kleinen Fehler im Oszi-Bild, der FF Teil kommt
nicht ganz zum Schluss sondern als vorletztes, getauscht mit dem Teil
davor. Ich hatte erst Low- und High-Byte im Code vertauscht, es dann
hier korrigiert aber das Bild nicht mehr geupdatet.
Und ja genau, 0x16 ist dann für's Schreiben und 0x17 für's Lesen. Ist ja
angegeben als 0001011X.
Mittlerweile habe ich auch eine Kommunikation erreichen können (ALARM
geht LOW nach dem Befehl). Jetzt kann ich sicher sein, dass die
Befehlsfolge beim Schreiben passt. Danke.
Beim Lesen gibt es noch Probleme momentan.
Im Protokoll steht ja "Write-Adresse, Command, Read-Adresse," und dann
wird gelesen.
Wie ist das korrekt im Code umzusetzen? Momentan hab ich das so:
Das endTransmission stört weil das im Protokoll nicht vorgesehen ist.
Aber weglassen geht ja nicht einfach. Das müsste ja eigentlich ganz ans
Ende laut Datenblatt...
Ich kenne die Arduino Software jetzt leider nicht, aber auch die
müsste ein Repeated Start unterstützen.
Wenn dein restliches lesen richtig ist, müsste das also in etwas so
aussehen:
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang