Habe das Netz schon auf den Kopf gestellt, aber leider nicht das richtige gefunden, oder einfach nach dem Falschen gesucht.
Also - ich suche einen Code, den ich in meinen Sketch einfügen kann, damit ich die Uhrzeit vom DS1307 RTC-Modul auch bei Sommer/Winterzeit korrekt angezeigt bekomme.
Im Moment klappt das mit der Sommerzeit nicht.
Habe die Uhrzeit mit dem Pc gestellt. Obwohl mein Pc gerade 20:24 anzeigt, zeigt das Display vom Arduino 19:26 an?
Gestellt habe ich hiermit:
/*
* TimeRTCSet.pde
* example code illustrating Time library with Real Time Clock.
*
* RTC clock is set in response to serial port time message
* A Processing example sketch to set the time is inclided in the download
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
void setup() {
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}
void loop()
{
if(Serial.available())
{
time_t t = processSyncMessage();
if(t >0)
{
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
}
}
digitalClockDisplay();
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
/* code to process time sync messages from the serial port */
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message
time_t processSyncMessage() {
// return the time if a valid sync message is received on the serial port.
while(Serial.available() >= TIME_MSG_LEN ){ // time message consists of a header and ten ascii digits
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
return pctime;
}
}
return 0;
}
Das mit der Sommerzeit ist recht aufwändig zu berechnen, aber es gibt eine Lib "DS1307new.h", die das unterstützt.
Sie stellt (neben den üblichen anderen Funktionen) auch die Funktion isMEZSummerTime() zur Verfügung.
guntherb:
Das mit der Sommerzeit ist recht aufwändig zu berechnen, aber es gibt eine Lib "DS1307new.h", die das unterstützt.
Ich mache die Feststellung der Sommerzeit mit gerade mal sechs Zeilen Code im Codeblock, davon eine längere if-Abfrage.
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;
}
Zu übergeben an die Funktion ist eine "Zonenzeit", also die Zeit auf der man die Echtzeituhr am besten dauernd laufen läßt:
Jahr
Monat
Tag
Stunde
Zeitzone (UTC=0, MEZ=1)
und Rückgabewert ist true oder false, je nachdem ob man für Sommerzeit eine Stunde draufschlagen muss oder nicht.
Im Fall der Time-Library, die mit Unix-Time "Sekunden seit 01.01.1970" arbeitet, würde man also bei Sommerzeit 3600 Sekunden auf die Zonenzeit UTC+1 draufschlagen.
DS1307 Testsketch
Format is "hh:mm:ss dd-mm-yyyy DDD"
MEZ=0, MESZ=1 : 1
19:40:14 15-06-2013 SAT seconds since 1.1.2000:424640414 MEZ=0, MESZ=1 : 1 - Address in NV-RAM is: 0 - Clock was set!
19:40:15 15-06-2013 SAT seconds since 1.1.2000:424640415 MEZ=0, MESZ=1 : 1 - Address in NV-RAM is: 1 - Clock was set!
19:40:16 15-06-2013 SAT seconds since 1.1.2000:424640416 MEZ=0, MESZ=1 : 1 - Address in NV-RAM is: 2 - Clock was set!
Es ist jedoch laut meinem Rechner 20:38. Also 1ne Stunde und 2 Minuten falsch
EDIT:
Ok, habe das Problem gelöst.
Habe einfach die aktuelle 1.0.5 installiert, die neue Time und DS1307 library installiert und die Zeit gestellt.
Nun ist die Uhrzeit korrekt!
Ja, Jurs Code rechnet richtig, aber die Jahreszahl muss 4stellig sein. Also nicht 18 sondern 2018, dann wird richtig gerechnet.
Hier nochmal der Code aus #4 mit der 4stelligen Jahreszahl - was dann zu richtigen Ergebnissen führt:
int year = 2013; // nicht 13 sondern 2013
int month = 3;
int day = 1;
int hour = 2;
int MEZ = 0;
int Jahr;
bool Sommerzeit = false;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Jahr: ");
Serial.println(year);
}
void loop() {
if (Sommerzeit) {
year++;
day = 1;
Sommerzeit = false;
}
if (month == 3 && (hour + 24 * day) >= (1 + MEZ + 24 * (31 - (5 * year / 4 + 4) % 7)))
{
Sommerzeit = true;
Serial.print("Sommerzeit: ");
Serial.print(day);
Serial.print(".03.");
Serial.println(year);
}
day++;
delay(10);
}
Edit: Dass die Jahreszahl 4stellig sein muss wird auch hier erwähnt.
Kaum macht man's richtig und funktioniert.
Vielen Dank, für die schnellen und guten Antworten.
Das die Jahreszahl 4-stellig sein muss, hatte ich überlesen.
Mit der Uhrzeit will ich noch testen.
Benutze NTP und stelle den interne RTC des MKR1000 mit MEZ.
Ich weiss der Thread ist schon etwas älter.
Ich habe den original Thread in dem Jurs seine geniale Formel vorstellt nicht mehr gefunden.
Ich habe diese bei mir in eine Bibliothek eingebaut und beim testen gemerkt, dass etwas nicht stimmt.
Hier noch einmal die betreffende Codezeile von Jurs
So lange ich mit MEZ, also tzHours= 1 teste, ist alles ok.
Wenn ich aber mit GMT also tzHours = 0 teste, funktioniert die Umschaltung nicht um 2:00 Uhr sondern um 1:00
Wenn ich die entsprechende Zeile im Code (den ich nur ansatzweise verstehe) :o so ändere, funktioniert alles.
Die Detektierung der Umschaltung gilt ja immer für die Ortszeit. bei tzHours = 1 + 1 bin ich bei 2:00 Uhr Ortszeit. Bei tzHours = 0 (GMT) + 1 ist das Resultat aber schon um 1:00 true, also eine Stunde zu früh.
Vermutlich mache ja ich einen Überlegungsfehler. Immer wenn es um Verschiebung von Zeit geht wird mir ganz schummrig.
Kann das jemand ohne viel Aufwand nachvollziehen?
Umstellung 2018: 25. März 2:00 Ein / 28. Okt. 2:00 Aus