Achtung! EspCore Version 2.6.0 oder höher.
NtpTime.ino
// ****************************************************************
// Sketch Esp8266 WiFi NTP Kalenderzeit
// created: Jens Fleischer, 2020-02-22
// last mod: Jens Fleischer, 2021-06-08
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: Esp8266
// Software: Esp8266 Arduino Core 2.6.0 - 3.0.0
// Getestet auf: Nodemcu, Wemos D1 Mini Pro, Sonoff Switch, Sonoff Dual
/******************************************************************
Copyright (c) 2020 Jens Fleischer. All rights reserved.
This file is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
*******************************************************************/
// Automatische Umstellung zwischen Sommer- und Normalzeit.
// Inclusive Abfrage ob die Zeit vom NTP Server geholt werden konnte.
/**************************************************************************************/
#include <ESP8266WiFi.h>
#include <time.h>
struct tm tm; // http://www.cplusplus.com/reference/ctime/tm/
const char* ssid = "Netzwerkname"; // << kann bis zu 32 Zeichen haben
const char* password = "PasswortvomNetzwerk"; // << mindestens 8 Zeichen jedoch nicht länger als 64 Zeichen
const uint32_t SYNC_INTERVAL = 24; // NTP Sync Interval in Stunden
const char* const PROGMEM NTP_SERVER[] = {"fritz.box", "de.pool.ntp.org", "at.pool.ntp.org", "ch.pool.ntp.org", "ptbtime1.ptb.de", "europe.pool.ntp.org"};
const char* const PROGMEM DAY_NAMES[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
const char* const PROGMEM DAY_SHORT[] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"};
const char* const PROGMEM MONTH_NAMES[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
const char* const PROGMEM MONTH_SHORT[] = {"Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"};
extern "C" uint8_t sntp_getreachability(uint8_t);
bool getNtpServer(bool reply = false) {
uint32_t timeout {millis()};
configTime("CET-1CEST,M3.5.0/02,M10.5.0/03", NTP_SERVER[0], NTP_SERVER[1], NTP_SERVER[2]); // Zeitzone einstellen https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
do {
delay(25);
if (millis() - timeout >= 1e3) {
Serial.printf("Warten auf NTP-Antwort %02ld sec\n", (millis() - timeout) / 1000);
delay(975);
}
sntp_getreachability(0) ? reply = true : sntp_getreachability(1) ? reply = true : sntp_getreachability(2) ? reply = true : false;
} while (millis() - timeout <= 16e3 && !reply);
return reply;
}
void setup() {
Serial.begin(115200);
delay(100);
Serial.printf("\n\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n%s\n\n",
(__FILE__), (__TIMESTAMP__), ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10, ESP.getFullVersion().c_str());
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nVerbunden mit: " + WiFi.SSID());
Serial.println("IP Addresse: " + WiFi.localIP().toString());
bool timeSync = getNtpServer();
Serial.printf("NTP Synchronisation %s!\n", timeSync ? "erfolgreich" : "fehlgeschlagen");
}
void loop() {
char buff[20]; // je nach Format von "strftime" eventuell anpassen
static time_t lastsec {0};
time_t now = time(&now);
localtime_r(&now, &tm);
if (tm.tm_sec != lastsec) {
lastsec = tm.tm_sec;
strftime (buff, sizeof(buff), "%d.%m.%Y %T", &tm); // http://www.cplusplus.com/reference/ctime/strftime/
if (!(time(&now) % (SYNC_INTERVAL * 3600))) {
getNtpServer(true);
}
// Verwendungsbeispiele
Serial.printf("\nLokalzeit: %s\n", buff); // Ausgabe der Kalenderzeit
Serial.printf("Unix Zeitstempel: %lld\n", (int64_t)time(&now));// Ausgabe Unix Zeitstempel
Serial.printf("UTC: %.2d:%.2d:%.2d\n", int(time(&now) % 86400L / 3600), int(time(&now) % 3600 / 60), int(time(&now) % 60)); // Ausgabe Koordinierte Weltzeit
Serial.print("Stunde: "); Serial.println(tm.tm_hour); // aktuelle Stunde
Serial.print("Minute: "); Serial.println(tm.tm_min); // aktuelle Minute
Serial.print("Sekunde: "); Serial.println(tm.tm_sec); // aktuelle Sekunde
Serial.print("Tag: "); Serial.println(tm.tm_mday); // Tag als Zahl
Serial.print("Monat: "); Serial.println(tm.tm_mon + 1); // Monat als Zahl
Serial.print("Jahr: "); Serial.println(tm.tm_year + 1900); // Jahr als Zahl
strftime (buff, sizeof(buff), "Wochentag: %u\n", &tm); // http://www.cplusplus.com/reference/ctime/strftime/
Serial.print(buff); // Tag der Woche
Serial.print("Tag des Jahr: "); Serial.println(tm.tm_yday + 1);// Tag des Jahres
strftime (buff, sizeof(buff), "Kalenderwoche: %V\n", &tm); // http://www.cplusplus.com/reference/ctime/strftime/
Serial.print(buff); // Kalenderwoche
Serial.println(DAY_NAMES[tm.tm_wday]); // aktueller Wochentag
Serial.println(MONTH_NAMES[tm.tm_mon]); // aktueller Monat
Serial.println(DAY_SHORT[tm.tm_wday]); // aktueller Wochentag (Abk.)
Serial.println(MONTH_SHORT[tm.tm_mon]); // aktueller Monat (Abk.)
Serial.printf("Name der Zeitzone: %s\n", _tzname[0]);
Serial.printf("Name der Sommerzeitzone: %s\n", _tzname[1]);
Serial.println(tm.tm_isdst ? "Sommerzeit" : "Normalzeit");
}
}
Vielen Dank für den Code.
Ich benutze ihn, um festzustellen, ob die Türen an meiner Garage nach 22:00 Uhr verschlossen sind.
Nur mal eine Frage: Wenn, aus welchem Grund auch immer, der ESP die WLAN-Verbindung verliert,
baut sich diese dann von allein wieder auf?
Oder muss ich da in meinem Code irgendwie abfragen, ob WLAN verfügbar, und wenn nicht, dann neu aufbauen?
Grüße aus Thüringen.
Andreas
Antwort:
Nach meiner Erfahrung klappt das nicht immer!
Nach einem Stromausfall braucht der Router viel länger zum starten als der Esp8266, deswegen habe ich in meinem Heizungssketch eine Routine dafür eingebaut.
Gruß Fips aus Th.
"invalid converation from const char to long int" [-fpermisse]
was auch immer das bedeuten mag
Schöne Grüße
Stefan
Antwort:
Es funktioniert bei dir nicht!
Bei mir schon.
Du versuchst den Sketch mit einer EspCoreVersion vor 2.6.0. zu kompillieren.
Wenn es dir nicht möglich ist eine aktuellere CoreVersion zu benutzen dann ersetze die Zeile mit den folgenden beiden.
configTime(0, 0, NTP_SERVER[1]);
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
Gruß Fips
Vielen Dank für dein Programm. Funktioniert soweit bis auf:
Als Monat wird mir richtig "6" angezeigt - in Textform aber "Juli". Ist es hier evtl. wie bei den Wochentagen, das die Zuordnungstabelle mit "Dezember"beginnen müsste?
Schöne grüße aus Südhessen!
Antwort:
Da hat sich ein Fehler eingeschlichen.
Danke für deine Aufmerksamkeit.
Gruß Fips