From 198c6034942d5957782a901ad30b81b117fb7a83 Mon Sep 17 00:00:00 2001 From: Felix Biego Date: Fri, 29 Jul 2022 20:00:58 +0300 Subject: [PATCH] v2.0.0 Temporary fix 2K38 bug #10 #12 --- ESP32Time.cpp | 48 +++++++++---- ESP32Time.h | 17 +++-- README.md | 10 +-- examples/esp32_time/esp32_time.ino | 2 +- .../esp32_time_multiple.ino | 14 ++-- .../esp32_time_sleep/esp32_time_sleep.ino | 70 +++++++++++++++++++ library.json | 2 +- library.properties | 2 +- 8 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 examples/esp32_time_sleep/esp32_time_sleep.ino diff --git a/ESP32Time.cpp b/ESP32Time.cpp index 168ffc8..a4f05cb 100644 --- a/ESP32Time.cpp +++ b/ESP32Time.cpp @@ -36,7 +36,7 @@ ESP32Time::ESP32Time(){} @param offest gmt offset in seconds */ -ESP32Time::ESP32Time(long offset){ +ESP32Time::ESP32Time(unsigned long offset){ this->offset = offset; } @@ -88,9 +88,14 @@ void ESP32Time::setTimeStruct(tm t) { @param ms microseconds (optional) */ -void ESP32Time::setTime(long epoch, int ms) { +void ESP32Time::setTime(unsigned long epoch, int ms) { struct timeval tv; - tv.tv_sec = epoch; // epoch time (seconds) + if (epoch > 2082758399){ + this->overflow = true; + tv.tv_sec = epoch - 2082758399; // epoch time (seconds) + } else { + tv.tv_sec = epoch; // epoch time (seconds) + } tv.tv_usec = ms; // microseconds settimeofday(&tv, NULL); } @@ -100,10 +105,19 @@ void ESP32Time::setTime(long epoch, int ms) { */ tm ESP32Time::getTimeStruct(){ struct tm timeinfo; - getLocalTime(&timeinfo); + time_t now; + time(&now); + localtime_r(&now, &timeinfo); time_t tt = mktime (&timeinfo); - tt = tt + offset; - struct tm * tn = localtime(&tt);; + + if (this->overflow){ + tt += 63071999; + } + tt += offset; + struct tm * tn = localtime(&tt); + if (this->overflow){ + tn->tm_year += 64; + } return *tn; } @@ -193,38 +207,42 @@ String ESP32Time::getDate(bool mode){ } /*! - @brief get the current milliseconds as long + @brief get the current milliseconds as unsigned long */ -long ESP32Time::getMillis(){ +unsigned long ESP32Time::getMillis(){ struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_usec/1000; } /*! - @brief get the current microseconds as long + @brief get the current microseconds as unsigned long */ -long ESP32Time::getMicros(){ +unsigned long ESP32Time::getMicros(){ struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_usec; } /*! - @brief get the current epoch seconds as long + @brief get the current epoch seconds as unsigned long */ -long ESP32Time::getEpoch(){ +unsigned long ESP32Time::getEpoch(){ struct tm timeinfo = getTimeStruct(); return mktime(&timeinfo); } /*! - @brief get the current epoch seconds as long from the rtc without offset + @brief get the current epoch seconds as unsigned long from the rtc without offset */ -long ESP32Time::getLocalEpoch(){ +unsigned long ESP32Time::getLocalEpoch(){ struct timeval tv; gettimeofday(&tv, NULL); - return tv.tv_sec; + unsigned long epoch = tv.tv_sec; + if (this->overflow){ + epoch += 63071999 + 2019686400; + } + return epoch; } /*! diff --git a/ESP32Time.h b/ESP32Time.h index 3038aec..43b46b1 100644 --- a/ESP32Time.h +++ b/ESP32Time.h @@ -31,8 +31,8 @@ class ESP32Time { public: ESP32Time(); - ESP32Time(long offset); - void setTime(long epoch = 1609459200, int ms = 0); // default (1609459200) = 1st Jan 2021 + ESP32Time(unsigned long offset); + void setTime(unsigned long epoch = 1609459200, int ms = 0); // default (1609459200) = 1st Jan 2021 void setTime(int sc, int mn, int hr, int dy, int mt, int yr, int ms = 0); void setTimeStruct(tm t); tm getTimeStruct(); @@ -44,9 +44,9 @@ class ESP32Time { String getDate(bool mode = false); String getAmPm(bool lowercase = false); - long getEpoch(); - long getMillis(); - long getMicros(); + unsigned long getEpoch(); + unsigned long getMillis(); + unsigned long getMicros(); int getSecond(); int getMinute(); int getHour(bool mode = false); @@ -56,8 +56,11 @@ class ESP32Time { int getMonth(); int getYear(); - long offset; - long getLocalEpoch(); + unsigned long offset; + unsigned long getLocalEpoch(); + + private: + bool overflow; }; diff --git a/README.md b/README.md index d7d79e7..2e6f19c 100644 --- a/README.md +++ b/README.md @@ -20,16 +20,16 @@ getDateTime(true) // (String) Sunday, January 17 2021 15:24:38 getTimeDate() // (String) 15:24:38 Sun, Jan 17 2021 getTimeDate(true) // (String) 15:24:38 Sunday, January 17 2021 -getMicros() // (long) 723546 -getMillis() // (long) 723 -getEpoch() // (long) 1609459200 -getLocalEpoch() // (long) 1609459200 // local epoch without offset +getMicros() // (unsigned long) 723546 +getMillis() // (unsigned long) 723 +getEpoch() // (unsigned long) 1609459200 +getLocalEpoch() // (unsigned long) 1609459200 // local epoch without offset getSecond() // (int) 38 (0-59) getMinute() // (int) 24 (0-59) getHour() // (int) 3 (0-12) getHour(true) // (int) 15 (0-23) getAmPm() // (String) pm -getAmPm(true) // (String) PM +getAmPm(false) // (String) PM getDay() // (int) 17 (1-31) getDayofWeek() // (int) 0 (0-6) getDayofYear() // (int) 16 (0-365) diff --git a/examples/esp32_time/esp32_time.ino b/examples/esp32_time/esp32_time.ino index 53a7066..029b72e 100644 --- a/examples/esp32_time/esp32_time.ino +++ b/examples/esp32_time/esp32_time.ino @@ -29,7 +29,7 @@ ESP32Time rtc(3600); // offset in seconds GMT+1 void setup() { Serial.begin(115200); - rtc.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 + rtc.setTime(30, 24, 15, 17, 1, 2042); // 17th Jan 2021 15:24:30 //rtc.setTime(1609459200); // 1st Jan 2021 00:00:00 //rtc.offset = 7200; // change offset value diff --git a/examples/esp32_time_multiple/esp32_time_multiple.ino b/examples/esp32_time_multiple/esp32_time_multiple.ino index bbab7e8..97cdc25 100644 --- a/examples/esp32_time_multiple/esp32_time_multiple.ino +++ b/examples/esp32_time_multiple/esp32_time_multiple.ino @@ -47,9 +47,9 @@ void loop() { // Serial.println(rtc.getTimeDate()); // (String) 15:24:38 Sun, Jan 17 2021 // Serial.println(rtc.getTimeDate(true)); // (String) 15:24:38 Sunday, January 17 2021 // -// Serial.println(rtc.getMicros()); // (long) 723546 -// Serial.println(rtc.getMillis()); // (long) 723 -// Serial.println(rtc.getEpoch()); // (long) 1609459200 +// Serial.println(rtc.getMicros()); // (unsigned long) 723546 +// Serial.println(rtc.getMillis()); // (unsigned long) 723 +// Serial.println(rtc.getEpoch()); // (unsigned long) 1609459200 // Serial.println(rtc.getSecond()); // (int) 38 (0-59) // Serial.println(rtc.getMinute()); // (int) 24 (0-59) // Serial.println(rtc.getHour()); // (int) 3 (0-12) @@ -68,10 +68,10 @@ void loop() { // formating options http://www.cplusplus.com/reference/ctime/strftime/ - Serial.println(rtc.getEpoch()); // (long) - Serial.println(rtc1.getEpoch()); // (long) - Serial.println(rtc2.getEpoch()); // (long) + Serial.println(rtc.getEpoch()); // (unsigned long) + Serial.println(rtc1.getEpoch()); // (unsigned long) + Serial.println(rtc2.getEpoch()); // (unsigned long) - Serial.println(rtc.getLocalEpoch()); // (long) epoch without offset, same for all instances + Serial.println(rtc.getLocalEpoch()); // (unsigned long) epoch without offset, same for all instances delay(1000); } diff --git a/examples/esp32_time_sleep/esp32_time_sleep.ino b/examples/esp32_time_sleep/esp32_time_sleep.ino new file mode 100644 index 0000000..805d7d6 --- /dev/null +++ b/examples/esp32_time_sleep/esp32_time_sleep.ino @@ -0,0 +1,70 @@ +/* + MIT License + + Copyright (c) 2021 Felix Biego + + 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 + +#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */ +#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */ + +ESP32Time rtc; + + +void wakeup_reason() { + esp_sleep_wakeup_cause_t wakeup_reason; + + wakeup_reason = esp_sleep_get_wakeup_cause(); + switch (wakeup_reason) + { + case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; + case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; + case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; + case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; + case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; + default : + Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); + rtc.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 + //rtc.setTime(1609459200); // 1st Jan 2021 00:00:00 + //rtc.offset = 7200; // change offset value + + break; + } +} + +void setup() { + Serial.begin(115200); + + wakeup_reason(); + + Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format + + esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); + + Serial.println("Going to sleep now"); + Serial.flush(); + esp_deep_sleep_start(); +} + +void loop() { + +} diff --git a/library.json b/library.json index 50cdb52..185fee7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP32Time", - "version": "1.1.0", + "version": "2.0.0", "keywords": "Arduino, ESP32, Time, Internal RTC", "description": "An Arduino library for setting and retrieving internal RTC time on ESP32 boards", "repository": diff --git a/library.properties b/library.properties index 3f4816a..5926944 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP32Time -version=1.1.0 +version=2.0.0 author=fbiego maintainer=fbiego sentence=Set and retrieve internal RTC time on ESP32 boards.