Daten aus einem struct auslesen, um etwas zu vergleichen

Ich habe das Problem dass ich es nicht auf die Reihe bekomme, aus dem "struct tm local" was rauszulösen um es nummerisch zu vergleichen. Also das Programm hier unten, indem ich mit einer if - Abfrage schauen muss, ob ich zwischen 00:00 Uhr und 00:01 Uhr habe, um den NTP Server neu abzufragen. Ich benutze ja hier die Time.h Lib. nicht, dadurch weiß ich nicht wo ich eingreifen könnte :roll_eyes:

Hier das Programm dazu:

#include <WiFi.h>
//#define NTP_SERVER "de.pool.ntp.org"
#define NTP_SERVER "Fritz.Box"
#define TZ_INFO "WEST-1DWEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" // Western European Time

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
byte zaehler = 0;
const unsigned long Tag = ((1000 * 60) * 60) * 24UL;
unsigned long laufzeit = Tag;
unsigned long aktuellzeit;
//---------------------Setup---------------------------
void setup()
{
  lcd.begin();
  lcd.backlight();
  Serial.begin(9600);
  lcd.setCursor (0, 0);
  lcd.print (F(" NTP Server Abfrage "));
}
//---------------------LOOP---------------------------
void loop()
{
  aktuellzeit = millis();

  tm local;
  getLocalTime(&local);
  lcd.setCursor (0, 2);
  lcd.print(&local, "   Datum: %d.%m.%y");
  lcd.setCursor (0, 3);
  lcd.print(&local, "   Zeit:  %H:%M:%S");
  if (aktuellzeit - laufzeit >= Tag)
  {
    NTP_Zeit();
    laufzeit = aktuellzeit;
  }
}
//----------------WIFI Verbindung---------------------
void NTP_Zeit()
{
  lcd.setCursor (0, 1);
  lcd.print(F("Zeitserver verbinden"));
  WiFi.mode(WIFI_STA);
  WiFi.begin("Name", "Password");

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
  lcd.setCursor (0, 1);
  lcd.print(F("++ 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);
  lcd.setCursor (0, 1);
  lcd.print(F(" NTP Zeit abgefragt "));
}

Sehr erstaunlich, dass deine LCD Bibliothek so etwas können soll.

Da habe ich auch gestaunt. Habe es einfach mal so probiert. Das funktioniert schon.

Print.h ist auf einem ESP leistungsfähiger

    size_t print(struct tm * timeinfo, const char * format = NULL);

das "struct tm" enthält die folgenden Attribute

Member Type Meaning Range
tm_sec int seconds after the minute 0-60*
tm_min int minutes after the hour 0-59
tm_hour int hours since midnight 0-23
tm_mday int day of the month 1-31
tm_mon int months since January 0-11
tm_year int years since 1900
tm_wday int days since Sunday 0-6
tm_yday int days since January 1 0-365
tm_isdst int Daylight Saving Time flag
1 Like

überlass das doch dem ESP.
Setz einfach den Abfrageintervall.

uint32_t sntp_update_delay_MS_rfc_not_less_than_15000 ()
{
  return 24 * 60 * 60 * 1000UL; 
}

zum Nachlesen:
https://werner.rothschopf.net/202011_arduino_esp8266_ntp_en.htm

so

// Anzahl der Sekunden seit Mitternacht
uint32_t nbSek = 3600ul * local.tm_hour + 60ul * local.tm_min + local.tm_sec;
if (nbSek <= 60) { // zwischen 00:00 Uhr und 00:01 Uhr
  ...
}

Danke, wieder was gelernt.

dann ist es ein guter tag! :wink:

Ich bin leider viel zu langsam für dieses Forum :flushed:

Nur um guten Willen zu demonstrieren noch meine simple Variante:

void loop()
{
  aktuellzeit = millis();

  tm local;
  getLocalTime(&local);

  lcd.setCursor (0, 0);
  lcd.print(local.tm_hour);
  lcd.print(" ");
  lcd.print(local.tm_min);
  lcd.print(" ");
  lcd.print(local.tm_sec);
  lcd.print(" ");
  if (local.tm_sec == 0) lcd.print("   *      ");
  if (local.tm_sec == 30) lcd.print("   +      ");

  lcd.setCursor (0, 2);
  lcd.print(&local, "   Datum: %d.%m.%y");
  lcd.setCursor (0, 3);
  lcd.print(&local, "   Zeit:  %H:%M:%S");
  if (aktuellzeit - laufzeit >= Tag)
  {
    NTP_Zeit();
    laufzeit = aktuellzeit;
  }
}

Welche LiquidCrystal_I2C Bibliothek verwendest Du. Denn meine über den Bibliotheksverwalter installierte gibt mir eine Warnung bezüglich ESP32.

Auch von mir vielen Dank an euch hier :smiley:

Ich habe das dann mal so geändert:

#include <WiFi.h>
//#define NTP_SERVER "de.pool.ntp.org"
#define NTP_SERVER "Fritz.Box"
#define TZ_INFO "WEST-1DWEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" // Western European Time

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
byte zaehler = 0;
//---------------------Setup---------------------------
void setup()
{
  lcd.begin();
  lcd.backlight();
  Serial.begin(9600);
  lcd.setCursor (0, 0);
  lcd.print (F(" NTP Server Abfrage "));
}
//---------------------LOOP---------------------------
void loop()
{
  tm local;
  getLocalTime(&local);
  lcd.setCursor (0, 2);
  lcd.print(&local, "   Datum: %d.%m.%y");
  lcd.setCursor (0, 3);
  lcd.print(&local, "   Zeit:  %H:%M:%S");
  if (zaehler == 0)
  {
    NTP_Zeit();
    zaehler = 1;
  }
  uint32_t nbSek = 3600ul * local.tm_hour + local.tm_min * 60ul + local.tm_sec;
  if (nbSek <= 60) // zwischen 00:00 Uhr und 00:01 Uhr
  {
    NTP_Zeit();
  }
}
//----------------WIFI Verbindung---------------------
void NTP_Zeit()
{
  lcd.setCursor (0, 1);
  lcd.print(F("Zeitserver verbinden"));
  WiFi.mode(WIFI_STA);
  WiFi.begin("Name", "Password");

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
  lcd.setCursor (0, 1);
  lcd.print(F("++ 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);
  lcd.setCursor (0, 1);
  lcd.print(F(" NTP Zeit abgefragt "));
}

Das mit dem if (zaehler == 0) ist nur drin, dass er bei Neustart eine erste Zeit Aktualisierung macht.

Danke euch
Franz

Randnotiz:

auf einem ESP ist es in Ordnung, so zu schreiben

weil ein int 4 Byte lang ist.

Aber es ist besser, sich das Schreiben anzugewöhnen

const unsigned long Tag = ((1000UL * 60UL) * 60UL) * 24UL;

um zu erzwingen, dass alle Multiplikationen unsigned long verwenden

oder erzwinge zumindest den Typ des ersten Multiplikanden

const unsigned long Tag = 1000UL * 60 * 60 * 24;

Geht nicht auch ein Aufruf von NTP_Zeit(); in setup? Nur so als Anregung.

OK. Da habe ich nicht so genau hingesehen, weil das nur eine Übergangslösung war. :slightly_frowning_face: Ich dachte weil ich UL am Ende stehen habe, gilt es für alle Zahlen in der Reihe :roll_eyes:

62 posts were split to a new topic: Welche LiquidCrystal_I2C Lib benutze ich?

Ich habe auf anfrage von Franz54 diese Diskussion geteilt weil das Tema sich geändert hat.
Bitte hier wegen struct weiterschreiben
und Welche LiquidCrystal_I2C Lib benutze ich? - International / Deutsch - Arduino Forum wegen der Bibliotheksungereimtheiten.
Grüße Uwe

1 Like

Vielen Dank, dass du dir diese Arbeit gemacht hast.
Jetzt ist das wieder eine Linie. Wäre schade ums Thema gewesen. Ich habe da auch noch ein Problem wo ich gerne die Lösung dazu hätte :roll_eyes: J-M-L hat mir da ganz toll weitergeholfen, und eigentlich kann man mit der Info ja jetzt weiter arbeiten. Aber eines würde mich noch interessieren. Wo wird diese Aufteilung gemacht.
|Member |Type| Meaning |Range|
|tm_sec |int |seconds after the minute |0-60*|
|tm_min |int |minutes after the hour |0-59|
|tm_hour |int |hours since midnight |0-23|
|tm_mday |int |day of the month |1-31|
|tm_mon |int |months since January |0-11|
|tm_year |int |years since 1900 ||
|tm_wday |int |days since Sunday |0-6|
|tm_yday |int |days since January 1 |0-365|
|tm_isdst |int |Daylight Saving Time flag ||

Was werkelt da wo im Hintergrung, dass ich die enzelnen Daten vom "struct tm local" so schön abgreifen kann? :slightly_frowning_face:

Hier mal das aktuelle Programm:

#include <WiFi.h>
//#define NTP_SERVER "de.pool.ntp.org"
#define NTP_SERVER "Fritz.Box"
#define TZ_INFO "WEST-1DWEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" // Western European Time

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//---------------------Setup---------------------------
void setup()
{
  lcd.begin();
  lcd.backlight();
  Serial.begin(9600);
  lcd.setCursor (0, 0);
  lcd.print (F(" NTP Server Abfrage "));
  NTP_Zeit();
}
//---------------------LOOP---------------------------
void loop()
{
  tm local;
  getLocalTime(&local);
  lcd.setCursor (0, 2);
  lcd.print(&local, " Datum:    %d.%m.%y");
  lcd.setCursor (0, 3);
  lcd.print(&local, " Zeit :    %H:%M:%S");
  /*
    struct tm enthält diese Atribute:
    ===============================================
    Member   Type  Meaning                   Range
    tm_sec   int   seconds after the minute  0-60*
    tm_min   int   minutes after the hour    0-59
    tm_hour  int   hours since midnight      0-23
    tm_mday  int   day of the month          1-31
    tm_mon   int   months since January      0-11
    tm_year  int   years since 1900
    tm_wday  int   days since Sunday         0-6
    tm_yday  int   days since January 1      0-365
    tm_isdst int   Daylight Saving Time flag
    ==============================================
  */
  //00:00:XX = 3600(=1 Std) * std = 0 + min = 0 * 60 = 0 + sec = maximal 59 sec
  uint32_t nbSek = 3600ul * local.tm_hour + local.tm_min * 60ul + local.tm_sec;
  if (nbSek <= 2) // zwischen 00:00:00 Uhr und 00:00:59 Uhr Zeit vom NTP holen
  {
    NTP_Zeit();
  }
}
//----------------WIFI Verbindung---------------------
void NTP_Zeit()
{
  lcd.setCursor (0, 1);
  lcd.print(F("Zeitserver verbinden"));
  WiFi.mode(WIFI_STA);
  WiFi.begin("Name", "Passwort");
  while (WiFi.status() != WL_CONNECTED) // Ist WLAN Connect?
  {
    delay(500);
  }
  lcd.setCursor (0, 1);
  lcd.print(F("++ 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);
  lcd.setCursor (0, 0);
  lcd.print(&local, " vom %d.%m um %H:%M ");
  lcd.setCursor (0, 1);
  lcd.print(F("---------------------"));
}

https://en.cppreference.com/w/cpp/chrono/c/tm
Alternativ:
https://www.nongnu.org/avr-libc/user-manual/structtm.html

Beim ESP32 wohl hier:
packages\esp32\hardware\esp32\1.0.6\tools\sdk\include\newlib\time.h

struct tm
{
  int	tm_sec;
  int	tm_min;
  int	tm_hour;
  int	tm_mday;
  int	tm_mon;
  int	tm_year;
  int	tm_wday;
  int	tm_yday;
  int	tm_isdst;
#ifdef __TM_GMTOFF
  long	__TM_GMTOFF;
#endif
#ifdef __TM_ZONE
  const char *__TM_ZONE;
#endif
};

Ja genau, das dachte ich am Anfang auch. Aber diese Time.h Lib benutze ich nicht. Nur die WiFi.

Franz

dies ist die Folge der Konfiguration

#define NTP_SERVER "Fritz.Box"
... 
configTzTime(TZ_INFO, NTP_SERVER); // ESP32 Systemzeit mit NTP Synchronisieren

➜ Vorausgesetzt, Ihr ESP hat Zugriff auf den NTP-Server, wird eine Hintergrundaufgabe die Zeit beibehalten
(Bietet Fritz.Box einen NTP-Server an?)