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
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.
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.)
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.
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.
Rolf, bezüglich der Wartezeit. Verstehe ich das richtig, Du hast eine
Wartezeit vor Abschalten eingebaut? Wie hoch ist die?
Vor dem Abschalten des I2C-Bus, Vcc schalte ich nie, das liegt fest verdrahtet auf Gnd. Ob das in deinem Szenario sinnvoll ist oder nicht, weiß ich nicht.
Die Wartezeit habe ich nicht direkt programmiert, ich arbeite mit dem INT-Signal und warte (theoretisch unnötig, praktisch aber nötig) in einer Schleife, bis das INT-Signal nach Quittieren eines Interrupts wieder High wird. Um die Wartezeit zu messen, müsste ich mein Gerät auseinanderbauen :-( es sind aber sicher weniger als 5 ms.
Auf jeden Fall hängen die interne Stromversorgung der Uhr und der Zustand des I2C-Bus zusammen, deswegen mein Tipp.