2020-02-28
Achtung!
Funktioniert ab Arduino Core Version 2.6.0 oder höher.

// ****************************************************************
// Sketch Esp8266 WiFi NTP Kalenderzeit
// created: Jens Fleischer, 2020-02-22
// last mod: Jens Fleischer, 2020-02-28
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: Esp8266
// Software: Esp8266 Arduino Core 2.6.0 - 2.6.3
// 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
/**************************************************************************************/

#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 %2502ld 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: %ld\n", time(&now));         // Ausgabe Unix Zeitstempel
    Serial.printf("UTC: %.2ld:%.2ld:%.2ld\n", time(&now) % 86400L / 3600, time(&now) % 3600 / 60, time(&now) % 60);  // Ausgabe Koordinierte Weltzeit
    Serial.print("Sekunde: "); Serial.println(tm.tm_sec);         // Ausgabe aktuelle Sekunde
    Serial.print("Minute: "); Serial.println(tm.tm_min);          // Ausgabe aktuelle Minute
    Serial.print("Stunde: "); Serial.println(tm.tm_hour);         // Ausgabe aktuelle Stunde
    strftime (buff, sizeof(buff), "Kalenderwoche: %V\n", &tm);    // http://www.cplusplus.com/reference/ctime/strftime/
    Serial.print(buff);                                           // Ausgabe Kalenderwoche
    Serial.println(DAY_NAMES[tm.tm_wday]);                        // Ausgabe aktueller Tag
    Serial.println(MONTH_NAMES[tm.tm_mon]);                       // Ausgabe aktueller Monat
    Serial.println(DAY_SHORT[tm.tm_wday]);                        // Ausgabe aktueller Tag (Abk.)
    Serial.println(MONTH_SHORT[tm.tm_mon]);                       // Ausgabe aktueller Monat (Abk.)
    Serial.println(tm.tm_isdst ? "Sommerzeit" : "Normalzeit");
  }
}

Zurück