ESP32 mit NTP Zeitabfrage

Hallo Gemeinde.
Ich habe mir ein Programm vorgenommen, mit dem man die Zeit vom NTP Server ausliest und die Systemzeit damit aktualisiert. Das funktioniert wunderbar. Ich frage mich nur warum das Programm immer die Zeit ausliest, dann den ESP 30 Sek. schlafen schickt, in dann wieder Resetet und wieder die Zeit NTP Server holt.
Oder um genau zu sein, ich frage mich nur, warum der ESP immer wieder schlafen geschickt wir, um dann durch einen Reset neu zu starten? Ich habe noch keine Ahnung ob das Reseten nötig ist. Also ob der ESP dann, wenn man nicht immer wieder resetet, irgendwann keine Internetverbindung mehr bekommt , oder was auch immer der Grund ist, für das schlafen schicken und wieder reseten.
Ich habe ja schon öfter in den Foren gelesen, dass die Internetverbindung abbricht und dann nicht mehr aufgebaut werden kann. Beziehungsweise jedesmal dann ein Neustart des Arduinos nötig ist. Ist das der Grund für das schlafen schicken und wieder durch einen Reset auswecken?

Oder hat sich da einfach einer gespielt und das schlafen schicken ist unnötig?

Ich sehe da auch, dass der ESP durch diesen Neustart wirklich "neu startet". Also auch wieder durchs Setup läuft, Aber trotzdem den Zähler für die Neustarts nicht zurückstellt, weil diese Info im RTC Speicher gehalten wird.

Franz

PS: Also nochmal die Frage, ist das schlafen schicken und wieder aufwecken nötig, dass diese Geschichte ewig weiterlaufen kann, oder ist es unnötig und es hat sich da nur einer gespielt!

Entschuldigung. Ich habe vergessen das Programm anzuhängen. Das ist hier:

#include <WiFi.h>
#define SchlafZeit 3E7 // Mikrosekunden hier 3s
#define NTP_SERVER "de.pool.ntp.org"
#define TZ_INFO "WEST-1DWEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" // Western European Time
RTC_DATA_ATTR int bootZaeler = 0;   // Variable in RTC Speicher bleibt erhalten nach Reset
 
void ErsteStart()
{
  Serial.println("Start nach dem Reset");
  WiFi.mode(WIFI_STA);
  WiFi.begin("WlanName", "Pass");
  Serial.println("");
 
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Addresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("Hole NTP Zeit");
  struct tm local;
  configTzTime(TZ_INFO, NTP_SERVER); // ESP32 Systemzeit mit NTP Synchronisieren
  getLocalTime(&local, 10000);      // Versuche 10 s zu Synchronisieren
  WiFi.mode(WIFI_OFF);
}
 
void setup()
{
  esp_sleep_wakeup_cause_t wakeup_cause; // Variable für wakeup Ursache
  setenv("TZ", TZ_INFO, 1);             // Zeitzone  muss nach dem reset neu eingestellt werden
  tzset();
  Serial.begin(115200);
  Serial.println("");
  ++bootZaeler;
  Serial.println("Start Nr.: " + String(bootZaeler));
  wakeup_cause = esp_sleep_get_wakeup_cause(); // wakeup Ursache holen
  if (wakeup_cause != 3) ErsteStart();     // Wenn wakeup durch Reset
}
 
void loop()
{
  tm local;
  getLocalTime(&local);
  Serial.println(&local, "Datum: %d.%m.%y  Zeit: %H:%M:%S"); // Zeit Datum Print Ausgabe formatieren
  Serial.println("Deep Sleep - Gehe schlafen \r\n \r\n");   
 
  esp_sleep_enable_timer_wakeup(SchlafZeit);    // Deep Sleep Zeit einstellen
  esp_deep_sleep_start();                       // Starte Deep Sleep
}

Wenn du den ESP32 Schlafen legst, darfst du dich nicht wundern, oder?

Es ist ziemlich blödsinnig in voller loop Geschwindigkeit die Zeit zu besorgen,
das dient nur dazu, die Zugriffe weit auseinander zu legen, bzw. als Demo.

Einmal nach einem Rest und alle paar Stunden reicht völlig aus.

Macht es nicht, folgt man dem Kommentar:

Im Übrigen ist das ein unsigned const. Warum machst Du da ein define draus?

Kommt drauf an, was Du willst.

Mehr noch: der (externe) Zeitserver fühlt sich gefloodet und mag irgendwann nicht mehr und gibt keine Antwort :wink:

Absolut korrekt. :grinning:

Als Beispiel wäre eine Funktion zum Besorgen der Zeit,
die im setup aufgerufen wird, meiner Ansicht nach besser.

In dem Fall - reset nach TimeOut - ja.
Ich würde aber das reset schon weghauen und nur periodisch alle xx Minuten (ich glaube ptbtime hat irgendwann 3 Minuten Sperrzeit) die Zeit holen.
@Franz54
Und mal ehrlich: Jeder Router hat mittlerweile eine Funktion, die die Internetzeit bereit stellt... Da muss ich nicht wer weiss wohin meine Anfrage stellen.

statt

tut es da auch zum Beispiel

#define NTP_SERVER "fritz.box"

wenn du eine fritzbox hast
vgs

Nö.

Das verstehe ich jetzt nicht.

#include <time.h>                   // time() ctime()
time_t now;                         // this is the epoch
tm myTimeInfo;                      // the structure tm holds time information in a more convient way

const char* ntpServer = "fritz.box";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 7200;

void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(myTimeInfo.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(myTimeInfo.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(myTimeInfo.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(myTimeInfo.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(myTimeInfo.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(myTimeInfo.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(myTimeInfo.tm_wday);         // days since Sunday 0-6
  if (myTimeInfo.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");

  Serial.println();
}


void synchroniseWith_NTP_Time() {
  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");

  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    BlinkHeartBeatLED(OnBoard_LED, 100);
    delay(100);
    Serial.print(".");
  }
  Serial.print("\n time synchronsized \n");
  showTime();
}

funktoniert bei mir wunderbar.

vgs

Und bei mir nicht. Das brauch ich nicht mal ausprobieren.
Jetzt nochmal drüber nachdenken, warum das so sein könnte.

drüber nachgedacht habe ich und bin auch auf eine plausible Erklärungsmöglichkeit gekommen. Scheiben tu ich es trotzdem nicht

Ich poste lieber noch einen compilierenden Demo-Code.
Da sind wieder die functions drin die - na du weißt schon

#include <WiFi.h>

unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;

//const char *ssid     = "WLANBuero_EXT"; 
const   char *ssid     = "FRITZ!Box 7490";

const char *password = "";

const char* ntpServer = "fritz.box";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 7200;

#include <time.h>                   // time() ctime()
time_t now;                         // this is the epoch
tm myTimeInfo;                      // the structure tm holds time information in a more convient way

void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(myTimeInfo.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(myTimeInfo.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(myTimeInfo.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(myTimeInfo.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(myTimeInfo.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(myTimeInfo.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(myTimeInfo.tm_wday);         // days since Sunday 0-6
  if (myTimeInfo.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");
    
  Serial.println();
}

void connectToWifi() {
  Serial.print("Connecting to "); 
  Serial.println(ssid);

  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    BlinkHeartBeatLED(OnBoard_LED, 333);
    delay(332);
    Serial.print(".");
  }
  Serial.print("\n connected.");
  Serial.println(WiFi.localIP() );

}

void synchroniseWith_NTP_Time() {
  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");
  
  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    BlinkHeartBeatLED(OnBoard_LED, 100);
    delay(100);
    Serial.print(".");
  }
  Serial.print("\n time synchronsized \n");
  showTime();    
}


void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println(__FILE__);
  Serial.print( F("  compiled ") );
  Serial.print(__DATE__);
  Serial.print( F(" ") );
  Serial.println(__TIME__);  
}

boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();  
  if ( currentMillis - periodStartTime >= TimePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);
  
  if ( TimePeriodIsOver(MyBlinkTimer,BlinkPeriod) ) {
    digitalWrite(IO_Pin,!digitalRead(IO_Pin) ); 
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("\n Setup-Start \n");
  PrintFileNameDateTime();
  
  connectToWifi();
  synchroniseWith_NTP_Time();
}

void loop() {
  BlinkHeartBeatLED(OnBoard_LED,100);

  if ( TimePeriodIsOver(MyTestTimer,1000) ) {
    showTime();    
  }  
}

s

Ich sage nicht dass ich das Programm ohne Bremse laufen lassen würde. Ich würde sogar nur einmal am Tag den Zeitserver abfragen. Den Rest des Tages die Systemzeit benutzen.

DAS OBEN GEZEIGTE PROGRAMM HABE ICH NICHT GESCHRIEBEN, SONDERN ICH MÖCHTE DEN GRUND VERSTEHEN, warum der Autor immer die ZEit abfragt, dann den ESP schlafen legt und 30 Sekunden später wieder mit nem Reset startet, wieder die Zeit abfragt, und wieder schlafen legt. Ich muss ihn ja nicht schalfen legen, zwischen den Abfragezeiten. Das kann ich ja auch über Millis regeln. Oher wie ich es machen würde, einmal am Tag abfragen, ansonsten was anderes machen.

Ich will ja nur wissen ob es aus irgend einen Grund nötg ist, den ESP immer wieder neu zu starten.

Franz

Nicht trotzdem.
Und genau darum.

Warum fragst Du nicht den Autor?

@Franz54

Wenn der code so wäre das nur bei jedem zweiten Aufwachen die Zeit neu synchronisiert würde dann würde das demonstrieren das die im ESP32 eingebaute RTC auch im deep-sleepmodus weiterläuft.

@my_xy_projekt: sigh!

ICH mache gar nichts daraus! Ich habe das Programm so aus dem Netz und möchte den Sinn vestehen. Und es sind def. 30 Sekunden zwischen den Zeitabfragen, wo der ESP pennt.

Weil hier vielleicht auch jemand den Grund kennt.

Doch.
Du hast keine Fremdquelle angegeben. Damit ist es DEIN Code.

Aber es ist müssig.
Mittlerweile ist bekannt, das Du irgendwo irgendwas kopiert hast.

Ja.
Du weisst jetzt auch, was ein Example ist.
Das ist wie die Diskussion um das delay() in den Examples - ja dafür geht das.
In einer Anwendung wohl eher kontraproduktiv.

Ja, das wäre auch mal zu testen. Komme ich vielleicht mal darauf zurück.

Ich denke ich habe gleich im ersten Satz deutlich geschrieben, dass ich mir das Programm nur zum lernen / testen vorgenommen habe. Und gerne den Sinn verstehen würde. Ich würde ja wohl nicht nach dem Sinn eines Programmes fragen, das ich geschrieben habe.