Jahreszahlformat - RTC Winterzeit-Sommerzeit

Hallo,

ich bin gerade dabei die Sache mit der RTC anzupassen und nutze dafür den Code von jurs.
Danke erstmal dafür. 1A.

Jetzt bin ich beim testen, ob die Winter/Sommerzeit Feststellung bei mir funktioniert, auf ein Problem gestoßen.
Übergibt man der Funktion die Jahreszahl 4stellig, ist alles i.O.
Übergibt man der Funktion die Jahreszahl 2stellig, funktioniert sie nicht mehr.
Warum?
Die Berechnung der Hilfsvariablen x1 und x2 wird doch unabhängig von allen anderen vorgenommen.
Mit der alten Funktion funktioniert das auch 2stellig.

Und warum werden die Funktionsvariablen year, month, day und hour in der IDE rot dargestellt?
Würde doch bedeuten, diese Namen werden von der IDE intern schon verwendet?

/*
Arduino Mega2560
I2C RTC DS3231
*/

#include <Wire.h>
#define ds3231_adress  0x68   // Adresse

// boolean i2c_status;

int Sekunde, Minute, Stunde, Wochentag, Tag, Monat, Jahr;

void setup()
{
  Wire.begin();
  Serial.begin(57600);
  
}

void loop()
{
 
 
 if (read_DS3231 (ds3231_adress) == true)     // wenn Fehlerstatus "wahr", dann
   {
    Serial.println("DS3231 I2C Busfehler");
   }
   else                                       // wenn kein Busfehler, dann
     { 
      if (Sommerzeit_aktiv(Jahr, Monat, Tag, Stunde) == true)
        {                                     // wenn Sommerzeit, dann
         Serial.print("Sommerzeit"); Serial.print("\t");
         Stunde = Stunde + 1;                 // Sommerzeitkorrektur   
         if (Stunde >=24) 
           {
            Stunde = 0;
            Tag = Tag + 1;
           }
        }
        else
          {                                  
           Serial.print("Winterzeit"); Serial.print("\t");
          }          
      Serial.print(Stunde);  Serial.print("\t");
      Serial.print(Minute); Serial.print("\t");
      Serial.print(Sekunde); Serial.print("\t");
      Serial.print(Tag); Serial.print("\t");
      Serial.print(Monat); Serial.print("\t");
      Serial.print(Jahr); Serial.print("\n");
     }
  
 delay(1000);
}
 
 
boolean read_DS3231 (int i2c_adresse)
{
  boolean error = false;                   // Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse);     // Connect
  Wire.write(0);                           // Anfrage ab/der Register Nummer
  if (Wire.endTransmission() > 0 )         // war Connect fehlerfrei?
   { 
    error = true;                          // I2C Busfehler
    return error;                          // Abruch
   } 
   
  Wire.requestFrom(i2c_adresse, 7);        // 7 Bytes in Folge anfordern/lesen

  if (Wire.available() > 0 )               // sind Daten vorhanden?
    {
     Sekunde   = bcdToDec(Wire.read() & 0x7F);  // Maske für die ersten 7 Bits alleine
     Minute    = bcdToDec(Wire.read() );
     Stunde    = bcdToDec(Wire.read() & 0x3F);  // Umschaltung auf 24h statt 12h (AM/PM)
                          Wire.read();          // wäre der Wochentag
     Tag       = bcdToDec(Wire.read() );             
     Monat     = bcdToDec(Wire.read() );
     Jahr      = bcdToDec(Wire.read() ) + 2000;
    }    
}


boolean Sommerzeit_aktiv (int year, int month, int day, int hour)
// ausgehend das die RTC in der Zeitzone UTC+1, also "Winterzeit Berlin" dauerhaft läuft
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour
// return value: returns true during Daylight Saving Time, false otherwise
{ 
  static int x1,x2, lastYear; // Zur Beschleunigung des Codes ein Cache für einige statische Variablen
  int x3;
  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
  // der nachfolgende Code wird nur für Monat 3 und 10 ausgeführt
  // Umstellung erfolgt auf Stunde utc_hour=1, in der Zeitzone Berlin entsprechend 2 Uhr MEZ
  // Es wird ein Cache-Speicher für die Variablen x1 und x2 verwendet, 
  // dies beschleunigt die Berechnung, wenn sich das Jahr bei Folgeaufrufen nicht ändert
  // x1 und x2 werden nur neu Berechnet, wenn sich das Jahr bei nachfolgenden Aufrufen ändert
  if (year!= lastYear) 
    { // Umstellungsbeginn und -ende
     x1= 1 + 1 + 24*(31 - (5 * year /4 + 4) % 7);  
     x2= 1 + 1 + 24*(31 - (5 * year /4 + 1) % 7);
     lastYear=year;
   }  
  x3= hour + 24 * day;
  if (month==3 && x3>=x1 || month==10 && x3<x2) return true; else return false;
}



/* Sommerzeit Korrektur, ausgehend das die RTC in der Zeitzone UTC+1, also Winterzeit Berlin dauerhaft läuft
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour 
// return value: returns true during Daylight Saving Time, false otherwise  */
/*
boolean Sommerzeit_aktiv()
{
  if (Monat<3 || Monat>10) return false;  // keine Sommerzeit in Jan, Feb, Nov, Dez
  if (Monat>3 && Monat<10) return true;   // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
  if (Monat==3 && (Stunde + 24 * Tag)>=(2 + 24*(31 - (5 * Jahr /4 + 4) % 7)) || Monat==10 && (Stunde + 24 * Tag)<(2 + 24*(31 - (5 * Jahr /4 + 1) % 7)))
    return true;
  else
    return false;
}   
*/

byte bcdToDec(byte val)  // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert binary coded decimal to decimal number
// Hilfsfunktion für die Echtzeituhr
{
  return ( (val/16*10) + (val%16) );
}

Doc_Arduino:
ich bin gerade dabei die Sache mit der RTC anzupassen und nutze dafür den Code von jurs.
Danke erstmal dafür. 1A.

Du nutzt offenbar einen modifizierten Code von jurs.
Mein Code war leicht wiederverwertbar, weil er die zur Berechnung notwendigen Parameter beim Funktionsaufruf übergeben bekommen hat. Außerdem hat mein Code die Zeitzone berücksichtigt, so daß man sowohl eine UTC-Zeit (timezone=0) eine "Winterzeit" (timezone=1) oder eine Sommerzeit (timezone=2) übergeben konnte und man hat das richtige Ergebnis erhalten. Das ist nach Wegrationalisierung der timezone irgendwie nicht mehr der Fall.

Dein Code nutzt nun globale Variablen zur Berechnung innerhalb der Funktion.
Kann man machen, aber dann muss man immer aufpassen, womit man rechnet.

Doc_Arduino:
Übergibt man der Funktion die Jahreszahl 4stellig, ist alles i.O.
Übergibt man der Funktion die Jahreszahl 2stellig, funktioniert sie nicht mehr.
Warum?

So auf den ersten Blick sage ich mal: Die Funktionen liefern dieselben Ergebnisse, wenn sie mit denselben Werten rechnen. Allerdings rechnet die eine Funktion mit einer globalen Variablen "year" und die andere mit einer globalen Variablen "Jahr".

Und die Funktion, die mit der globalen Variablen "Jahr" rechnet, rechnet immer mit vierstelligen Jahreszahlen, weil die Variable Jahr durch Auslesen der RTC wie folgt erzeugt wird:

Jahr      = bcdToDec(Wire.read() ) + 2000;

Eine Berechnung mit einer zweistelligen Jahreszahl sehe ich nicht.
Also wieso soll es ein Problem geben? Und welches Problem genau, hast Du ein Beispiel?

Doc_Arduino:
Und warum werden die Funktionsvariablen year, month, day und hour in der IDE rot dargestellt?
Würde doch bedeuten, diese Namen werden von der IDE intern schon verwendet?

Das bedeutet, dass Du irgendeine Library installiert hast, die diese Variablennamen als Keywords deklariert hat. Ob diese Namen für irgendwas anderes auch tatsächlich verwendet werden, darüber sagt das nichts aus. Das sagt nur aus, dass Du gerade ein Keyword hingeschrieben hast. Der Arduino-Editor ist recht trivial gestrickt.

Du nutzt offenbar einen modifizierten Code von jurs

Der orginale Code von jurs schaut wohl so aus:

/*-------- utility code from jurs ----------*/
boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
{
  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;
}

Hallo jurs,

stopp, dass läuft etwas in die falsche Richtung. Das ist alles Dein Code, legal modifiziert. :wink: Dort wo ich den her habe, hast Du selbst geschrieben das man „tzHours“ noch wegrationalisieren kann um ein Byte einzusparen. Wenn man weis in welcher konstanten Zeitzone die Uhr läuft. Ohne das man die Uhr selbst um die Stunde +/- stellt. Das habe ich gemacht. Nichts weiter.

Meine modifizierte RTC DS3231 Funktion von Dir nutzt globale Variablen, ja, aber nur am Ende zur Anzeige. Und eben dann zur Korrektur der Stunde Sommerzeit/Winterzeit an anderer Stelle.

Die neue schnellere „Sommerzeit_aktiv“ Funktion nutzt weiterhin nur lokale Variablen. Ist nur um tzHours „gekürzt“.

Die alte „Sommerzeit_aktiv“ Funktion unten drunter, die auskommentiert ist, nutzt globale Variablen. Hier habe ich nur die Namen der Variablen vorbeugend geändert, weil die rot markiert wurden. Die Funktion ist ansonsten unverändert. Um die geht es jedoch nicht.

Ich hatte die ganze Zeit mit der alten Funktion die Jahreszahl 2stellig. Hat funktioniert.

Jahr = bcdToDec(Wire.read() );

Mit der neuen Sommerzeit Funktion funktioniert es mit 2stelliger Jahreszahl nicht mehr. Deshalb habe ich die Codezeile um +2000 ergänzt.

Meine Frage war jetzt, gibt es einen ersichtlichen Grund warum die Formel mit 2stelliger Jahreszahl anders rechnet?

Wenn ich die Uhr auf 30.03.2014 01:59 stelle und warte bis es 2 Uhr wird, dann „stellt“ sie sich einfach nicht auf 3 Uhr. Die Funktion liefert weiterhin „false“ zurück. Ist die Jahreszahl 4stellig, funktioniert alles und liefert dann „true“ zurück.

Ich hoffe das Problem ist jetzt klarer beschrieben? :wink:

Wenn es nur noch mit 4stelliger Jahreszahl funktioniert, dann muß ich eben damit leben. Nur wollte ich gern wissen warum es plötzlich mit 2stelliger nicht mehr funktioniert. Muß ja einen Grund haben. :~

Wünsche noch schöne Oster Feiertage ...

@ rudirabbit:
das war etwas Quatsch, wa Du rauskopiert hast. Das ist der "alte" Code. Ich verlinke mal den eigentlichen Thread, muß jeder selber komplett lesen um was es geht. Da wird auch viel erklärt zu dem Code. Sommerzeitumstellung - Deutsch - Arduino Forum

Hallo,

hab das mal versucht mit Excel nachzustellen und dann händisch zu rechnen, weil der µC Ganzzahlen abschneidet.

Folgende µC Formel
__ErsterTagSzMaerz= 31 - (5 * year /4 + 4) % 7; __
wäre in Excel
=31-REST(5*year/4+4;7)
dabei lande ich mit year=2014 bei
=31-REST(5*2014/4+4;7)
=31-2521,5 modulo 7

Jetzt wird im µC abgeschnitten, weil wir mit Ganzzahlen arbeiten, dann müßte es aus Sicht des µC lauten
=31-2521 module 7 ergibt einen Rest von 1 (360*7=2520)
=31-1
= 30 Das wäre dann der 30.03.2014, paßt.

Wenn ich mit 14 statt 2014 als year rechne, wäre das wie folgt
=31-REST(5*14/4+4;7)
=31-21,5 modulo 7
=31-21 module 7 ergibt einen Rest von 0
= 31 - 0
= 31 Das wäre dann fälschlicherweise der 31. statt der 30.

Die Formel vom "alten" Code lautet (2 + 24*(31 - (5 * Jahr /4 + 4) % 7))
= 2 + 24*(31 - (5 * 2014 /4 + 4) % 7)
= 2 + 24 * 2521 % 7
= 2 + 24 * (31-1)
= 722

mit Jahr 14 statt 2014
= 2 + 24*(31 - (5 * 14 /4 + 4) % 7)
= 2 + 24 * 21 % 7
= 2 + 24 * (31-0)
= 746 kommt auch was anderes raus

Der Vergleich im Code wäre ausgerechnet für den Fall am 30.März 2014 auch 722 >= ...

Da muß ich einen Test mit den Sketchen und Uhr stellen vergessen haben. Entschuldigung für die Aufregung.
Erkenntnis daraus. Man muß in beiden Sommerzeit_aktiv Funktionen Jahreszahlen 4stellig verwenden bzw. der Funktion übergeben.

Nicht das ich daraufhin falsch verstanden wurden bin. Ich wollte nicht die tolle Funktion in Frage stellen, sondern nur wissen warum beide Funktionen, fälschlicherweise angenommen, verschieden rechnen. Das hat sich damit geklärt.

Jetzt könnte ich natürlich noch in die Funktion eine Abfrage einbauen ob die Jahreszahl 2 oder 4stellig ist. Das macht aber keinen Sinn, weil dann wieder unnötige Rechenzeit verloren geht, die einfach auch sinnlos ist. Ich verwende jetzt 4stellige Jahreszahlen und gut ist.

Danke jurs nochmal für die tollen Funktionen rund um die Uhrzeit. :slight_smile:

Hallo,
ich habe eine Frage zum Wert der Variablen tzHours.
Ist der Wert für Deutschland immer auf 1 (für UTC+1) zu setzen oder wird bei Sommerzeit der Wert auf 2 (für UTC+2) gestellt?

rudirabbit:
Der orginale Code von jurs schaut wohl so aus:

/*-------- utility code from jurs ----------*/

boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
{
 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;
}

Kurz noch etwas zum Hintergrund meiner Frage.
Ich empfange über eine serielle Schnittstelle ein Datentelegramm welches auch die Uhrzeit im Unix-Format enthält.
Diese Uhrzeit beinhaltet bereits die Sommer- Winterzeitumschaltung. Zur Winterzeit erhalte ich also UTC+1 und zur Sommerzeit UTC+2.
Auf dem Arduino benutze ich die "Time.h" Lib.
Immer dann wenn ich ein Datentelegramm mit Uhrzeit empfange, wird die Arduino interne Uhr durch setTime(unixTime) abgeglichen.
Ich weis aber erst mal nicht ob gerade Sommerzeit oder Winterzeit ist.
Das will ich aber wissen weil eine Funktin zur Berechnung des Sonnenstandes immer UTC+0 benötigt.
Hierzu verstelle ich die interne Uhr temporär um eine oder zwei Stunden nach hinten.
Dann wird der die Sonnenposition (mit UTC+0) ermittelt und die Uhr wieder eine oder zwei Stunden nach vorne gestellt.

Der Code von Jurs erhält immer die aktuelle lokale Zeit.
Bei der Umstellung von Winterzeit auf Sommerzeit sehe ich kein Problem, denn zur Winterzeit ist tzHours = 1.
Wie ist es aber bei der Umstellung von Sommerzeit auf Winterzeit?
Arbeitet der Code dann richtig wenn tzHours = 1 ist oder muss dann tzHours = 2 sein?

Danke für eure Antworten
Peter

Ich finde es schräg boolesche Ausdrücke auszuwerten um dann per IF zu entscheiden ob man true oder false zurückgibt. Ich würde deshalb statt sowas

{
  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;
}

Eher sowas schreiben

{
  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
  return (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)));
}

oder ganz konsequent gleich

{
    return  
        (month>3 && month<10) || // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
        (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));
}

Sorry @Udo,
ich bin jetzt durch dein Posting etwas verwirrt.

Meine Frage war eigentlich: Welchen Wert übergebe ich mit tzHours an die Rechenfunktion wenn ich ihr die aktuelle lokale Zeit als Parameter übergebe damit ich als Ergebnis true für Sommerzeit oder false für Winterzeit erhalte.
Ich weis dass das Ergebnis eigentlich immer richtig ist, nur zur Umschaltzeit vom Sommer- auf Winterzeit erhalte ich für eine Stunde ein falsches Ergebnis wenn ich für tzHours einen falschen Wert angebe.

Und was liefert dein Vorschlag:

als Rückgabewert?

Gruß, Peter

peter_de:
ich habe eine Frage zum Wert der Variablen tzHours.
Ist der Wert für Deutschland immer auf 1 (für UTC+1) zu setzen oder wird bei Sommerzeit der Wert auf 2 (für UTC+2) gestellt?

UTC-Zeit ist UTC, also tzHours=0
Winterzeit ist UTC+1, also tzHours=1
Sommerzeit ist UTC+2, also tzHours=2

Wenn Du prüfen möchtest, ob eine bestimmte Zeitangabe in die Sommerzeit fällt, nimmst Du die Uhrzeitangabe und die Zeitzone in der die Uhr läuft, und fragst ab. Mit der Zeit, die auf der Uhr angezeigt wird und der Zeitzone, in der die Uhr läuft. Also bei einer auf Winterzeit laufenden Uhr mit tzHours=1 und bei einer auf Sommerzeit umgestellten Uhr mit tzHours=2.

rudirabbit:
Ich empfange über eine serielle Schnittstelle ein Datentelegramm welches auch die Uhrzeit im Unix-Format enthält.
Diese Uhrzeit beinhaltet bereits die Sommer- Winterzeitumschaltung. Zur Winterzeit erhalte ich also UTC+1 und zur Sommerzeit UTC+2.

Eine Unix-Uhrzeit läuft immer auf GMT. Auf Rechnern mit Betriebssystem (PC, Server) wird diese Zeit dann ggf. in "lokal Time" umgerechnet.

Wenn Du eine Uhrzeit hast, mit Zeitzonenverschiebung und sogar Sommerzeitumschaltung, dann ist das keine Unix-Time, sondern dann ist es eine Localtime.

Ich weis aber erst mal nicht ob gerade Sommerzeit oder Winterzeit ist.
Das will ich aber wissen weil eine Funktin zur Berechnung des Sonnenstandes immer UTC+0 benötigt.

Bei einer Uhr, von der Du nicht weißt, ob sie auf Sommer- oder auf Winterzeit (UTC+2 oder UTC+1) eingestellt ist, gibt es bei der Rückstellung im Herbst immer eine Phase von einer Stunde, bei der Du nicht genau sagen kannst, welche Zeit vorliegt. Da es bei der Zeitumstellung im Herbst die Stunde zwischen 02:00 und 03:00 Uhr zweimal gibt, kann Dir bei einer solchen Zeitangabe niemand sagen, ob Du in der 2A Stunde (Sommerzeit) oder der 2B Stunde (Winterzeit) bist, wenn Dir keine Informationen darüber vorliegen, um was für eine Zeitangabe es sich handelt.

Es sei denn, Du wertest die Stetigkeit der Zeit Deiner Uhr aus: Wenn sie am Umstellungstag Ende Oktober noch nicht eine Stunde rückwärts gesprungen ist, bist Du noch auf Sommerzeit UTC+2, und nachdem die Uhr eine Stunde zurückgesprungen ist, bist Du auf Winterzeit UTC+1-

Aber diese eine Stunde ist wahrscheinlich für eine Anwendung zur Berechnung des Sonnenstands relativ irrelevant: Ende Oktober nachts zwischen 2 und 3 befindet sich die Sonne in Mitteleuropa sowieso immer unterhalb des Horizonts. Und zwar sowohl nach Sommerzeit wie auch nach Winterzeit.

Hierzu verstelle ich die interne Uhr temporär um eine oder zwei Stunden nach hinten.
Dann wird der die Sonnenposition (mit UTC+0) ermittelt und die Uhr wieder eine oder zwei Stunden nach vorne gestellt.

Klingt ziemlich umständlich. Astronomische Formeln beziehen sich doch immer auf UTC-Zeiten, da kannst Du die Uhrzeit doch gleich auf UTC laufen lassen.

Hallo,

Meine Frage war eigentlich: Welchen Wert übergebe ich mit tzHours an die Rechenfunktion wenn ich ihr die aktuelle lokale Zeit als Parameter übergebe damit ich als Ergebnis true für Sommerzeit oder false für Winterzeit erhalte.

Du darfst den Wert der tzHours nicht ändern. Du mußt Dich für eine Zeitzone entscheiden und dann konsequent durchziehen. Oder Du hast Deine festgestellten Effekte, die dann auch normal sind. Deshalb läuft meine RTC konsequent in der Winterzeit und im Sketch korrigiere ich im Sommer die Stunde +1. Ich muß nur aufpassen, falls ich die RTC mal stellen sollte, dass ich auch im Sommer die Winterzeit eingebe. Die Variable tzHours habe ich ganz rausgenommen.

... auf Winterzeit erhalte ich für eine Stunde ein falsches Ergebnis wenn ich für tzHours einen falschen Wert angebe.

eigentlich auch logisch, wenn man was falsches vorgibt, dass was falsches rauskommt.
In dem Code wird für das aktuelle Jahr der Umschaltpunkt berechnet. Inkl. Deiner Vorgabe für die Zeitzone. Der bekommt das aber nach der "Stunde Umstellzeit" dennoch mit und korrigiert trotzdem wieder. Also der Code ist nicht dumm. Wenn Du meine obige Rechnung verstehst, weist Du auch was im Code alles passiert und geprüft wird.

Was pylon uns sagen möchte verstehe ich auch noch nicht. Es fehlt der Rückgabewert ob true oder false. Die original Return's sollen ja den Code schneller machen.

Danke @jurs für den ausführlichen Beitrag.
Meine Frage konnte beantwortet werden.

Vielleicht noch ein paar Erklärungen zu meiner doch wohl etwas speziellen Anwendung.
Und der Bitte um Entschuldigung weil ich meine Frage hier gepostet habe und eigentlich keine RTC habe.

jurs:
Eine Unix-Uhrzeit läuft immer auf GMT. Auf Rechnern mit Betriebssystem (PC, Server) wird diese Zeit dann ggf. in "lokal Time" umgerechnet.

Wenn Du eine Uhrzeit hast, mit Zeitzonenverschiebung und sogar Sommerzeitumschaltung, dann ist das keine Unix-Time, sondern dann ist es eine Localtime.

Ich lese über Serial1 eines Mega 2560 die Kommunikation zwischen einem Datenlogger und den Wechselrichtern meiner Photovoltaikanlage mit.

Der Datenlogger synchronisiert (vermutlich) seine interne Uhrzeit mit einem NTP-Server im Internet.
Er addiert dann eine bzw. zwei Stunden, je nach Winter- oder Sommerzeit, hinzu und arbeitet dann mit dieser lokalen Zeit.
Genaueres kann ich dazu nicht sagen weil die Gerätebeschreibung darüber nichts hergibt.
Meine Beobachtungen haben aber gezeigt, dass die Interne Uhr des Datenloggers immer bis auf +/- 1 Sekunde mit diversen DCF77 Funkuhren im Haus überein stimmt.

Der Datenlogger fragt dann zyklisch (alle 15s) die Wechselrichter ab und übermittelt in jeder Anfrage die aktuelle lokale Uhrzeit.
Das gesendete Protokoll enthält die Uhrzeit in einem 4 Bytes (unsigned long) Format.
Zur Winterzeit die Sekunden seit dem 1. Januar 1970 00:00 + 3600 Sekunden.
Zur Sommerzeit die Sekunden seit dem 1. Januar 1970 00:00 + 7200 Sekunden.

Die Antworttelegramme der Wechselrichter enhalten dann etliche Messwerte über den aktuellen Betriebszustand welche ich auswerte und mit dem zugehörigen Zeitstempel abspeichere.
Ich verwende diesen Zeitstempel weil auch der Datenlogger mit der lokalen Zeit arbeitet und kann damit leichter die vom Arduino aufbereiteten Daten mit den vom Datenlogger aufbereiten Daten synchronisieren.

Warum aber lese ich mit dem Arduino die Kommunikation mit wenn doch schon der Datenlogger alles über die Wechselrichter erfährt?
Der Datenlogger speichert nur Mittelwerte über 5 Minuten (also Mittelwerte aus 20 Messwerten) die er von den Wechselrichtern erhält. Zudem übermitteln die Wechselrichter auch Messwerte die den Datenlogger nicht interessieren und die er dann einfach wegwirft. Aber auch diese vom Datenlogger unbeachteten Werte interessieren mich weil sie den Zustand der Photovoltaikanlage besser beschreiben als nur die vom Datenlogger ausgewerteten Daten alleine.

Deshalb läuft auch die Arduino interne Uhr auf lokaler Zeit.
Um jetzt aber den Sonnenstand zu berechnen, der zur Überwachung der Photovoltaikanlage eine wichtige Größe ist, benötige ich die aktuelle UTC-Time. Hierfür muss ich dann aber wissen ob die lokale Zeit gerade UTC+1 oder UTC+2 ist.

Es mag daher vielleicht umständlich aussehen was ich mache, aber es war für mich die einfachste Lösung in einer Zeile sommerzeit ? adjustTime(-7200) : adjustTime(-3600); die Interne Uhr um eine oder zwei Stunden zurück zu stellen, dann mit der "verstellten" Uhrzeit die Routine zur Berechnung der Sonnenposition aufzurufen und anschließend die interne Uhr wieder mit sommerzeit ? adjustTime(7200) : adjustTime(3600); auf lokale Zeit gerade zu biegen.

jurs:
Bei einer Uhr, von der Du nicht weißt, ob sie auf Sommer- oder auf Winterzeit (UTC+2 oder UTC+1) eingestellt ist, gibt es bei der Rückstellung im Herbst immer eine Phase von einer Stunde, bei der Du nicht genau sagen kannst, welche Zeit vorliegt. Da es bei der Zeitumstellung im Herbst die Stunde zwischen 02:00 und 03:00 Uhr zweimal gibt, kann Dir bei einer solchen Zeitangabe niemand sagen, ob Du in der 2A Stunde (Sommerzeit) oder der 2B Stunde (Winterzeit) bist, wenn Dir keine Informationen darüber vorliegen, um was für eine Zeitangabe es sich handelt.

Das ist allerdings richtig.
Ich weis wirklich nicht was die Uhr im Datenlogger bei der Umstellung von Sommerzeit auf Winterzeit macht und welche Zeit ich von ihr in der 2A Stunde oder 2B Stunde erhalte.
Eigentlich ist es für die Erfassung der Daten von den Wechselrichtern auch völlig egal, weil diese Nachts eh im Tiefschlaf sind und auf Anfragen des Datenloggers keine Antwort geben.
Der Arduino empfängt aber auch Daten von einer kleinen Wetterstation im Garten und anderen Messungen die zeitsynchron mit den Daten der Photovoltaikanlage abgespeichert werden sollen. Und für diese Daten muss ich mir dann überlegen wie der Zeitstempel in der Stunde 2A und 2B aussehen soll.

Viele Grüße
Peter

Warum nimmst Du nicht einfach ein DCF77 Modul anstelle einer RTC? Dann ist das Sommerzeit / Winterzeitproblem gelöst, denn DCF77 liefert ein Sommerzeit / Winterzeitflag mit. Falls Deine Wechselrichter die Module stören --> meine Library behebt sowas problemlos: DCF77 Library | Blinkenlight

Danke @Udo,
ich habe hier sogar noch ein historisches Modell einer DCF77 Uhr in Betrieb, Baujahr 1985 und sie läuft immer noch :slight_smile: http://www.acs-77.de/

Ich verwende aber auch keine RTC am Arduino, sondern erhalte die Zeitinformation aus der Kommunikation zwischen dem Datenlogger und den Wechselrichtern. Diese Kommunikation lese ich seriell mit und extrahiere daraus u.A. auch die Uhrzeitinformation.
Diese Uhrzeit ist so genau, dass ich keine weitere Uhr am Arduino brauche.

Das Problem war nur, dass die vom Datenlogger im Telegramm gelieferte Uhrzeit immer der lokalen Zeit enspricht.
Weil ich aber zur Berechnung des Sonnenstandes immer UTC-Time brauche muss ich von der lokalen Zeit eine oder zwei Stunden abziehen. Deshalb muss ich wissen ob mir vom Datenlogger gerade Sommerzeit oder Winterzeit geliefert wird um zu entscheiden ob ich eine oder zwei Stunden abziehen muss um UTC zu erhalten.
Mein Problem wurde mit dem Beitrag von "jurs" am 02.05. gelöst.

Gruß
Peter