ESP32+RTC DS3231 soll für 17 Stunden in den deep sleep gehen

Hallo,
ich möchte meinen ESP32 wroom mit einem RTC DS3231 aus einen deep sleep
nach 17 Stunden wieder aufwecken (SQW ist auf GPIO 4).
Da der ESP32 später mit einer Batterie betrieben wird, ist Deep sleep echt wichtig :wink:

Pinbelegung:
DS3231 -> ESP32
GND -> GND
VCC -> 3.3v
SDA -> GPIO 21
SQW -> GPIO 4
32K (nicht angeschlossen)

Wenn der Deep Sleep funktioniert, wird der Sketch noch erweitert, um einen Optokoppler (ist mit einem Widerstand an GND und GPIO 15 angeschlossen) zu schalten.

Habe im Vorfeld schon mehrere Sketche getestet, um etwas dazu zu lernen und aus Spaß :wink: : Zeige mir die Datum in Serialmonitor alle x sec. Aufwachen mit touch…. Alles ohne Probleme.

Ich hatte ein Sketch getestet, die bei einem bestimmten Datum und Uhrzeit wecken sollten.. die hatten aber immer wieder Fehlalarme zwischendurch. Habe nicht verstanden wo die Fehlalarme herkommen sind, aber ich wollte ja auch kein bestimmtes Datum oder Wochentag, sondern “nur” 17 Stunden Schlaf und aufwachen… mach deinen Job und schlaf wieder.

Ich habe zum testen den Alarm auf 2 min reduziert, bevor ich auf 17 Stunden gehe. Aber er wird nicht aufgeweckt. Die Batterie vom DS3221 ist getestet und OK.

Hier mal der momentane Sketch:

#include <Wire.h>
#include <RTClib.h>
#include <esp_sleep.h>

RTC_DS3231 rtc;

void setup() {
  Serial.begin(115200);

  if (!rtc.begin()) {
    Serial.println("Konnte RTC nicht finden!");
    while (1);
  }

  // Überprüfe, ob die RTC die aktuelle Zeit hat, andernfalls setze sie auf die Systemzeit
  if (!rtc.lostPower()) {
    DateTime now = rtc.now();
    Serial.println(now.timestamp(DateTime::TIMESTAMP_FULL));
    Serial.println("RTC hat die Zeit verloren! Setze die Zeit auf die Systemzeit.");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }




/*
  DateTime now = rtc.now();
  DateTime alarmTime = now + TimeSpan(17, 0, 0, 0); // SOLL -17 Stunden in der Zukunft
  rtc.setAlarm1(alarmTime, DS3231_A1_Hour); // Alarm im Stundentakt
*/

// 2Min zum testen
  DateTime now = rtc.now();
  DateTime alarmTime = now + TimeSpan(0, 0, 2, 0); // zum testen nur 2 Minuten in der Zukunft
  rtc.setAlarm1(alarmTime, DS3231_A1_Minute); // Alarm im min.takt




  // Aktiviere den Alarm und konfiguriere den SQW-Ausgang als Weck-Pin (GPIO 4)
  rtc.disableAlarm(1);
  rtc.clearAlarm(1);
  rtc.writeSqwPinMode(DS3231_OFF);

  // Deep Sleep konfigurieren
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_4, 0); // Weck-Pin: GPIO 4, low aktiviert den Weckvorgang
}

void loop() {
  Serial.println("Gehe in den Deep Sleep-Modus...");
  esp_deep_sleep_start();
}

Ausgabe SerialMonitor:

ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:1344

load:0x40078000,len:13964

load:0x40080400,len:3600

entry 0x400805f0

E (97) psram: PSRAM ID read error: 0xffffffff

2024-02-04T10:00:32

RTC hat die Zeit verloren! Setze die Zeit auf die Systemzeit.

Gehe in den Deep Sleep-Modus...

Hoffe Ihr könnt mir helfen.

Versuch es mal ohne Ausrufezeichen :slightly_smiling_face:

Danke für den Tipp. Hab es geändert.

if (rtc.lostPower()) {

Ausgabe im SM:

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:1344

load:0x40078000,len:13964

load:0x40080400,len:3600

entry 0x400805f0

E (97) psram: PSRAM ID read error: 0xffffffff


Gehe in den Deep Sleep-Modus...

Leider wacht er nicht nach 2min wieder auf.

Hallo,
dann solltest Du jetzt erst mal testen ob es am ESP oder an der RTC liegt. Versuche den ESP mit einer Drahtbrücke aufzuwecken, Pegel beachten.

Habe mal umgebaut.

Connecting-Button-to-ESP32-for-ext0-External-Wakeup-Source

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}

Habe 2x den Taster gedrückt.

Ausgabe SM:

ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0
E (39) psram: PSRAM ID read error: 0xffffffff
Boot number: 23
Wakeup caused by external signal using RTC_IO
Going to sleep now
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0
E (39) psram: PSRAM ID read error: 0xffffffff
Boot number: 24
Wakeup caused by external signal using RTC_IO
Going to sleep now

Das scheint zu klappen.

Hallo,
ich weiß nicht was die RTC macht, allerdings sollte es ja mit 1x drücken klappen.

kennst Du das hier
https://randomnerdtutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/

Es geht auch beim ersten Tastendruck. Wollte damit nur sagen, dass ich nach dem ersten Tastendruck nochmal gedrückt habe.

Das klingt irgendwie falsch.

Hast du an dem Pin für Alarm einen Pullup Widerstand?

Dann hast Du vermutlich den Wecker falsch gestellt oder in der falschen Reihenfolge.

Im Thema ESP32 deep sleep with DS3231 findest Du ein funktionierendes Programm von mir.

Serieller Monitor

Boot number: 1
Wakeup was not caused by deep sleep: 0
Alarm will happen in 10 seconds!
16:56:30
Going to sleep now
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0

Boot number: 2
Wakeup caused by external signal using RTC_IO
Alarm will happen in 10 seconds!
16:56:40
Going to sleep now
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0

Boot number: 3
Wakeup caused by external signal using RTC_IO
Alarm will happen in 10 seconds!
16:56:50
Going to sleep now

@ agmue

Dank dir!!!

Mit ein paar kleinen Änderungen macht er was er soll.

Freut mich!

Auch wenn meine DS3231 erfreulich genau laufen, wenn Du einen Router erreichen kannst, wäre noch ein Abgleich der DS3231-Zeit mit einem NTP-Server möglich. Der ESP32 hat ja nicht ohne Grund Funk an Board :wink: