Forum: Projekte & Code I2C Kommunikation zum DS3231 in Espressif-IDF 5.5 zickt plötzlich rum


von Olli Z. (z80freak)


Lesenswert?

Verflixt, ich habe einen DS3231 den ich per GPIO einschalte (mit VCC 
versorge) wenn ich vom Code mit ihm kommunizieren will (Uhrzeit lesen, 
Alarmzeit programmieren, etc.). Danach schalte ich ihn wieder aus.

Das mache ich im Prinzip so:
1
// I2C für DS3231 initialisieren und Handle erzeugen
2
i2c_dev_t dev;
3
memset(&dev, 0, sizeof(i2c_dev_t));
4
ESP_ERROR_CHECK(ds3231_init_desc(&dev, I2C_MASTER_NUM, I2C_MASTER_SDA_IO, I2C_MASTER_SCL_IO));
5
6
// Alarmzeit stellen
7
gpio_set_level(DS3231_VCC_PIN, 1);
8
vTaskDelay(pdMS_TO_TICKS(100)); // 100 ms Stabilisierungszeit nach Poweron
9
ESP_ERROR_CHECK(ds3231_clear_alarm_flags(&dev, DS3231_ALARM_1));
10
ESP_ERROR_CHECK(ds3231_set_alarm(&dev, DS3231_ALARM_1, &alarm_time, DS3231_ALARM1_MATCH_SECMINHOUR, NULL, 0));
11
ESP_ERROR_CHECK(ds3231_enable_alarm_ints(&dev, DS3231_ALARM_1));
12
gpio_set_level(DS3231_VCC_PIN, 0);
13
14
while(1)
15
{
16
  // Aktuell Uhrzeit auslesen
17
  gpio_set_level(DS3231_VCC_PIN, 1);
18
  vTaskDelay(pdMS_TO_TICKS(100)); // 100 ms Stabilisierungszeit nach Poweron
19
  ESP_ERROR_CHECK(ds3231_get_time(&dev, &alarm_time)); // get current time
20
  gpio_set_level(DS3231_VCC_PIN, 0);
21
22
  ... anderer code
23
24
  vTaskDelay(pdMS_TO_TICKS(60000));
25
}

Das einstellen der Alarmzeit funktioniert wunderbar, immer:
1
I (406) i2cdev: [Port 0] First initialization. Configuring bus with SDA=12, SCL=11 (Pullups SCL:0 SDA:0)
2
W (406) i2c.master: Please check pull-up resistances whether be connected properly. Otherwise unexpected behavior would happen. For more detailed information, please read docs
3
I (426) i2cdev: [Port 0] Successfully installed I2C master bus (Handle: 0x4084dd68).
4
I (426) i2cdev: [0x68 at 0] Device added successfully (Device Handle: 0x4084e244, Speed: 400000 Hz).

Aber wenn es daran geht die Uhrzeit periodisch auszulesen, streikt das 
ganze plötzlich:
1
I (756) i2cdev: [0x68 at 0] Device added successfully (Device Handle: 0x4084e2d0, Speed: 400000 Hz).
2
E (1956) i2c.master: s_i2c_synchronous_transaction(945): I2C transaction failed
3
E (1956) i2c.master: i2c_master_transmit_receive(1248): I2C transaction failed
4
W (1956) i2cdev: [0x68 at 0] I2C op failed (Try 0, Handle 0x4084e2d0): 259 (ESP_ERR_INVALID_STATE).
5
W (1966) i2cdev: [0x68 at 0] Invalid state error - handle may need recreation
6
W (1966) i2cdev: [0x68 at 0] Removing potentially corrupted device handle 0x4084e2d0 after permanent error
7
W (2016) i2cdev: [0x68 at 0] Retrying operation...
8
I (2016) i2cdev: [0x68 at 0] Device added successfully (Device Handle: 0x4084e2d0, Speed: 400000 Hz).
9
E (2076) i2c.master: clear bus failed.
10
E (2076) i2c.master: s_i2c_transaction_start(617): reset hardware failed
11
E (2076) i2c.master: s_i2c_synchronous_transaction(945): I2C transaction failed
12
E (2076) i2c.master: i2c_master_transmit_receive(1248): I2C transaction failed
13
W (2086) i2cdev: [0x68 at 0] I2C op failed (Try 1, Handle 0x4084e2d0): 259 (ESP_ERR_INVALID_STATE).
14
W (2096) i2cdev: [0x68 at 0] Invalid state error - handle may need recreation
15
W (2096) i2cdev: [0x68 at 0] Removing potentially corrupted device handle 0x4084e2d0 after permanent error
16
W (2186) i2cdev: [0x68 at 0] Retrying operation...
17
I (2186) i2cdev: [0x68 at 0] Device added successfully (Device Handle: 0x4084e2d0, Speed: 400000 Hz).
18
E (2246) i2c.master: clear bus failed.
19
E (2246) i2c.master: s_i2c_transaction_start(617): reset hardware failed
20
E (2246) i2c.master: s_i2c_synchronous_transaction(945): I2C transaction failed
21
E (2246) i2c.master: i2c_master_transmit_receive(1248): I2C transaction failed
22
W (2256) i2cdev: [0x68 at 0] I2C op failed (Try 2, Handle 0x4084e2d0): 259 (ESP_ERR_INVALID_STATE).
23
W (2266) i2cdev: [0x68 at 0] Invalid state error - handle may need recreation
24
W (2266) i2cdev: [0x68 at 0] Removing potentially corrupted device handle 0x4084e2d0 after permanent error
25
W (2436) i2cdev: [0x68 at 0] Retrying operation...
26
I (2436) i2cdev: [0x68 at 0] Device added successfully (Device Handle: 0x4084e2d0, Speed: 400000 Hz).
27
E (2496) i2c.master: clear bus failed.
28
E (2496) i2c.master: s_i2c_transaction_start(617): reset hardware failed
29
E (2496) i2c.master: s_i2c_synchronous_transaction(945): I2C transaction failed
30
E (2496) i2c.master: i2c_master_transmit_receive(1248): I2C transaction failed
31
W (2506) i2cdev: [0x68 at 0] I2C op failed (Try 3, Handle 0x4084e2d0): 259 (ESP_ERR_INVALID_STATE).
32
W (2516) i2cdev: [0x68 at 0] Invalid state error - handle may need recreation
33
W (2516) i2cdev: [0x68 at 0] Removing potentially corrupted device handle 0x4084e2d0 after permanent error
34
E (2526) i2cdev: [0x68 at 0] I2C operation failed after 4 retries. Last error: 259 (ESP_ERR_INVALID_STATE)

Wenn ich den Poweron/Poweroff weglasse funktioniert die Sache. Komisch 
nur das es mal so lief... irgendwas habe ich falsch gemacht. Ich denke 
nicht das der DS3231 grundsätzlich ein Problem damit hat wenn man ihn 
immer wieder wegschaltet, da er durch die Pufferbatterie intern 
weiterläuft.

Es muss also irgendwas mit dem I2C Bus zu tun haben? Ich hatte schonmal 
ans Handle (dev) gedacht und das nach jedem Poweron wieder neu erzeugt, 
aber das bringt keinen Unterschied.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Messe die Spannung an SDA und SCL im Ruhezustand, wenn VCC aus 
geschaltet ist. Hast du dann saubere HIGH Pegel?

Messe nochmal, während VCC eingeschaltet ist und noch keine 
Kommunikation stattfand.

Messe nochmal nach der fehlgeschlagenen Kommunikation.

Wenn du ein Oszilloskop hast - um so besser, dann kannst du das alles in 
einem Bild unterbringen.

von Rolf (rolf22)


Lesenswert?

Olli Z. schrieb:
> Ich denke nicht das der DS3231 grundsätzlich ein Problem damit hat wenn
> man ihn immer wieder wegschaltet, da er durch die Pufferbatterie intern
> weiterläuft.

Vorab: Du kannst Vcc der Uhr fest auf Gnd legen, dann ist der 
Stromverbrauch minimal. Siehe Datenblatt. Wenn du den I2C-Bus nur zum 
Auslesen/Programmieren aktivierst, spart das u. U. zusätzlich Strom.

Ansonsten: Die Uhr mag es definitiv nicht, wenn man den I2C-Bus 
abschaltet, während sie intern noch "Restarbeiten" erledigt. Womöglich 
mag sie es auch nicht, wenn man nach dem Auslesen per I2C sofort die 
Versorgung wegnimmt – das weiß ich aber nicht.

(In meinem Gerät hier ging das 6 Monate lang gut, dann plötzlich stürzte 
die Uhr alle paar Stunden ab. Nachdem ich eine Wartezeit eingebaut habe, 
läuft es seit einem Jahr problemlos. Mit Vcc = Gnd: das Gerät hat außer 
einer CR2032 gar keine Stromversorgung.)

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Ich habe den Fehler gefunden, er lag in meinem Programm. In einer 
Kondition hatte ich veressen zuvor den DS wieder mit Strom zu versorgen, 
klar das das schief ging.

Rolf, bezüglich der Wartezeit. Verstehe ich das richtig, Du hast eine 
Wartezeit vor Abschalten eingebaut? Wie hoch ist die? Auf ein paar 
Sekunden kommt es ja wirklich nicht drauf an. Mein Thema ist eher die 
Parallelität. Ich müsste daher am besten eine Timer ISR erstellen die 
bei jedem poweroff() den DS nach x Sekunden erst ausschaltet und durch 
ein poweron() blockiert wird. Sonst kann es wieder zu komischen 
Konstellationen kommen.

von Rainer W. (rawi)


Lesenswert?

Gelesen?

Forum: Projekte & Code

Hier könnt ihr Projekte, Schaltungen oder Codeschnipsel vorstellen. 
Projekte bitte nur mit Code oder Schaltplan posten (falls ihr nur Fotos 
vorstellen möchtet, bitte in "Zeigt her eure Kunstwerke"). Bitte hier 
keine Fragen posten.

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.