Sommerzeit - Winterzeit - wie anpassen

Hallo,

mal wieder ein kleines - eher taktisches - Problem.
Ich habe in meinem Datenlogger mit dem NODEMCU eine RTC DS 1307 drin. Die RTC wird beim Programmstart (SETUP) über mein WLAN (wenn in Reichweite) mit einem NTP-Server gestellt. Alle 30 Minuten wird dann mit Datum und Zeit ein Datensatz auf eine SD geschrieben. So weit so gut, funktioniert auch.
Jetzt möchte ich auf Sommer/Winterzeit umschalten. Und da hänge ich gerade ein wenig. Funktion zur SZ/WZ-Erkennung habe ich, geht auch. Aber wie stelle ich um? Soll ich die RTC umstellen oder erst bei der Anzeige oder beim Speichern auf SD die Stunde dazu- oder wegnehmen?
Wenn ich die RTC umstelle ist es kritisch wenn der NTP-Server nicht erreichbar ist. Dann fehlt sozusagen ein definierter Startwert.
Einfacher wäre es die Stunde immer bei dem Aufruf zu korrigieren: Wenn Sommerzeit dann Stunde+1, sonst lassen. Wie könnte ich das machen?
Zeit frage ich so ab:

#include "DS1307RTC.h"                                              // Uhr

RTC_DS1307        rtc;                                                  // RTC-Modul


-------------------------------------------------------------


String F_Zeit(bool Sekunden)                                        // liefert Zeit als Std:Min und evtl. Sekunden
{
  RTC.read(tm);

  if (Sekunden)                                                    // wenn true Sekunden zurück
  {
    return (printDigits(tm.Hour) + ":" + printDigits(tm.Minute) +
            ":" + printDigits(tm.Second));
  }
  return (printDigits(tm.Hour) + ":" + printDigits(tm.Minute));
}

printDigits() macht bei einer einstelliger Zahl einfach eine 0 davor dass es schöner aussieht.

Wie kann ich da die Stunde ändern? Wenn ich zu tm.Hour einfach 1 dazuzähle geht es soweit, nur bei 0 Uhr gibt es 24 Uhr und noch das "gestrige" Datum. Und das sieht doof aus.
Wäre schön wenn jemand dazu was hätte.....

Ich arbeite ebenfalls an dem Problem, habe auch noch keine finale Lösung. Aus meiner Sicht ist es sinnvoll die Zeit in der RTC neu zu setzen- und um den Wechsel zur Winterzeit nur einmal durchzuführen am besten einen Marker ins EEprom setzen, der klar definiert, ob schon auf Winterzeit umgestellt wurde oder nicht...

Hallo uk1408,

eigentlich werden bei Datenaufzeichnungen keine Zeitveränderungen vorgenommen. Ich weiß, im DIY Bereich "macht das doch jeder", aber dies ist nicht richtig.

Zurück zu deinem Problem, eine "Umrechnung" und Zeitsynchronisation gleichzeitig funktioniert nicht so einfach. Schließlich musst du deiner Umrechnung auch sagen ob eine externe Umstellung auf MESZ funktioniert hat oder nicht. Denn wenn umgestellt wurde, dann darf ja keine Stunde mehr dazugezählt werden.

Lösungsvorschlag, such dir einen Zeitserver welcher immer nur MEZ oder UTC zur Verfügung stellt und dann wird entweder immer ohne Umrechnung gespeichert oder die Umrechnung muss halt immer alle Daten beinhalten, also wenn Std. 24 dann Std. null und Datum plus eins usw..

Ach ja, wenn möglich tausche die Uhr gegen eine DS3231. Bei günstigem Wohnort vielleicht auch gleich noch ein DCF77 Modul integrieren.

Gruß

MiReu

Ich tüftle gerade an sowas ähnliches.
Der Data-Logger soll alle 5 Minuten versuchen, sich mit einem mitgetragenes Access-Point am Handy zu verbinden, was i.d.R. mislingt, weil ich abwesend bin.
Wenn ich (ca. monatlich) die Stationen besuche, wird die Uhrzeit synchronisiert und der Data-Logger copiert seine Daten par FTP auf dem Server, sonst tickt die Solar-Powered-Station autonom für sich und sammelt Daten.

Ich bin aber mit dem Programmieren noch nicht so weit, warte noch auf die bestellte HW...

Könntest Du Dein Code veröffentlichen?
Danke

Schließe mich MiReu an. Lokale Zeiten haben bei sowas nichts verloren. In UTC speichern und gut ist es.

Ansonsten schau Dir hier mal den Code von Jurs an.

Gruß Tommy

So,
erst mal danke für die rege und rasche Beteiligung. Dies scheint doch auch noch andere zu betreffen.
@MiReu: Ich mache nicht nur Datenaufzeichnung sondern zeige die Werte und die Zeit auf einem Display. Und da macht sich dann die "richtige" Zeit ganz gut. Und ich möchte einfach auch wissen ob das geht....
@MaHa76: Das mit einem Flag habe ich ja gemacht, aber das wurde mit irgendwann zu unübersichtlich.....
@RIN67630: Mein Sketch hat ca. 1400 Zeilen, ich glaube das ist etwas lang für hier.
@Tommy56: Den Sommerzeitcode von Jurs habe ich verwendet...

Zwischenzeitlich habe ich dann noch etwas gegoogelt (ja, das kann ich auch :slight_smile: ) und ein wenig probiert und bin auf folgendes gekommen:

//----------------------------------------------
String F_Datum()                                                   // Datum strukturiert Tag.Mon.Jahr
{
  DateTime jetzt = RTC.get();                                      // Uhrzeit aus RTC

  if (summertime_EU())
  {
    setTime(jetzt.unixtime() + 3600);                              // Sommerzeit + 1 Stunde
  }
  else
  {
    setTime(jetzt.unixtime());                                     // lassen
  }
  time_t t = now();                                                // temporäres Zeitelement

  return (printDigits(day(t)) + "." + printDigits(month(t)) + "." + year(t));
}
//----------------------------------------------
String F_Uhr(bool Sekunden)                                        // liefert Zeit als Std:Min und evtl. Sekunden
{
  DateTime jetzt = RTC.get();                                      // Uhrzeit aus RTC
  if (summertime_EU())                                             // wenn Sommerzeit
  {
    setTime(jetzt.unixtime() + 3600);                              // Sommerzeit + 1 Stunde
  }
  else
  {
    setTime(jetzt.unixtime());                                     // lassen
  }
  time_t t = now();                                                // temporäres Zeitelement
  String RetString = (printDigits(hour(t)) + ":" + printDigits(minute(t)));
  if (Sekunden)                                                    // wenn true mit Sekunden zurück
  {
    RetString += ":" + printDigits(second(t));
  }
  return (RetString);
}
//----------------------------------------------------
boolean summertime_EU()
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
{
  RTC.read(tm);
  int year     = tm.Year;
  byte month   = tm.Month,
       day     = tm.Day,
       hour    = tm.Hour,
       tzHours = 1;                                                // Timezone MEZ oder UT

  if (month < 3 || month > 10) return false;                       // keine Sommerzeit in Jan, Feb, Nov, Dez
  if (month > 3 && month < 10) return true;                        // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
  if (month == 3 && (hour + 24 * day) >= (1 + tzHours + 24 * (31 - (5 * year / 4 + 4) % 7))
      || month == 10 && (hour + 24 * day) < (1 + tzHours + 24 * (31 - (5 * year / 4 + 1) % 7)))
    return true;
  else
    return false;
}
// --------------------------------------------------------------------
String printDigits(int Zahl)                                       // einstellige Zahl mit 0 ergänzen (9 wird 09) und als String zurückgeben
{
  String Z = "";
  if (Zahl < 10)
  {
    Z = "0";
  }
  Z = Z + String(Zahl, DEC);
  return Z;
}

Ich lass jetzt die RTC immer auf NTP-Zeit mit der richtigen Zeitzone laufen und rechne immer beim Aufruf von Zeit oder Datum um. Der Code ist vielleicht etwas umständlich aber es funktioniert. Für Optimierungen bin ich immer dankbar....

Ich würde die RTC auf UTC laufen lassen und für's Anzeigen umrechnen. Rule auf thumb: solange wie möglich auf einer sauberen Basis arbeiten und on the fly auf andere Einheiten umrechnen, wenn's die Rechenleistung zulässt.

Die Frage ist auch immer: Wie genau ist genau genug?
Hängt natürlich immer von der Anwendung ab. Für - sagen wir zum Beispiel - eine Heim-Wetterstation ist eine geforderte Genauigkeit im Millisekundenbereich möglicherweise etwas übertrieben :slight_smile:

Die Auswahl der richtigen RTC spielt jedenfalls eine wichtige Rolle.
Es wurde ja schon erwähnt, dass eine DS1307 eher ungenau ist. Meine Erfahrung: +/- mehrere Minuten pro Jahr und noch mehr wenn die Temperatur stark schwankt.

Eine DS3231 ist viel genauer. Meine Erfahrung: +/- niedriger einstelliger Sekundenbetrag pro Jahr (ich habe mehrere davon schon länger im Einsatz).
Mir würde das wahrscheinlich für die meisten Datalogging-Einsätze, die mir so einfallen im Privatbereich, reichen. Und damit erspare ich mir kompliziertes Synchronisieren :slight_smile:

Die DS3231 kann ich wirklich empfehlen und sie läuft mit einer Knopfzelle auch ohne externe Stromversorgung mehrere Jahre.

Na wenn es "nur" um die Anzeige in "Echtzeit" geht, dann ist das Ganze doch ganz einfach.

Die Zeitumstellung wird nur auf die Anzeigewerte beschränkt. Uhr und Aufzeichnung laufen ganz normal mit MEZ. Dann brauchst du keine Speicherung von wegen "Uhr ist umgestellt...".

Natürlich kannst du auch vor dem Speichern die Zeit "richtigstellen" lassen, ich würde die Routine aber in den Anzeigeteil schreiben, macht das ganze Programm schneller bzw. bremst es weniger aus (Oder war die Anzeige der Daten auf einem anderen Gerät? Hab ich vergessen und auch jetzt nicht noch mal nachgelesen.)

Gruß

MiReu