Forum: Mikrocontroller und Digitale Elektronik I2C-Protokoll aus Datenblatt erfüllt? (Fuel Gauge LC709203F)


von Daniel U. (daniel_22)



Lesenswert?

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

: Bearbeitet durch User
von Christian S. (roehrenvorheizer)


Lesenswert?

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

: Bearbeitet durch User
von Daniel U. (daniel_22)


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

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).

: Bearbeitet durch User
von Daniel U. (daniel_22)


Lesenswert?

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.

von Daniel U. (daniel_22)


Lesenswert?

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:
1
 Wire.beginTransmission(device_address);
2
 Wire.write(0x11); //Command
3
 Wire.endTransmission();
4
 Wire.requestFrom(device_address, 2);  // receive 2 bytes
5
 while (Wire.available()) {
6
   Serial.print(Wire.read(), HEX);
7
 }

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...

von Mike R. (thesealion)


Lesenswert?

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:
1
 Wire.beginTransmission(device_address);
2
 Wire.write(0x11); //Command
3
 Wire.beginTransmission(device_address+1);
4
 Wire.requestFrom(device_address, 2);  // receive 2 bytes
5
 while (Wire.available()) {
6
   Serial.print(Wire.read(), HEX);
7
 }
8
 Wire.endTransmission();

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.