ESP32 deep sleep with DS3231

Hallo an alle,

vorsicht bin Anfänger und stelle blöde Fragen!!!!

Genau gesagt geht es um ESp32 und deep sleep.
Grundsätzlich wollte ich fragen ob es mit einem ESP32 überhaupt möglich ist nach einem deep sleep den loop zu nutzen
Was ich bis jetzt so im Internet gelesen habe funktioniert das anscheinend nicht?

Jemand nähere Infos dazu?

Zum Verständnis, habe auf der Uni ein Projekt wo ich ein paar Werte (Temperatur, Tön, etc) 2 oder 3 mal am Tag für 5min messen soll und dann auf einer SD zwischenspeichern und dann über SIM an eine Cloud senden.

Also die Daten einzulesen ist kein Problem, auch das speichern auf der SD Karte ist easy.

Jedoch komme ich mit dem sleep modus vom ESP32 nicht zurecht.
Ich habe auch eine externe RTC DS3231 um Datum und Uhrzeit zu wissen und dann die Datein auf der SD zu benennen, etc...
Mit der DS3231 wollte ich einen das aufwachen aus dem deep sleep bewirken.
Da scheitere ich aber.

Wie gesagt die Bsp welche es im Internet gibt, sagen alle, das der loop nicht ausgeführt werden kann.
Vlt wäre jemand so nett mir zu helfen?
Danke und schöne Grüße

Hab das Bsp gefunden wo der ESP in deep sleep versetzt wird und versucht auf den DS3231 umzubauen, da dieser ja SQW nur low setzten kann, daher eben die abfrage für wacke up ob die beiden Pins 33 und 27 auf low sind und dann einfach das blinken der Led welches als testfunktion im loop

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

RTC_DATA_ATTR int bootCount = 0;
#define LED 2

/*
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(9600);
  delay(1000); //Take some time to open up the Serial Monitor

  pinMode(LED, OUTPUT);

  //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,0); //1 = High, 0 = Low //Pin 33
  esp_sleep_enable_ext1_wakeup(0x8000000,ESP_EXT1_WAKEUP_ALL_LOW); //Pin 27

  //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");
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
  
}

void loop(){
  digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)
  //delay(1000);                       // wait for a second
  digitalWrite(LED, LOW);    // turn the LED off by making the voltage LOW
  //delay(1000);                       // wait for a second

  //delay(1000); //Take some time to open up the Serial Monitor
}

Und der code den ich gefunden habe um den Interupt vom DS3231 zu triggern:

/* Example implementation of an alarm using DS3231
 *
 * VCC and GND of RTC should be connected to some power source
 * SDA, SCL of RTC should be connected to SDA, SCL of arduino
 * SQW should be connected to CLOCK_INTERRUPT_PIN
 * CLOCK_INTERRUPT_PIN needs to work with interrupts
 */
#include <RTClib.h>
// #include <Wire.h>
RTC_DS3231 rtc;
// the pin that is connected to SQW
#define CLOCK_INTERRUPT_PIN 2
void setup() {
    Serial.begin(9600);
    // initializing the rtc
    if(!rtc.begin()) {
        Serial.println("Couldn't find RTC!");
        Serial.flush();
        abort();
    }
    
//    if(rtc.lostPower()) {
//        // this will adjust to the date and time at compilation
//        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//    }
    
    //we don't need the 32K Pin, so disable it
    rtc.disable32K();
    
    // Making it so, that the alarm will trigger an interrupt
    //pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
    //attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);
    
    // set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
    // if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
    rtc.clearAlarm(1);
    rtc.clearAlarm(2);
    
    // stop oscillating signals at SQW Pin
    // otherwise setAlarm1 will fail
    rtc.writeSqwPinMode(DS3231_OFF);
    
    // turn off alarm 2 (in case it isn't off already)
    // again, this isn't done at reboot, so a previously set alarm could easily go overlooked
    rtc.disableAlarm(2);
    
    // schedule an alarm 10 seconds in the future
    if(!rtc.setAlarm1(
            rtc.now() + TimeSpan(10),
            DS3231_A1_Second // this mode triggers the alarm when the seconds match. See Doxygen for other options
    )) {
        Serial.println("Error, alarm wasn't set!");
    }else {
        Serial.println("Alarm will happen in 10 seconds!");  
    }
}
void loop() {
    // print current time
    char date[10] = "hh:mm:ss";
    rtc.now().toString(date);
    Serial.println(date);
    // resetting SQW and alarm 1 flag
    // using setAlarm1, the next alarm could now be configurated
    if(rtc.alarmFired(1)) {
        rtc.clearAlarm(1);
        Serial.println("Alarm cleared");
    }
    
    delay(2000);
}
void onAlarm() {
    Serial.println("Alarm occured!");
}

Vlt wäre jemand so nett mir zu helfen ob und wie es möglich ist das zu kombinieren, sodass die LED 1min blinkt und dann 1 min im deep sleep ist.

Bin für jeden Tipp dankbar.
Nochmals schone Grüße

ESP32 Deep Sleep with Arduino IDE and Wake Up Sources | Random Nerd Tutorials

Die Frage an dich ist nun:

  • welchen Deepsleep Modus möchtest du nutzen?

und fasse deine Anforderungen zusammen:
Was soll dein ESP alles machen?

  • 1 min sleep/ 1 min blinken
  • 3 mal am Tag für 5 min was messen und speichern. Wie sieht die Messung aus, was wird schlussendlich gespeichert? ein Wert oder mehre?--> was soll in so einem 5 Minuten Interval mit dem Blinken geschehen - trotzdem nur 1min blinken?
  • etwas an eine "Cloud" senden ... wie oft am Tag / in welchem Interval, welche Daten genau?
  • was soll passieren wenn "die Cloud" nicht erreichbar ist?

Das ist möglich.

Wenn Du in das Beispiel \2.0.2\libraries\ESP32\examples\DeepSleep\TimerWakeUp\TimerWakeUp.ino schaust, dann wird loop nie erreicht, weil am Ende von setup schon der Schlaf beginnt. Wenn man das etwas umstellt, blinkt auch eine LED in loop:

/*
  Simple Deep Sleep with Timer Wake Up
  =====================================
  ESP32 offers a deep sleep mode for effective power
  saving as power is an important factor for IoT
  applications. In this mode CPUs, most of the RAM,
  and all the digital peripherals which are clocked
  from APB_CLK are powered off. The only parts of
  the chip which can still be powered on are:
  RTC controller, RTC peripherals ,and RTC memories

  This code displays the most basic deep sleep with
  a timer to wake it up and how to store data in
  RTC memory to use it over reboots

  This code is under Public Domain License.

  Author:
  Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#define LED 13
#define uS_TO_S_FACTOR 1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) */

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);
  pinMode(LED, OUTPUT);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.printf("\nBoot number: %d\n", bootCount);

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

  // First we configure the wake up source, we set our ESP32 to wake up every 5 seconds
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.printf("Setup ESP32 to sleep for every %d Seconds\n", TIME_TO_SLEEP);
}

void loop() {
  static uint32_t vorhin = 0;
  static uint32_t intervall = 0;
  static byte schritt = 0;
  if (millis() - vorhin >= intervall) {
    vorhin = millis();
    switch (schritt) {
      case 0:
        digitalWrite(LED, HIGH);
        intervall = 1000;
        schritt++;
        break;
      case 1:
        digitalWrite(LED, LOW);
        schritt++;
        break;
      case 2:
        Serial.println("Going to sleep now");
        Serial.flush();
        esp_deep_sleep_start();
        Serial.println("This will never be printed");
        break;
    }
  }
}

Hay,

danke für die Antwort.
Zu den fragen:
*Das mit 1min sleep/ 1min blinken war nur ein minimal Bsp. am ende sollte es 3 mal am Tag 5 min messen, aber wenn ich das andere mit 1min mal ahbe sollte ich den rest auch hin bekommen, vermute ich zumindest.
*senden soll es die gemessenen daten, also Temperatur, Spannungslevel von der Ton aufzeichung um dann eine fft für frequenzspektrum zu machen und dann noch 3 Strome und 3 Spannungen

  • wollte das dann so handhaben, wenn senden der Datei von der SD erfolgreich war, dann die SD löschen und wenn nicht, dann bei der nächsten Verbindung alle Datein (ältere Tage wo senden nicht funktioniert hat) von der SD senden und dann löschen

Grüß

Hy

danke für die Antwort.
Ok dachte nur weil das alle geschrieben haben.
Die Idee mit später den deep sleep starten hatte ich auch aber war mir nicht sicher, jedoch ist das mit der DS3231 zusammenmergen mein größeres problem

Gruß

Danke hatte nicht gedacht dass wenn überall steht der loop wird nicht ausgeführt, nur der code der grund ist und wenn ich sleep einfach in den loop verschieben kann ist es ja easy.
Danke für die Info!!

Nur wie wecke ich das ding jetzt über den DS3231 auf?
Da habe ich eher meine größeren Probleme!

Vlt hat jemand Lust und zeit mir zu helfen, sonst sag ich an jeden danke für die tipps!!!

Danke
Grüß

Dann nutze doch das Beispiel ExternalWakeUp.ino als Ausgangspunkt:

/*
  Deep Sleep with External Wake Up
  =====================================
  This code displays how to use deep sleep with
  an external trigger as a wake up source and how
  to store data in RTC memory to use it over reboots

  This code is under Public Domain License.

  Hardware Connections
  ======================
  Push Button to GPIO 33 pulled down with a 10K Ohm
  resistor

  NOTE:
  ======
  Only RTC IO can be used as a source for external wake
  source. They are pins: 0,2,4,12-15,25-27,32-39.

  Author:
  Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#define LED 13

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);
  pinMode(LED, OUTPUT);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.printf("\nBoot number: %d\n", 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.
  */
  pinMode(GPIO_NUM_33, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); //1 = High, 0 = Low
}

void loop() {
  static uint32_t vorhin = 0;
  static uint32_t intervall = 0;
  static byte schritt = 0;
  if (millis() - vorhin >= intervall) {
    vorhin = millis();
    switch (schritt) {
      case 0:
        digitalWrite(LED, HIGH);
        intervall = 1000;
        schritt++;
        break;
      case 1:
        digitalWrite(LED, LOW);
        schritt++;
        break;
      case 2:
        Serial.println("Going to sleep now");
        Serial.flush();
        esp_deep_sleep_start();
        Serial.println("This will never be printed");
        break;
    }
  }
}

Verbindet man SQW mit GPIO33, kann DS3231 den ESP32-Schlaf beenden:

#include <RTClib.h>
RTC_DS3231 DS3231;

const byte LED = 13;
bool ds3231_vorhanden = false;

RTC_DATA_ATTR int bootCount = 0;  // diese Variable ist auch nach deep sleep vorhanden

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(500); //Take some time to open up the Serial Monitor
  pinMode(LED, OUTPUT);
  ++bootCount;
  Serial.printf("\nBoot number: %d\n", bootCount);
  print_wakeup_reason();  //Print the wakeup reason for ESP32
  pinMode(GPIO_NUM_33, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); //1 = High, 0 = Low

  if (!DS3231.begin())
  {
    Serial.println("Couldn't find RTC!");
  } else {
    ds3231_vorhanden = true;
    DS3231.disable32K();  //we don't need the 32K Pin, so disable it
    DS3231.writeSqwPinMode(DS3231_OFF);  // stop oscillating signals at SQW Pin, otherwise setAlarm1 will fail
    DS3231.clearAlarm(1);                // set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
    DS3231.clearAlarm(2);
    DS3231.disableAlarm(2);              // turn off alarm 2 (in case it isn't off already)
    if (!DS3231.setAlarm1(
          DS3231.now() + TimeSpan(10),   // schedule an alarm 10 seconds in the future
          DS3231_A1_Second            // this mode triggers the alarm when the seconds match
        ))
    {
      Serial.println("Error, alarm wasn't set!");
    } else {
      Serial.println("Alarm will happen in 10 seconds!");
    }
  }
}

void loop() {
  char date[10] = "hh:mm:ss";
  static uint32_t vorhin = 0;
  static uint32_t intervall = 0;
  static byte schritt = 0;
  if (millis() - vorhin >= intervall) {
    vorhin = millis();
    switch (schritt) {
      case 0:
        DS3231.now().toString(date);
        Serial.println(date);
        digitalWrite(LED, HIGH);
        intervall = 1000;
        schritt++;
        break;
      case 1:
        digitalWrite(LED, LOW);
        schritt++;
        break;
      default:
        Serial.println("Going to sleep now");
        Serial.flush();
        esp_deep_sleep_start();
        Serial.println("This will never be printed");
        break;
    }
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.