From dc8dbdb957a0cc3b79c0594012bfc1f8978ea006 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Fri, 13 Feb 2026 12:26:11 -0800 Subject: [PATCH] snapshot --- .gitmodules | 6 + TFT_eSPI | 1 + libraries/NTP/LICENSE | 22 ++ libraries/NTP/NTP.cpp | 288 +++++++++++++++ libraries/NTP/NTP.h | 288 +++++++++++++++ libraries/NTP/README.md | 330 ++++++++++++++++++ .../ESP32_OLED_NTP/ESP32_OLED_NTP.ino | 58 +++ libraries/NTP/examples/WIFI_NTP/WIFI_NTP.ino | 37 ++ libraries/NTP/keywords.txt | 30 ++ libraries/NTP/library.json | 13 + libraries/NTP/library.properties | 10 + libraries/NTPClient/CHANGELOG | 15 + libraries/NTPClient/NTPClient.cpp | 212 +++++++++++ libraries/NTPClient/NTPClient.h | 114 ++++++ libraries/NTPClient/README.md | 52 +++ .../NTPClient/examples/Advanced/Advanced.ino | 37 ++ libraries/NTPClient/examples/Basic/Basic.ino | 33 ++ .../examples/IsTimeSet/IsTimeSet.ino | 53 +++ libraries/NTPClient/keywords.txt | 24 ++ libraries/NTPClient/library.properties | 9 + sketches/doorbell/TFT_eSPI | 1 + sketches/doorbell/doorbell.ino | 2 +- 22 files changed, 1634 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 160000 TFT_eSPI create mode 100755 libraries/NTP/LICENSE create mode 100755 libraries/NTP/NTP.cpp create mode 100755 libraries/NTP/NTP.h create mode 100755 libraries/NTP/README.md create mode 100644 libraries/NTP/examples/ESP32_OLED_NTP/ESP32_OLED_NTP.ino create mode 100644 libraries/NTP/examples/WIFI_NTP/WIFI_NTP.ino create mode 100755 libraries/NTP/keywords.txt create mode 100755 libraries/NTP/library.json create mode 100644 libraries/NTP/library.properties create mode 100644 libraries/NTPClient/CHANGELOG create mode 100755 libraries/NTPClient/NTPClient.cpp create mode 100755 libraries/NTPClient/NTPClient.h create mode 100644 libraries/NTPClient/README.md create mode 100644 libraries/NTPClient/examples/Advanced/Advanced.ino create mode 100644 libraries/NTPClient/examples/Basic/Basic.ino create mode 100644 libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino create mode 100644 libraries/NTPClient/keywords.txt create mode 100644 libraries/NTPClient/library.properties create mode 160000 sketches/doorbell/TFT_eSPI diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d0c00cf --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "TFT_eSPI"] + path = TFT_eSPI + url = https://github.com/Cincinnatu/TFT_eSPI +[submodule "sketches/doorbell/TFT_eSPI"] + path = sketches/doorbell/TFT_eSPI + url = https://github.com/Cincinnatu/TFT_eSPI.git diff --git a/TFT_eSPI b/TFT_eSPI new file mode 160000 index 0000000..42f64b3 --- /dev/null +++ b/TFT_eSPI @@ -0,0 +1 @@ +Subproject commit 42f64b37e450e43868ca0e811075484e2f3bfccb diff --git a/libraries/NTP/LICENSE b/libraries/NTP/LICENSE new file mode 100755 index 0000000..de699d2 --- /dev/null +++ b/libraries/NTP/LICENSE @@ -0,0 +1,22 @@ +MIT License + +NTP library for Arduino framework +Copyright (c) 2022 Stefan Staub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/NTP/NTP.cpp b/libraries/NTP/NTP.cpp new file mode 100755 index 0000000..e0d873e --- /dev/null +++ b/libraries/NTP/NTP.cpp @@ -0,0 +1,288 @@ +/** + * NTP library for Arduino framework + * The MIT License (MIT) + * (c) 2022 sstaub + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "NTP.h" + +NTP::NTP(UDP& udp) { + this->udp = &udp; + } + +NTP::~NTP() { + stop(); + } + +void NTP::begin(const char* server) { + this->server = server; + init(); + } + +void NTP::begin(IPAddress serverIP) { + this->serverIP = serverIP; + init(); + } + +void NTP::init() { + memset(ntpRequest, 0, NTP_PACKET_SIZE); + ntpRequest[0] = 0b11100011; // LI, Version, Mode + ntpRequest[1] = 0; // Stratum, or type of clock + ntpRequest[2] = 6; // Polling Interval + ntpRequest[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + ntpRequest[12] = 49; + ntpRequest[13] = 0x4E; + ntpRequest[14] = 49; + ntpRequest[15] = 52; + udp->begin(NTP_PORT); + ntpUpdate(); + if (dstZone) { + timezoneOffset = dstEnd.tzOffset * SECS_PER_MINUTES; + dstOffset = (dstStart.tzOffset - dstEnd.tzOffset) * SECS_PER_MINUTES; + currentTime(); + beginDST(); + } + } + +void NTP::stop() { + udp->stop(); + } + +bool NTP::update() { + if ((millis() - lastUpdate >= interval) || lastUpdate == 0) { + return ntpUpdate(); + } + return false; + } + +bool NTP::ntpUpdate() { + if (server == nullptr) udp->beginPacket(serverIP, NTP_PORT); + else udp->beginPacket(server, NTP_PORT); + udp->write(ntpRequest, NTP_PACKET_SIZE); + udp->endPacket(); + uint8_t timeout = 0; + uint8_t size = 0; + do { + delay (10); + size = udp->parsePacket(); + if (timeout > 100) return false; + timeout++; + } while (size != 48); + lastUpdate = millis() - (10 * (timeout + 1)); + udp->read(ntpQuery, NTP_PACKET_SIZE); + #ifdef __AVR__ + unsigned long highWord = word(ntpQuery[40], ntpQuery[41]); + unsigned long lowWord = word(ntpQuery[42], ntpQuery[43]); + timestamp = highWord << 16 | lowWord; + if (timestamp != 0) { + ntpTime = timestamp; + utcTime = ntpTime - NTP_OFFSET; + } + else return false; + #else + timestamp = ntpQuery[40] << 24 | ntpQuery[41] << 16 | ntpQuery[42] << 8 | ntpQuery[43]; + if (timestamp != 0) { + ntpTime = timestamp; + utcTime = ntpTime - SEVENTYYEARS; + } + else return false; + #endif + return true; + } + +void NTP::updateInterval(uint32_t interval) { + this->interval = interval; + } + +void NTP::ruleDST(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset) { + strcpy(dstStart.tzName, tzName); + dstStart.week = week; + dstStart.wday = wday; + dstStart.month = month; + dstStart.hour = hour; + dstStart.tzOffset = tzOffset; + } + +const char* NTP::ruleDST() { + if(dstZone) { + return ctime(&dstTime); + } + else return RULE_DST_MESSAGE; + } + +void NTP::ruleSTD(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset) { + strcpy(dstEnd.tzName, tzName); + dstEnd.week = week; + dstEnd.wday = wday; + dstEnd.month = month; + dstEnd.hour = hour; + dstEnd.tzOffset = tzOffset; + } + +const char* NTP::ruleSTD() { + if(dstZone) { + return ctime(&stdTime); + } + else return RULE_STD_MESSAGE; + } + +const char* NTP::tzName() { + if (dstZone) { + if (summerTime()) return dstStart.tzName; + else return dstEnd.tzName; + } + return GMT_MESSAGE; + } + +void NTP::timeZone(int8_t tzHours, int8_t tzMinutes) { + this->tzHours = tzHours; + this->tzMinutes = tzMinutes; + timezoneOffset = tzHours * 3600; + if (tzHours < 0) { + timezoneOffset -= tzMinutes * 60; + } + else { + timezoneOffset += tzMinutes * 60; + } + } + +void NTP::isDST(bool dstZone) { + this->dstZone = dstZone; + } + +bool NTP::isDST() { + return summerTime(); + } + +time_t NTP::epoch() { + currentTime(); + return utcCurrent; + } + +void NTP::currentTime() { + utcCurrent = utcTime + ((millis() - lastUpdate) / 1000); + if (dstZone) { + if (summerTime()) { + local = utcCurrent + dstOffset + timezoneOffset; + current = gmtime(&local); + } + else { + local = utcCurrent + timezoneOffset; + current = gmtime(&local); + } + if ((current->tm_year + 1900) > yearDST) beginDST(); + } + else { + local = utcCurrent + timezoneOffset; + current = gmtime(&local); + } + } + +int16_t NTP::year() { + currentTime(); + return current->tm_year + 1900; + } + +int8_t NTP::month() { + currentTime(); + return current->tm_mon + 1; + } + +int8_t NTP::day() { + currentTime(); + return current->tm_mday; + } + +int8_t NTP::weekDay() { + currentTime(); + return current->tm_wday; + } + +int8_t NTP::hours() { + currentTime(); + return current->tm_hour; + } + +int8_t NTP::minutes() { + currentTime(); + return current->tm_min; + } + +int8_t NTP::seconds() { + currentTime(); + return current->tm_sec; + } + +const char* NTP::formattedTime(const char *format) { + currentTime(); + memset(timeString, 0, sizeof(timeString)); + strftime(timeString, sizeof(timeString), format, current); + return timeString; + } + +void NTP::beginDST() { + dstTime = calcDateDST(dstStart, current->tm_year + 1900); + utcDST = dstTime - (dstEnd.tzOffset * SECS_PER_MINUTES); + stdTime = calcDateDST(dstEnd, current->tm_year + 1900); + utcSTD = stdTime - (dstStart.tzOffset * SECS_PER_MINUTES); + yearDST = current->tm_year + 1900; + } + +time_t NTP::calcDateDST(struct ruleDST rule, int year) { + uint8_t month = rule.month; + uint8_t week = rule.week; + if (week == 0) { + if (month++ > 11) { + month = 0; + year++; + } + week = 1; + } + + struct tm tm; + tm.tm_hour = rule.hour; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_mday = 1; + tm.tm_mon = month; + tm.tm_year = year - 1900; + time_t t = mktime(&tm); + + t += ((rule.wday - tm.tm_wday + 7) % 7 + (week - 1) * 7 ) * SECS_PER_DAY; + if (rule.week == 0) t -= 7 * SECS_PER_DAY; + return t; + } + +bool NTP::summerTime() { + if ((utcCurrent > utcDST) && (utcCurrent <= utcSTD)) { + return true; + } + else { + return false; + } + } + +uint32_t NTP::ntp() { + return ntpTime; + } + +uint32_t NTP::utc() { + return utcTime; + } diff --git a/libraries/NTP/NTP.h b/libraries/NTP/NTP.h new file mode 100755 index 0000000..e889e87 --- /dev/null +++ b/libraries/NTP/NTP.h @@ -0,0 +1,288 @@ +/** + * NTP library for Arduino framewoek + * The MIT License (MIT) + * (c) 2022 sstaub + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef NTP_H +#define NTP_H + +#include "Arduino.h" +#include +#include + +#define SEVENTYYEARS 2208988800UL +#define UNIXOFFSET 946684800UL + +#ifdef __AVR__ + //#define POSIX_OFFSET NTP_OFFSET - SEVENTYYEARS// - UNIX_OFFSET// + 30 years + #define POSIX_OFFSET UNIXOFFSET +#else + #define POSIX_OFFSET -SEVENTYYEARS +#endif + +#define NTP_PACKET_SIZE 48 +#define NTP_PORT 123 +#define SECS_PER_MINUTES 60 +#define SECS_PER_DAY 86400 + +#define GMT_MESSAGE "GMT +/- offset" +#define RULE_DST_MESSAGE "no DST rule" +#define RULE_STD_MESSAGE "no STD rule" + +enum week_t {Last, First, Second, Third, Fourth}; +enum dow_t {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; +enum month_t {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; + +class NTP { + public: + /** + * @brief constructor for the NTP object + * + * @param udp + */ + NTP(UDP& udp); + + /** + * @brief destructor for the NTP object + * + */ + ~NTP(); + + /** + * @brief starts the underlying UDP client with the default local port + * + * @param server NTP server host name + * @param serverIP NTP server IP address + */ + void begin(const char* server = "pool.ntp.org"); + void begin(IPAddress serverIP); + + /** + * @brief stops the underlying UDP client + * + */ + void stop(); + + /** + * @brief This should be called in the main loop of your application. By default an update from the NTP Server is only + * made every 60 seconds. This can be configured in the NTPTime constructor. + * + * @return true on success + * @return false on no update or update failure + */ + bool update(); + + /** + * @brief set the update interval + * + * @param updateInterval in ms, default = 60000ms + */ + void updateInterval(uint32_t interval); + + /** + * @brief set the rule for DST (daylight saving time) + * start date of DST + * + * @param tzName name of the time zone + * @param week Last, First, Second, Third, Fourth (0 - 4) + * @param wday Sun, Mon, Tue, Wed, Thu, Fri, Sat (0 - 7) + * @param month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec (0 -11) + * @param hour the local hour when rule chages + * @param tzOffset sum of summertime and timezone offset + */ + void ruleDST(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset); + + /** + * @brief get the DST time as a ctime string + * + * @return char* time string + */ + const char* ruleDST(); + + /** + * @brief set the rule for STD (standard day) + * end date of DST + * + * @param tzName name of the time zone + * @param week Last, First, Second, Third, Fourth (0 - 4) + * @param wday Sun, Mon, Tue, Wed, Thu, Fri, Sat (0 - 7) + * @param month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec (0 -11) + * @param hour the local hour when rule chages + * @param tzOffset timezone offset + */ + void ruleSTD(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset); + + /** + * @brief get the STD time as a ctime string + * + * @return char* time string + */ + const char* ruleSTD(); + + /** + * @brief get the name of the timezone + * + * @return char* name of the timezone + */ + const char* tzName(); + + /** + * @brief set the timezone manually + * this should used if there is no DST! + * + * @param tzHours + * @param tzMinutes + */ + void timeZone(int8_t tzHours, int8_t tzMinutes = 0); + + /** + * @brief set daylight saving manually! + * use in conjunction with timeZone, when there is no DST! + * + * @param dstZone + */ + void isDST(bool dstZone); + + /** + * @brief returns the DST state + * + * @return int 1 if summertime, 0 no summertime + */ + bool isDST(); + + /** + * @brief get the Unix epoch timestamp + * + * @return time_t timestamp + */ + time_t epoch(); + + /** + * @brief get the year + * + * @return int year + */ + int16_t year(); + + /** + * @brief get the month + * + * @return int month, 1 = january + */ + int8_t month(); + + /** + * @brief get the day of a month + * + * @return int day + */ + int8_t day(); + + /** + * @brief get the day of a week + * + * @return int day of the week, 0 = sunday + */ + int8_t weekDay(); + + /** + * @brief get the hour of the day + * + * @return int + */ + int8_t hours(); + + /** + * @brief get the minutes of the hour + * + * @return int minutes + */ + int8_t minutes(); + + /** + * @brief get the seconds of a minute + * + * @return int seconds + */ + int8_t seconds(); + + /** + * @brief returns a formatted string + * + * @param format for strftime + * @return char* formated time string + */ + const char* formattedTime(const char *format); + + /** + * @brief returns NTP timestamp + * + * @return uint32_t + */ + uint32_t ntp(); + + /** + * @brief returns UNIX timestamp + * + * @return uint32_t + */ + uint32_t utc(); + + private: + UDP *udp; + const char* server = nullptr; + IPAddress serverIP; + uint8_t ntpRequest[NTP_PACKET_SIZE]; // = {0xE3, 0x00, 0x06, 0xEC}; + uint8_t ntpQuery[NTP_PACKET_SIZE]; + time_t utcCurrent = 0; + time_t local = 0; + struct tm *current; + uint32_t interval = 60000; + uint32_t lastUpdate = 0; + uint8_t tzHours = 0; + uint8_t tzMinutes = 0; + int32_t timezoneOffset; + int16_t dstOffset = 0; + bool dstZone = true; + uint32_t timestamp; + uint32_t ntpTime = 0; + uint32_t utcTime = 0; + time_t utcSTD, utcDST; + time_t dstTime, stdTime; + uint16_t yearDST; + char timeString[64]; + struct ruleDST { + char tzName[6]; // five chars max + int8_t week; // First, Second, Third, Fourth, or Last week of the month + int8_t wday; // day of week, 0 = Sun, 2 = Mon, ... 6 = Sat + int8_t month; // 0 = Jan, 1 = Feb, ... 11=Dec + int8_t hour; // 0 - 23 + int tzOffset; // offset from UTC in minutes + } dstStart, dstEnd; + void init(); + bool ntpUpdate(); + time_t localTime(); + void currentTime(); + void beginDST(); + time_t calcDateDST(struct ruleDST rule, int year); + bool summerTime(); +}; + +#endif diff --git a/libraries/NTP/README.md b/libraries/NTP/README.md new file mode 100755 index 0000000..39b056a --- /dev/null +++ b/libraries/NTP/README.md @@ -0,0 +1,330 @@ +# **NTP** +The **NTP** library allows you to receive time information from the Internet. It also have support for +different timezones and daylight saving time (DST). +This NTP library uses the functions of the time.h standard library.
+ +## Changes for 1.7 + +- support for AVR +- optimizations + +## Changes for 1.6 + +- change of begin(), now you can start with hostname or IP address +- no blocking +- better documentation + +## Example +Example for WIFI boards like ESP32 or MKR1000, NANO RP2040 Connect and other, prints formatted time and date strings to console. + +```cpp +// change next line to use with another board/shield +//#include +//#include // for WiFi shield or ESP32 +//#include // for WiFi 101 shield or MKR1000 +#include // for UNO Wifi Rev 2 or Nano RP2040 connect +//#include "WiFiUdp.h" // not needed for WiFiNINA +#include "NTP.h" + +const char *ssid = "yourSSID"; // your network SSID +const char *password = "yourPASSWORD"; // your network PW + +WiFiUDP wifiUdp; +NTP ntp(wifiUdp); + +void setup() { + Serial.begin(9600); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + Serial.println("Connecting ..."); + delay(500); + } + Serial.println("Connected"); + ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) + ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) + ntp.begin(); + Serial.println("start NTP"); + } + +void loop() { + ntp.update(); + Serial.println(ntp.formattedTime("%d. %B %Y")); // dd. Mmm yyyy + Serial.println(ntp.formattedTime("%A %T")); // Www hh:mm:ss + delay(1000); + } +``` + +# Documentation + +## Class Definitions + +```cpp +NTP(UDP& udp); +``` +Constructor for a NTP object + +Example, this should done before ```setup()``` +```cpp +WiFiUDP wifiUdp; +NTP ntp(wifiUdp); +``` + +```cpp +~NTP(); +``` +Destructor for a NTP object + + +## begin() + +```cpp +void begin(const char* server = "pool.ntp.org"); +void begin(IPAddress serverIP); +``` +Start the underlaying UDP client with a hostname or IP address. + +Example, this must done in ```setup()``` +```cpp +ntp.begin(); // start the NTP client with the standard host +``` + +## stop() + +```cpp +void stop(); +``` +Stop the underlaying UDP client + +Example, this must done in ```setup()``` +```cpp +ntp.stop(); +``` + + +## update() + +```cpp +void update(); +``` +This must called in the main ```loop()``` + +Example +```cpp +loop() { + ntp.update(); + } +``` + +## updateInterval() + +```cpp +void updateInterval(uint32_t interval); +``` +Set the update interval for connecting the NTP server in ms, default is 60000ms (60s) + +Example, this must done in ```setup()``` +```cpp +ntp.updateInterval(1000); // update every second +``` + +## ruleDST() + +```cpp +void ruleDST(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset); +``` +Set the rules for the daylight save time settings + +- tzname is the name of the timezone, e.g. "CEST" (central europe summer time) +- week Last, First, Second, Third, Fourth (0 - 4) +- wday Sun, Mon, Tue, Wed, Thu, Fri, Sat (0 - 7) +- month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec (0 -11) +- hour the local hour when rule changes +- tzOffset timezone offset in minutes + +Example, this must done in ```setup()``` +```cpp +ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) +``` + +## Return ruleDST() + +```cpp +const char* ruleDST(); +``` +Returns the DST time back, formatted as an ```ctime``` string + +## ruleSTD() + +```cpp +void ruleSTD(const char* tzName, int8_t week, int8_t wday, int8_t month, int8_t hour, int tzOffset); +``` + +Set the rules for the standard time settings + +- tzname is the name of the timezone, e.g. "CET" (central europe time) +- week Last, First, Second, Third, Fourth (0 - 4) +- wday Sun, Mon, Tue, Wed, Thu, Fri, Sat (0 - 7) +- month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec (0 -11) +- hour the local hour when rule changes +- tzOffset timezone offset in minutes + +Example, this must done in ```setup()``` +```cpp +ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, time +``` + +## Return ruleSTD() + +```cpp +const char* ruleSTD(); +``` +Return the STD time back, formatted as an ctime string + +## Return tzName() + +```cpp +const char* tzName(); +``` +Return you the name of the current timezone, based on your rule settings + +## timeZone() + +```cpp +void timeZone(int8_t tzHours, int8_t tzMinutes = 0); +``` + +Only use this function when you don't made the rules setting, +you have to the set isDST(false) + +## isDST() + +```cpp +void isDST(bool dstZone); +``` + +Use in conjunction with timeZone, when there is no DST! + +## Return isDST() + +```cpp +bool isDST(); +``` + +Return the DST status back, true if summertime + +## epoch() + +```cpp +time_t epoch(); +``` + +Return the Unix epoch timestamp + +## year(), month(), day(), weekDay(), hours(), minutes(), seconds() + +```cpp +int16_t year(); +int8_t month(); +int8_t day(); +int8_t weekDay(); +int8_t hours(); +int8_t minutes(); +int8_t seconds(); +``` + +Return the datas from the tm structure of the "time.h" library + +## Return formattedTime() + +```cpp +const char* formattedTime(const char *format); +``` + +Return a string, formated with strftime function of standard time library + +Example +```cpp +loop() { + ntp.update(); + Serial.println(ntp.formattedTime("%d. %B %Y")); // dd. Mmm yyyy + Serial.println(ntp.formattedTime("%A %T")); // Www hh:mm:ss + delay(1000); + } +``` + +Format symbols: +``` +| symbol | explanation +/* General */ +| % | writes literal %. The full conversion specification must be %%. +| n | writes newline character +| t | writes horizontal tab character +/* Year */ +| Y | writes year as a decimal number, e.g. 2017 +| y | writes last 2 digits of year as a decimal number (range [00,99]) +| C | writes first 2 digits of year as a decimal number (range [00,99]) +| G | writes ISO 8601 week-based year, i.e. the year that contains the specified week. + In IS0 8601 weeks begin with Monday and the first week of the year must satisfy the following requirements: + - Includes January 4 + - Includes first Thursday of the year +| g | writes last 2 digits of ISO 8601 week-based year, i.e. the year that contains the specified week (range [00,99]). + In IS0 8601 weeks begin with Monday and the first week of the year must satisfy the following requirements: + - Includes January 4 + - Includes first Thursday of the year +/* Month */ +| b | writes abbreviated month name, e.g. Oct (locale dependent) +| h | synonym of b +| B | writes full month name, e.g. October (locale dependent) +| m | writes month as a decimal number (range [01,12]) +/* Week */ +| U | writes week of the year as a decimal number (Sunday is the first day of the week) (range [00,53]) +| W | writes week of the year as a decimal number (Monday is the first day of the week) (range [00,53]) +| V | writes ISO 8601 week of the year (range [01,53]). + In IS0 8601 weeks begin with Monday and the first week of the year must satisfy the following requirements: + - Includes January 4 + - Includes first Thursday of the year +/* Day of the year/month */ +| j | writes day of the year as a decimal number (range [001,366]) +| d | writes day of the month as a decimal number (range [01,31]) +| e | writes day of the month as a decimal number (range [1,31]). + Single digit is preceded by a space. +/* Day of the week */ +| a | writes abbreviated weekday name, e.g. Fri (locale dependent) +| A | writes full weekday name, e.g. Friday (locale dependent) +| w | writes weekday as a decimal number, where Sunday is 0 (range [0-6]) +| u | writes weekday as a decimal number, where Monday is 1 (ISO 8601 format) (range [1-7]) +/* Hour, minute, second */ +| H | writes hour as a decimal number, 24 hour clock (range [00-23]) +| I | writes hour as a decimal number, 12 hour clock (range [01,12]) +| M | writes minute as a decimal number (range [00,59]) +| S | writes second as a decimal number (range [00,60]) +/* Other */ +| c | writes standard date and time string, e.g. Sun Oct 17 04:41:13 2010 (locale dependent) +| x | writes localized date representation (locale dependent) +| X | writes localized time representation (locale dependent) +| D | equivalent to "%m/%d/%y" +| F | equivalent to "%Y-%m-%d" (the ISO 8601 date format) +| r | writes localized 12-hour clock time (locale dependent) +| R | equivalent to "%H:%M" +| T | equivalent to "%H:%M:%S" (the ISO 8601 time format) +| p | writes localized a.m. or p.m. (locale dependent) +``` + +## Return utc() + + ```cpp + uint32_t utc(); + ``` + + Return the timestamp received from the ntp server in Unix timestamp format + + ## Return ntp() + + ```cpp + uint32_t ntp(); + ``` + + Return the timestamp received from the ntp server in the NTP timestamp format + + + diff --git a/libraries/NTP/examples/ESP32_OLED_NTP/ESP32_OLED_NTP.ino b/libraries/NTP/examples/ESP32_OLED_NTP/ESP32_OLED_NTP.ino new file mode 100644 index 0000000..d150d66 --- /dev/null +++ b/libraries/NTP/examples/ESP32_OLED_NTP/ESP32_OLED_NTP.ino @@ -0,0 +1,58 @@ +// example ESP32 board with oled, use oled lib https://github.com/squix78/esp8266-oled-ssd1306 + +#include +#include "WiFi.h" +#include +#include "SSD1306.h" +#include "NTP.h" + +char ssid[] = "yourSSID"; +char password[] = "yourPASSWORD"; + +SSD1306 display(0x3c, 5, 4); +WiFiUDP wifiUdp; +NTP ntp(wifiUdp); + +void display_text(String text){ + display.clear(); + display.setColor(WHITE); + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.drawString(64, 15, text); + display.display(); + } + +void setup() { + Serial.begin(9600); + display.init(); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + display_text("Connecting ..."); + delay (500); + } + display.clear(); + display_text("Connected"); + delay (500); + ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) + ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) + // ntp.isDST(false); + // ntp.timeZone(1); + // ntp.offset(0, 0, 0, 0); + ntp.begin(); + display_text("start NTP"); + delay (500); + } + +void loop() { + ntp.update(); + display.clear(); + display.fillRect(1, 0, 126 * ntp.seconds() / 59, 2); + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.drawString(64, 5, ntp.formattedTime("%d. %B %Y")); + display.drawString(64, 15, ntp.formattedTime("%A %T")); + display.drawString(64, 25, ntp.ruleDST()); + display.drawString(64, 35, ntp.ruleSTD()); + display.drawString(64, 45, ntp.tzName()); + display.display(); + delay(500); + } diff --git a/libraries/NTP/examples/WIFI_NTP/WIFI_NTP.ino b/libraries/NTP/examples/WIFI_NTP/WIFI_NTP.ino new file mode 100644 index 0000000..2e8e408 --- /dev/null +++ b/libraries/NTP/examples/WIFI_NTP/WIFI_NTP.ino @@ -0,0 +1,37 @@ +// example for WIFI based boards like ESP8266, ESP32, Nano RP2040 Connect, WiFi 101 shield or MKR1000 + +#include "Arduino.h" +// change next line to use with another board/shield +//#include +//#include // for WiFi shield or ESP32 +//#include // for WiFi 101 shield or MKR1000 +#include // for e.g. Nano RP2040 Connect +//#include "WiFiUdp.h" // not needed for WiFiNINA +#include "NTP.h" + +char ssid[] = "yourSSID"; +char password[] = "yourPASSWORD"; + +WiFiUDP wifiUdp; +NTP ntp(wifiUdp); + +void setup() { + Serial.begin(9600); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + Serial.println("Connecting ..."); + delay(500); + } + Serial.println("Connected"); + ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) + ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) + ntp.begin(); + Serial.println("start NTP"); + } + +void loop() { + ntp.update(); + Serial.println(ntp.formattedTime("%d. %B %Y")); // dd. Mmm yyyy + Serial.println(ntp.formattedTime("%A %T")); // Www hh:mm:ss + delay(1000); + } diff --git a/libraries/NTP/keywords.txt b/libraries/NTP/keywords.txt new file mode 100755 index 0000000..8350645 --- /dev/null +++ b/libraries/NTP/keywords.txt @@ -0,0 +1,30 @@ +####################################### +# Datatypes (KEYWORD1) +####################################### + +NTP KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +stop KEYWORD2 +update KEYWORD2 +updateInterval KEYWORD2 +timeZone KEYWORD2 +ruleDST KEYWORD2 +ruleSTD KEYWORD2 +tzName KEYWORD2 +isDST KEYWORD2 +epoch KEYWORD2 +year KEYWORD2 +month KEYWORD2 +day KEYWORD2 +weekDay KEYWORD2 +hours KEYWORD2 +minutes KEYWORD2 +seconds KEYWORD2 +formattedTime KEYWORD2 +utc KEYWORD2 +ntp KEYWORD2 diff --git a/libraries/NTP/library.json b/libraries/NTP/library.json new file mode 100755 index 0000000..2dbe9dc --- /dev/null +++ b/libraries/NTP/library.json @@ -0,0 +1,13 @@ +{ + "name": "NTP", + "keywords": "ntp, client, time, timezone", + "description": "A NTP client with timezone support", + "repository": + { + "type": "git", + "url": "https://github.com/sstaub/NTP.git" + }, + "version": "1.7", + "frameworks": "arduino", + "platforms": "*" +} diff --git a/libraries/NTP/library.properties b/libraries/NTP/library.properties new file mode 100644 index 0000000..4f3cda3 --- /dev/null +++ b/libraries/NTP/library.properties @@ -0,0 +1,10 @@ +name=NTP +version=1.7 +author=Stefan Staub +maintainer=Stefan Staub +sentence=NTP library +paragraph=NTP library for Arduino framework, using standard time.h library. +category=Timing +url=https://github.com/sstaub/NTP +architectures=* +includes=NTP.h diff --git a/libraries/NTPClient/CHANGELOG b/libraries/NTPClient/CHANGELOG new file mode 100644 index 0000000..6a082d5 --- /dev/null +++ b/libraries/NTPClient/CHANGELOG @@ -0,0 +1,15 @@ +NTPClient 3.1.0 - 2016.05.31 + +* Added functions for changing the timeOffset and updateInterval later. Thanks @SirUli + +NTPClient 3.0.0 - 2016.04.19 + +* Constructors now require UDP instance argument, to add support for non-ESP8266 boards +* Added optional begin API to override default local port +* Added end API to close UDP socket +* Changed return type of update and forceUpdate APIs to bool, and return success or failure +* Change return type of getDay, getHours, getMinutes, and getSeconds to int + +Older + +* Changes not recorded diff --git a/libraries/NTPClient/NTPClient.cpp b/libraries/NTPClient/NTPClient.cpp new file mode 100755 index 0000000..b435855 --- /dev/null +++ b/libraries/NTPClient/NTPClient.cpp @@ -0,0 +1,212 @@ +/** + * The MIT License (MIT) + * Copyright (c) 2015 by Fabrice Weinberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "NTPClient.h" + +NTPClient::NTPClient(UDP& udp) { + this->_udp = &udp; +} + +NTPClient::NTPClient(UDP& udp, long timeOffset) { + this->_udp = &udp; + this->_timeOffset = timeOffset; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName) { + this->_udp = &udp; + this->_poolServerName = poolServerName; +} + +NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP) { + this->_udp = &udp; + this->_poolServerIP = poolServerIP; + this->_poolServerName = NULL; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; +} + +NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset){ + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerIP = poolServerIP; + this->_poolServerName = NULL; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; + this->_updateInterval = updateInterval; +} + +NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerIP = poolServerIP; + this->_poolServerName = NULL; + this->_updateInterval = updateInterval; +} + +void NTPClient::begin() { + this->begin(NTP_DEFAULT_LOCAL_PORT); +} + +void NTPClient::begin(unsigned int port) { + this->_port = port; + + this->_udp->begin(this->_port); + + this->_udpSetup = true; +} + +bool NTPClient::forceUpdate() { + #ifdef DEBUG_NTPClient + Serial.println("Update from NTP Server"); + #endif + + // flush any existing packets + while(this->_udp->parsePacket() != 0) + this->_udp->flush(); + + this->sendNTPPacket(); + + // Wait till data is there or timeout... + byte timeout = 0; + int cb = 0; + do { + delay ( 10 ); + cb = this->_udp->parsePacket(); + if (timeout > 100) return false; // timeout after 1000 ms + timeout++; + } while (cb == 0); + + this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time + + this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); + + unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); + unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + + this->_currentEpoc = secsSince1900 - SEVENZYYEARS; + + return true; // return true after successful update +} + +bool NTPClient::update() { + if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval + || this->_lastUpdate == 0) { // Update if there was no update yet. + if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) this->begin(this->_port); // setup the UDP client if needed + return this->forceUpdate(); + } + return false; // return false if update does not occur +} + +bool NTPClient::isTimeSet() const { + return (this->_lastUpdate != 0); // returns true if the time has been set, else false +} + +unsigned long NTPClient::getEpochTime() const { + return this->_timeOffset + // User offset + this->_currentEpoc + // Epoch returned by the NTP server + ((millis() - this->_lastUpdate) / 1000); // Time since last update +} + +int NTPClient::getDay() const { + return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday +} +int NTPClient::getHours() const { + return ((this->getEpochTime() % 86400L) / 3600); +} +int NTPClient::getMinutes() const { + return ((this->getEpochTime() % 3600) / 60); +} +int NTPClient::getSeconds() const { + return (this->getEpochTime() % 60); +} + +String NTPClient::getFormattedTime() const { + unsigned long rawTime = this->getEpochTime(); + unsigned long hours = (rawTime % 86400L) / 3600; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + + unsigned long minutes = (rawTime % 3600) / 60; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + + unsigned long seconds = rawTime % 60; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + + return hoursStr + ":" + minuteStr + ":" + secondStr; +} + +void NTPClient::end() { + this->_udp->stop(); + + this->_udpSetup = false; +} + +void NTPClient::setTimeOffset(int timeOffset) { + this->_timeOffset = timeOffset; +} + +void NTPClient::setUpdateInterval(unsigned long updateInterval) { + this->_updateInterval = updateInterval; +} + +void NTPClient::setPoolServerName(const char* poolServerName) { + this->_poolServerName = poolServerName; +} + +void NTPClient::sendNTPPacket() { + // set all bytes in the buffer to 0 + memset(this->_packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode + this->_packetBuffer[1] = 0; // Stratum, or type of clock + this->_packetBuffer[2] = 6; // Polling Interval + this->_packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + this->_packetBuffer[12] = 49; + this->_packetBuffer[13] = 0x4E; + this->_packetBuffer[14] = 49; + this->_packetBuffer[15] = 52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + if (this->_poolServerName) { + this->_udp->beginPacket(this->_poolServerName, 123); + } else { + this->_udp->beginPacket(this->_poolServerIP, 123); + } + this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE); + this->_udp->endPacket(); +} + +void NTPClient::setRandomPort(unsigned int minValue, unsigned int maxValue) { + randomSeed(analogRead(0)); + this->_port = random(minValue, maxValue); +} diff --git a/libraries/NTPClient/NTPClient.h b/libraries/NTPClient/NTPClient.h new file mode 100755 index 0000000..a31d32f --- /dev/null +++ b/libraries/NTPClient/NTPClient.h @@ -0,0 +1,114 @@ +#pragma once + +#include "Arduino.h" + +#include + +#define SEVENZYYEARS 2208988800UL +#define NTP_PACKET_SIZE 48 +#define NTP_DEFAULT_LOCAL_PORT 1337 + +class NTPClient { + private: + UDP* _udp; + bool _udpSetup = false; + + const char* _poolServerName = "pool.ntp.org"; // Default time server + IPAddress _poolServerIP; + unsigned int _port = NTP_DEFAULT_LOCAL_PORT; + long _timeOffset = 0; + + unsigned long _updateInterval = 60000; // In ms + + unsigned long _currentEpoc = 0; // In s + unsigned long _lastUpdate = 0; // In ms + + byte _packetBuffer[NTP_PACKET_SIZE]; + + void sendNTPPacket(); + + public: + NTPClient(UDP& udp); + NTPClient(UDP& udp, long timeOffset); + NTPClient(UDP& udp, const char* poolServerName); + NTPClient(UDP& udp, const char* poolServerName, long timeOffset); + NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval); + NTPClient(UDP& udp, IPAddress poolServerIP); + NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset); + NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval); + + /** + * Set time server name + * + * @param poolServerName + */ + void setPoolServerName(const char* poolServerName); + + /** + * Set random local port + */ + void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535); + + /** + * Starts the underlying UDP client with the default local port + */ + void begin(); + + /** + * Starts the underlying UDP client with the specified local port + */ + void begin(unsigned int port); + + /** + * This should be called in the main loop of your application. By default an update from the NTP Server is only + * made every 60 seconds. This can be configured in the NTPClient constructor. + * + * @return true on success, false on failure + */ + bool update(); + + /** + * This will force the update from the NTP Server. + * + * @return true on success, false on failure + */ + bool forceUpdate(); + + /** + * This allows to check if the NTPClient successfully received a NTP packet and set the time. + * + * @return true if time has been set, else false + */ + bool isTimeSet() const; + + int getDay() const; + int getHours() const; + int getMinutes() const; + int getSeconds() const; + + /** + * Changes the time offset. Useful for changing timezones dynamically + */ + void setTimeOffset(int timeOffset); + + /** + * Set the update interval to another frequency. E.g. useful when the + * timeOffset should not be set in the constructor + */ + void setUpdateInterval(unsigned long updateInterval); + + /** + * @return time formatted like `hh:mm:ss` + */ + String getFormattedTime() const; + + /** + * @return time in seconds since Jan. 1, 1970 + */ + unsigned long getEpochTime() const; + + /** + * Stops the underlying UDP client + */ + void end(); +}; diff --git a/libraries/NTPClient/README.md b/libraries/NTPClient/README.md new file mode 100644 index 0000000..f83882c --- /dev/null +++ b/libraries/NTPClient/README.md @@ -0,0 +1,52 @@ +# NTPClient + +[![Check Arduino status](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml) +[![Compile Examples status](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml) +[![Spell Check status](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml) + +Connect to a NTP server, here is how: + +```cpp +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; + +// By default 'pool.ntp.org' is used with 60 seconds update interval and +// no offset +NTPClient timeClient(ntpUDP); + +// You can specify the time server pool and the offset, (in seconds) +// additionally you can specify the update interval (in milliseconds). +// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); + +void setup(){ + Serial.begin(115200); + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} +``` + +## Function documentation +`getEpochTime` returns the Unix epoch, which are the seconds elapsed since 00:00:00 UTC on 1 January 1970 (leap seconds are ignored, every day is treated as having 86400 seconds). **Attention**: If you have set a time offset this time offset will be added to your epoch timestamp. diff --git a/libraries/NTPClient/examples/Advanced/Advanced.ino b/libraries/NTPClient/examples/Advanced/Advanced.ino new file mode 100644 index 0000000..18a6a97 --- /dev/null +++ b/libraries/NTPClient/examples/Advanced/Advanced.ino @@ -0,0 +1,37 @@ +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; + +// You can specify the time server pool and the offset (in seconds, can be +// changed later with setTimeOffset() ). Additionally you can specify the +// update interval (in milliseconds, can be changed using setUpdateInterval() ). +NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} diff --git a/libraries/NTPClient/examples/Basic/Basic.ino b/libraries/NTPClient/examples/Basic/Basic.ino new file mode 100644 index 0000000..f0a2a7c --- /dev/null +++ b/libraries/NTPClient/examples/Basic/Basic.ino @@ -0,0 +1,33 @@ +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} diff --git a/libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino b/libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino new file mode 100644 index 0000000..619bfde --- /dev/null +++ b/libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino @@ -0,0 +1,53 @@ +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; +// initialized to a time offset of 10 hours +NTPClient timeClient(ntpUDP,"pool.ntp.org", 36000, 60000); +// HH:MM:SS +// timeClient initializes to 10:00:00 if it does not receive an NTP packet +// before the 100ms timeout. +// without isTimeSet() the LED would be switched on, although the time +// was not yet set correctly. + +// blue LED on ESP-12F +const int led = 2; +const int hour = 10; +const int minute = 0; + +void setup(){ + Serial.begin(115200); + + pinMode(led, OUTPUT); + // led is off when pin is high + digitalWrite(led, 1); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay (500); + Serial.print ("."); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + if(timeClient.isTimeSet()) { + if (hour == timeClient.getHours() && minute == timeClient.getMinutes()) { + digitalWrite(led, 0); + } + } + + delay(1000); +} diff --git a/libraries/NTPClient/keywords.txt b/libraries/NTPClient/keywords.txt new file mode 100644 index 0000000..edce989 --- /dev/null +++ b/libraries/NTPClient/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Datatypes (KEYWORD1) +####################################### + +NTPClient KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +end KEYWORD2 +update KEYWORD2 +forceUpdate KEYWORD2 +isTimeSet KEYWORD2 +getDay KEYWORD2 +getHours KEYWORD2 +getMinutes KEYWORD2 +getSeconds KEYWORD2 +getFormattedTime KEYWORD2 +getEpochTime KEYWORD2 +setTimeOffset KEYWORD2 +setUpdateInterval KEYWORD2 +setPoolServerName KEYWORD2 diff --git a/libraries/NTPClient/library.properties b/libraries/NTPClient/library.properties new file mode 100644 index 0000000..abdd80d --- /dev/null +++ b/libraries/NTPClient/library.properties @@ -0,0 +1,9 @@ +name=NTPClient +version=3.2.1 +author=Fabrice Weinberg +maintainer=Fabrice Weinberg +sentence=An NTPClient to connect to a time server +paragraph=Get time from a NTP server and keep it in sync. +category=Timing +url=https://github.com/arduino-libraries/NTPClient +architectures=* diff --git a/sketches/doorbell/TFT_eSPI b/sketches/doorbell/TFT_eSPI new file mode 160000 index 0000000..42f64b3 --- /dev/null +++ b/sketches/doorbell/TFT_eSPI @@ -0,0 +1 @@ +Subproject commit 42f64b37e450e43868ca0e811075484e2f3bfccb diff --git a/sketches/doorbell/doorbell.ino b/sketches/doorbell/doorbell.ino index eb3552f..9a26737 100644 --- a/sketches/doorbell/doorbell.ino +++ b/sketches/doorbell/doorbell.ino @@ -9,7 +9,7 @@ #include // ============== CONFIG ============== -const char* WIFI_SSID = "Dobro Veče"; +const char* WIFI_SSID = "KH-IoT"; const char* WIFI_PASS = "goodnight"; const char* ALERT_URL = "https://ntfy.sh/ALERT_klubhaus_topic/json?since=all";