├── .gitignore ├── library.properties ├── keywords.txt ├── library.json ├── LICENSE ├── README.md ├── ESP32Time.h ├── examples ├── esp32_time_sleep │ └── esp32_time_sleep.ino ├── esp32_time │ └── esp32_time.ino ├── esp32_time_multiple │ └── esp32_time_multiple.ino └── esp32_webserver_time_sleep │ └── esp32_webserver_time_sleep.ino └── ESP32Time.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.py 3 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ESP32Time 2 | version=2.0.6 3 | author=fbiego 4 | maintainer=fbiego 5 | sentence=Set and retrieve internal RTC time on ESP32 boards. 6 | paragraph=No need for external RTC module or NTP time synchronization. 7 | category=Timing 8 | url=https://github.com/fbiego/ESP32Time 9 | architectures=* 10 | includes=ESP32Time.h 11 | 12 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ESP32Time KEYWORD1 2 | 3 | setTime KEYWORD2 4 | getTime KEYWORD2 5 | setTimeStruct KEYWORD2 6 | getTimeStruct KEYWORD2 7 | getDateTime KEYWORD2 8 | getTimeDate KEYWORD2 9 | getDate KEYWORD2 10 | getAmPm KEYWORD2 11 | getMillis KEYWORD2 12 | getMicros KEYWORD2 13 | getEpoch KEYWORD2 14 | getLocalEpoch KEYWORD2 15 | getSecond KEYWORD2 16 | getMinute KEYWORD2 17 | getHour KEYWORD2 18 | getDay KEYWORD2 19 | getDayofWeek KEYWORD2 20 | getDayofYear KEYWORD2 21 | getMonth KEYWORD2 22 | getYear KEYWORD2 23 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESP32Time", 3 | "version": "2.0.6", 4 | "keywords": "Arduino, ESP32, Time, Internal RTC", 5 | "description": "An Arduino library for setting and retrieving internal RTC time on ESP32 boards", 6 | "repository": 7 | { 8 | "type": "git", 9 | "url": "https://github.com/fbiego/ESP32Time" 10 | }, 11 | "authors": 12 | [ 13 | { 14 | "name": "fbiego", 15 | "email": "fbiego.fb@gmail.com", 16 | "maintainer": true 17 | } 18 | ], 19 | "frameworks": "arduino", 20 | "platforms": "espressif8266, espressif32" 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Felix Biego 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32Time 2 | An Arduino library for setting and retrieving internal RTC time on ESP32 boards 3 | 4 | [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP32Time.svg?)](https://www.arduinolibraries.info/libraries/esp32-time) 5 | [![PlatformIO Registry](https://badges.registry.platformio.org/packages/fbiego/library/ESP32Time.svg)](https://registry.platformio.org/libraries/fbiego/ESP32Time) 6 | 7 | ## Functions 8 | 9 | ``` 10 | ESP32Time rtc(offset); // create an instance with a specifed offset in seconds 11 | rtc.offset; // get or modify the current offset 12 | setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 13 | setTime(1609459200); // 1st Jan 2021 00:00:00 14 | setTimeStruct(time); // set with time struct 15 | 16 | getTime() // (String) 15:24:38 17 | getDate() // (String) Sun, Jan 17 2021 18 | getDate(true) // (String) Sunday, January 17 2021 19 | getDateTime() // (String) Sun, Jan 17 2021 15:24:38 20 | getDateTime(true) // (String) Sunday, January 17 2021 15:24:38 21 | getTimeDate() // (String) 15:24:38 Sun, Jan 17 2021 22 | getTimeDate(true) // (String) 15:24:38 Sunday, January 17 2021 23 | 24 | getMicros() // (unsigned long) 723546 25 | getMillis() // (unsigned long) 723 26 | getEpoch() // (unsigned long) 1609459200 27 | getLocalEpoch() // (unsigned long) 1609459200 // local epoch without offset 28 | getSecond() // (int) 38 (0-59) 29 | getMinute() // (int) 24 (0-59) 30 | getHour() // (int) 3 (1-12) 31 | getHour(true) // (int) 15 (0-23) 32 | getAmPm() // (String) PM 33 | getAmPm(true) // (String) pm 34 | getDay() // (int) 17 (1-31) 35 | getDayofWeek() // (int) 0 (0-6) 36 | getDayofYear() // (int) 16 (0-365) 37 | getMonth() // (int) 0 (0-11) 38 | getYear() // (int) 2021 39 | 40 | getTime("%A, %B %d %Y %H:%M:%S") // (String) returns time with specified format 41 | ``` 42 | [`Formatting options`](http://www.cplusplus.com/reference/ctime/strftime/) 43 | -------------------------------------------------------------------------------- /ESP32Time.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Felix Biego 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef ESP32TIME_H 26 | #define ESP32TIME_H 27 | 28 | #include 29 | 30 | class ESP32Time { 31 | 32 | public: 33 | ESP32Time(); 34 | ESP32Time(long offset); 35 | void setTime(unsigned long epoch = 1609459200, int ms = 0) const; // default (1609459200) = 1st Jan 2021 36 | void setTime(int sc, int mn, int hr, int dy, int mt, int yr, int ms = 0) const; 37 | void setTimeStruct(tm t) const; 38 | tm getTimeStruct() const; 39 | String getTime(String format) const; 40 | 41 | String getTime() const; 42 | String getDateTime(bool mode = false) const; 43 | String getTimeDate(bool mode = false) const; 44 | String getDate(bool mode = false) const; 45 | String getAmPm(bool lowercase = false) const; 46 | 47 | unsigned long getEpoch() const; 48 | unsigned long getMillis() const; 49 | unsigned long getMicros() const; 50 | int getSecond() const; 51 | int getMinute() const; 52 | int getHour(bool mode = false) const; 53 | int getDay() const; 54 | int getDayofWeek() const; 55 | int getDayofYear() const; 56 | int getMonth() const; 57 | int getYear() const; 58 | 59 | long offset = 0; 60 | unsigned long getLocalEpoch() const; 61 | 62 | 63 | 64 | }; 65 | 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /examples/esp32_time_sleep/esp32_time_sleep.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Felix Biego 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | #define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */ 28 | #define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */ 29 | 30 | ESP32Time rtc; 31 | 32 | 33 | void wakeup_reason() { 34 | esp_sleep_wakeup_cause_t wakeup_reason; 35 | 36 | wakeup_reason = esp_sleep_get_wakeup_cause(); 37 | switch (wakeup_reason) 38 | { 39 | case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; 40 | case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; 41 | case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; 42 | case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; 43 | case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; 44 | default : 45 | Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); 46 | rtc.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 47 | //rtc.setTime(1609459200); // 1st Jan 2021 00:00:00 48 | //rtc.offset = 7200; // change offset value 49 | 50 | break; 51 | } 52 | } 53 | 54 | void setup() { 55 | Serial.begin(115200); 56 | 57 | wakeup_reason(); 58 | 59 | Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 60 | 61 | esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); 62 | 63 | Serial.println("Going to sleep now"); 64 | Serial.flush(); 65 | esp_deep_sleep_start(); 66 | } 67 | 68 | void loop() { 69 | 70 | } 71 | -------------------------------------------------------------------------------- /examples/esp32_time/esp32_time.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Felix Biego 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | //ESP32Time rtc; 28 | ESP32Time rtc(3600); // offset in seconds GMT+1 29 | 30 | void setup() { 31 | Serial.begin(115200); 32 | rtc.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 33 | //rtc.setTime(1609459200); // 1st Jan 2021 00:00:00 34 | //rtc.offset = 7200; // change offset value 35 | 36 | /*---------set with NTP---------------*/ 37 | // configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); 38 | // struct tm timeinfo; 39 | // if (getLocalTime(&timeinfo)){ 40 | // rtc.setTimeStruct(timeinfo); 41 | // } 42 | } 43 | 44 | void loop() { 45 | // Serial.println(rtc.getTime()); // (String) 15:24:38 46 | // Serial.println(rtc.getDate()); // (String) Sun, Jan 17 2021 47 | // Serial.println(rtc.getDate(true)); // (String) Sunday, January 17 2021 48 | // Serial.println(rtc.getDateTime()); // (String) Sun, Jan 17 2021 15:24:38 49 | // Serial.println(rtc.getDateTime(true)); // (String) Sunday, January 17 2021 15:24:38 50 | // Serial.println(rtc.getTimeDate()); // (String) 15:24:38 Sun, Jan 17 2021 51 | // Serial.println(rtc.getTimeDate(true)); // (String) 15:24:38 Sunday, January 17 2021 52 | // 53 | // Serial.println(rtc.getMicros()); // (long) 723546 54 | // Serial.println(rtc.getMillis()); // (long) 723 55 | // Serial.println(rtc.getEpoch()); // (long) 1609459200 56 | // Serial.println(rtc.getSecond()); // (int) 38 (0-59) 57 | // Serial.println(rtc.getMinute()); // (int) 24 (0-59) 58 | // Serial.println(rtc.getHour()); // (int) 3 (1-12) 59 | // Serial.println(rtc.getHour(true)); // (int) 15 (0-23) 60 | // Serial.println(rtc.getAmPm()); // (String) pm 61 | // Serial.println(rtc.getAmPm(true)); // (String) PM 62 | // Serial.println(rtc.getDay()); // (int) 17 (1-31) 63 | // Serial.println(rtc.getDayofWeek()); // (int) 0 (0-6) 64 | // Serial.println(rtc.getDayofYear()); // (int) 16 (0-365) 65 | // Serial.println(rtc.getMonth()); // (int) 0 (0-11) 66 | // Serial.println(rtc.getYear()); // (int) 2021 67 | 68 | // Serial.println(rtc.getLocalEpoch()); // (long) 1609459200 epoch without offset 69 | Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 70 | // formating options http://www.cplusplus.com/reference/ctime/strftime/ 71 | 72 | 73 | struct tm timeinfo = rtc.getTimeStruct(); 74 | //Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); // (tm struct) Sunday, January 17 2021 07:24:38 75 | 76 | delay(1000); 77 | } 78 | -------------------------------------------------------------------------------- /examples/esp32_time_multiple/esp32_time_multiple.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Felix Biego 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | ESP32Time rtc; 28 | ESP32Time rtc1(-3600); // offset GMT-1 29 | ESP32Time rtc2(7200); // offset GMT+2 30 | 31 | void setup() { 32 | Serial.begin(115200); 33 | rtc.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30 34 | //rtc1.setTime(1609459200); // 1st Jan 2021 00:00:00 35 | // time can be set on one instance 36 | // no need for rtc1.setTime() or rtc2.setTime() 37 | 38 | 39 | } 40 | 41 | void loop() { 42 | // Serial.println(rtc.getTime()); // (String) 15:24:38 43 | // Serial.println(rtc.getDate()); // (String) Sun, Jan 17 2021 44 | // Serial.println(rtc.getDate(true)); // (String) Sunday, January 17 2021 45 | // Serial.println(rtc.getDateTime()); // (String) Sun, Jan 17 2021 15:24:38 46 | // Serial.println(rtc.getDateTime(true)); // (String) Sunday, January 17 2021 15:24:38 47 | // Serial.println(rtc.getTimeDate()); // (String) 15:24:38 Sun, Jan 17 2021 48 | // Serial.println(rtc.getTimeDate(true)); // (String) 15:24:38 Sunday, January 17 2021 49 | // 50 | // Serial.println(rtc.getMicros()); // (unsigned long) 723546 51 | // Serial.println(rtc.getMillis()); // (unsigned long) 723 52 | // Serial.println(rtc.getEpoch()); // (unsigned long) 1609459200 53 | // Serial.println(rtc.getSecond()); // (int) 38 (0-59) 54 | // Serial.println(rtc.getMinute()); // (int) 24 (0-59) 55 | // Serial.println(rtc.getHour()); // (int) 3 (1-12) 56 | // Serial.println(rtc.getHour(true)); // (int) 15 (0-23) 57 | // Serial.println(rtc.getAmPm()); // (String) pm 58 | // Serial.println(rtc.getAmPm(true)); // (String) PM 59 | // Serial.println(rtc.getDay()); // (int) 17 (1-31) 60 | // Serial.println(rtc.getDayofWeek()); // (int) 0 (0-6) 61 | // Serial.println(rtc.getDayofYear()); // (int) 16 (0-365) 62 | // Serial.println(rtc.getMonth()); // (int) 0 (0-11) 63 | // Serial.println(rtc.getYear()); // (int) 2021 64 | 65 | Serial.println(rtc.getTime("RTC0: %A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 66 | Serial.println(rtc1.getTime("RTC1: %A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 67 | Serial.println(rtc2.getTime("RTC2: %A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 68 | 69 | // formating options http://www.cplusplus.com/reference/ctime/strftime/ 70 | 71 | Serial.println(rtc.getEpoch()); // (unsigned long) 72 | Serial.println(rtc1.getEpoch()); // (unsigned long) 73 | Serial.println(rtc2.getEpoch()); // (unsigned long) 74 | 75 | Serial.println(rtc.getLocalEpoch()); // (unsigned long) epoch without offset, same for all instances 76 | delay(1000); 77 | } 78 | -------------------------------------------------------------------------------- /ESP32Time.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Felix Biego 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #include "ESP32Time.h" 26 | #include "time.h" 27 | #include 28 | 29 | #ifdef RTC_DATA_ATTR 30 | RTC_DATA_ATTR static bool overflow; 31 | #else 32 | static bool overflow; 33 | #endif 34 | 35 | 36 | /*! 37 | @brief Constructor for ESP32Time 38 | */ 39 | ESP32Time::ESP32Time(){ 40 | } 41 | 42 | /*! 43 | @brief Constructor for ESP32Time 44 | @param offest 45 | gmt offset in seconds 46 | */ 47 | ESP32Time::ESP32Time(long offset){ 48 | this->offset = offset; 49 | } 50 | 51 | /*! 52 | @brief set the internal RTC time 53 | @param sc 54 | second (0-59) 55 | @param mn 56 | minute (0-59) 57 | @param hr 58 | hour of day (0-23) 59 | @param dy 60 | day of month (1-31) 61 | @param mt 62 | month (1-12) 63 | @param yr 64 | year ie 2021 65 | @param ms 66 | microseconds (optional) 67 | */ 68 | void ESP32Time::setTime(int sc, int mn, int hr, int dy, int mt, int yr, int ms) const { 69 | // seconds, minute, hour, day, month, year $ microseconds(optional) 70 | // ie setTime(20, 34, 8, 1, 4, 2021) = 8:34:20 1/4/2021 71 | struct tm t = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initalize to all 0's 72 | t.tm_year = yr - 1900; // This is year-1900, so 121 = 2021 73 | t.tm_mon = mt - 1; 74 | t.tm_mday = dy; 75 | t.tm_hour = hr; 76 | t.tm_min = mn; 77 | t.tm_sec = sc; 78 | time_t timeSinceEpoch = mktime(&t); 79 | setTime(timeSinceEpoch, ms); 80 | } 81 | 82 | /*! 83 | @brief set time from struct 84 | @param tm 85 | time struct 86 | */ 87 | void ESP32Time::setTimeStruct(tm t) const { 88 | time_t timeSinceEpoch = mktime(&t); 89 | setTime(timeSinceEpoch, 0); 90 | } 91 | 92 | /*! 93 | @brief set the internal RTC time 94 | @param epoch 95 | epoch time in seconds 96 | @param ms 97 | microseconds (optional) 98 | */ 99 | void ESP32Time::setTime(unsigned long epoch, int ms) const { 100 | struct timeval tv; 101 | if (epoch > 2082758399){ 102 | overflow = true; 103 | tv.tv_sec = epoch - 2082758399; // epoch time (seconds) 104 | } else { 105 | overflow = false; 106 | tv.tv_sec = epoch; // epoch time (seconds) 107 | } 108 | tv.tv_usec = ms; // microseconds 109 | settimeofday(&tv, NULL); 110 | } 111 | 112 | /*! 113 | @brief get the internal RTC time as a tm struct 114 | */ 115 | tm ESP32Time::getTimeStruct() const { 116 | struct tm timeinfo; 117 | time_t now; 118 | time(&now); 119 | localtime_r(&now, &timeinfo); 120 | time_t tt = mktime (&timeinfo); 121 | 122 | if (overflow){ 123 | tt += 63071999; 124 | } 125 | if (offset > 0){ 126 | tt += (unsigned long) offset; 127 | } else { 128 | tt -= (unsigned long) (offset * -1); 129 | } 130 | struct tm * tn = localtime(&tt); 131 | if (overflow){ 132 | tn->tm_year += 64; 133 | } 134 | return *tn; 135 | } 136 | 137 | /*! 138 | @brief get the time and date as an Arduino String object 139 | @param mode 140 | true = Long date format 141 | false = Short date format 142 | */ 143 | String ESP32Time::getDateTime(bool mode) const { 144 | struct tm timeinfo = getTimeStruct(); 145 | char s[51]; 146 | if (mode) 147 | { 148 | strftime(s, 50, "%A, %B %d %Y %H:%M:%S", &timeinfo); 149 | } 150 | else 151 | { 152 | strftime(s, 50, "%a, %b %d %Y %H:%M:%S", &timeinfo); 153 | } 154 | return String(s); 155 | } 156 | 157 | /*! 158 | @brief get the time and date as an Arduino String object 159 | @param mode 160 | true = Long date format 161 | false = Short date format 162 | */ 163 | String ESP32Time::getTimeDate(bool mode) const { 164 | struct tm timeinfo = getTimeStruct(); 165 | char s[51]; 166 | if (mode) 167 | { 168 | strftime(s, 50, "%H:%M:%S %A, %B %d %Y", &timeinfo); 169 | } 170 | else 171 | { 172 | strftime(s, 50, "%H:%M:%S %a, %b %d %Y", &timeinfo); 173 | } 174 | return String(s); 175 | } 176 | 177 | /*! 178 | @brief get the time as an Arduino String object 179 | */ 180 | String ESP32Time::getTime() const { 181 | struct tm timeinfo = getTimeStruct(); 182 | char s[51]; 183 | strftime(s, 50, "%H:%M:%S", &timeinfo); 184 | return String(s); 185 | } 186 | 187 | /*! 188 | @brief get the time as an Arduino String object with the specified format 189 | @param format 190 | time format 191 | http://www.cplusplus.com/reference/ctime/strftime/ 192 | */ 193 | String ESP32Time::getTime(String format) const { 194 | struct tm timeinfo = getTimeStruct(); 195 | char s[128]; 196 | char c[128]; 197 | format.toCharArray(c, 127); 198 | strftime(s, 127, c, &timeinfo); 199 | return String(s); 200 | } 201 | 202 | /*! 203 | @brief get the date as an Arduino String object 204 | @param mode 205 | true = Long date format 206 | false = Short date format 207 | */ 208 | String ESP32Time::getDate(bool mode) const { 209 | struct tm timeinfo = getTimeStruct(); 210 | char s[51]; 211 | if (mode) 212 | { 213 | strftime(s, 50, "%A, %B %d %Y", &timeinfo); 214 | } 215 | else 216 | { 217 | strftime(s, 50, "%a, %b %d %Y", &timeinfo); 218 | } 219 | return String(s); 220 | } 221 | 222 | /*! 223 | @brief get the current milliseconds as unsigned long 224 | */ 225 | unsigned long ESP32Time::getMillis() const { 226 | struct timeval tv; 227 | gettimeofday(&tv, NULL); 228 | return tv.tv_usec/1000; 229 | } 230 | 231 | /*! 232 | @brief get the current microseconds as unsigned long 233 | */ 234 | unsigned long ESP32Time::getMicros() const { 235 | struct timeval tv; 236 | gettimeofday(&tv, NULL); 237 | return tv.tv_usec; 238 | } 239 | 240 | /*! 241 | @brief get the current epoch seconds as unsigned long 242 | */ 243 | unsigned long ESP32Time::getEpoch() const { 244 | struct tm timeinfo = getTimeStruct(); 245 | return mktime(&timeinfo); 246 | } 247 | 248 | /*! 249 | @brief get the current epoch seconds as unsigned long from the rtc without offset 250 | */ 251 | unsigned long ESP32Time::getLocalEpoch() const { 252 | struct timeval tv; 253 | gettimeofday(&tv, NULL); 254 | unsigned long epoch = tv.tv_sec; 255 | if (overflow){ 256 | epoch += 63071999 + 2019686400; 257 | } 258 | return epoch; 259 | } 260 | 261 | /*! 262 | @brief get the current seconds as int 263 | */ 264 | int ESP32Time::getSecond() const { 265 | struct tm timeinfo = getTimeStruct(); 266 | return timeinfo.tm_sec; 267 | } 268 | 269 | /*! 270 | @brief get the current minutes as int 271 | */ 272 | int ESP32Time::getMinute() const { 273 | struct tm timeinfo = getTimeStruct(); 274 | return timeinfo.tm_min; 275 | } 276 | 277 | /*! 278 | @brief get the current hour as int 279 | @param mode 280 | true = 24 hour mode (0-23) 281 | false = 12 hour mode (1-12) 282 | */ 283 | int ESP32Time::getHour(bool mode) const { 284 | struct tm timeinfo = getTimeStruct(); 285 | if (mode) 286 | { 287 | return timeinfo.tm_hour; 288 | } 289 | else 290 | { 291 | int hour = timeinfo.tm_hour; 292 | if (hour > 12) 293 | { 294 | return timeinfo.tm_hour-12; 295 | } 296 | else if (hour == 0) 297 | { 298 | return 12; // 12 am 299 | } 300 | else 301 | { 302 | return timeinfo.tm_hour; 303 | } 304 | 305 | } 306 | } 307 | 308 | /*! 309 | @brief return current hour am or pm 310 | @param lowercase 311 | true = lowercase 312 | false = uppercase 313 | */ 314 | String ESP32Time::getAmPm(bool lowercase) const { 315 | struct tm timeinfo = getTimeStruct(); 316 | if (timeinfo.tm_hour >= 12) 317 | { 318 | if (lowercase) 319 | { 320 | return "pm"; 321 | } 322 | else 323 | { 324 | return "PM"; 325 | } 326 | } 327 | else 328 | { 329 | if (lowercase) 330 | { 331 | return "am"; 332 | } 333 | else 334 | { 335 | return "AM"; 336 | } 337 | } 338 | } 339 | 340 | /*! 341 | @brief get the current day as int (1-31) 342 | */ 343 | int ESP32Time::getDay() const { 344 | struct tm timeinfo = getTimeStruct(); 345 | return timeinfo.tm_mday; 346 | } 347 | 348 | /*! 349 | @brief get the current day of week as int (0-6) 350 | */ 351 | int ESP32Time::getDayofWeek() const { 352 | struct tm timeinfo = getTimeStruct(); 353 | return timeinfo.tm_wday; 354 | } 355 | 356 | /*! 357 | @brief get the current day of year as int (0-365) 358 | */ 359 | int ESP32Time::getDayofYear() const { 360 | struct tm timeinfo = getTimeStruct(); 361 | return timeinfo.tm_yday; 362 | } 363 | 364 | /*! 365 | @brief get the current month as int (0-11) 366 | */ 367 | int ESP32Time::getMonth() const { 368 | struct tm timeinfo = getTimeStruct(); 369 | return timeinfo.tm_mon; 370 | } 371 | 372 | /*! 373 | @brief get the current year as int 374 | */ 375 | int ESP32Time::getYear() const { 376 | struct tm timeinfo = getTimeStruct(); 377 | return timeinfo.tm_year+1900; 378 | } 379 | -------------------------------------------------------------------------------- /examples/esp32_webserver_time_sleep/esp32_webserver_time_sleep.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Power ON the ESP32, select ESP32-RTC-Logger network on your phone and enter the password. 4 | 5 | Visit 192.168.4.1 using your browser and press syncTime. 6 | 7 | This will run 'rtc.setTime(epochTime)' and send the ESP32 to sleep for the duration of 'TIME_TO_SLEEP'. 8 | 9 | */ 10 | 11 | /* 12 | MIT License 13 | 14 | Copyright (c) 2024 Francisco Bexiga 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy 17 | of this software and associated documentation files (the "Software"), to deal 18 | in the Software without restriction, including without limitation the rights 19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the Software is 21 | furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all 24 | copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 | SOFTWARE. 33 | */ 34 | 35 | #include 36 | #include 37 | 38 | #define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */ 39 | #define TIME_TO_SLEEP 30 /* Time ESP32 will go to sleep (in seconds) */ 40 | 41 | ESP32Time rtc; 42 | 43 | // Set your access point name and password 44 | const char *ssid = "ESP32-RTC-Logger"; 45 | const char *password = "12345678"; 46 | 47 | // Create an instance of the server 48 | WiFiServer server(80); 49 | 50 | // Variable to store the state 51 | RTC_DATA_ATTR bool timeWasSet = false; 52 | 53 | // LED pin 54 | const int ledPin = 2; 55 | 56 | void wakeup_reason() { 57 | esp_sleep_wakeup_cause_t wakeup_reason; 58 | 59 | wakeup_reason = esp_sleep_get_wakeup_cause(); 60 | switch (wakeup_reason) { 61 | case ESP_SLEEP_WAKEUP_EXT0 : 62 | Serial.println("Wakeup caused by external signal using RTC_IO"); 63 | break; 64 | case ESP_SLEEP_WAKEUP_EXT1 : 65 | Serial.println("Wakeup caused by external signal using RTC_CNTL"); 66 | break; 67 | case ESP_SLEEP_WAKEUP_TIMER : 68 | Serial.println("Wakeup caused by timer"); 69 | break; 70 | case ESP_SLEEP_WAKEUP_TOUCHPAD : 71 | Serial.println("Wakeup caused by touchpad"); 72 | break; 73 | case ESP_SLEEP_WAKEUP_ULP : 74 | Serial.println("Wakeup caused by ULP program"); 75 | break; 76 | default : 77 | Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); 78 | break; 79 | } 80 | } 81 | 82 | void blinkLED(int numBlinks, int blinkInterval) { 83 | for (int i = 0; i < numBlinks; i++) { 84 | digitalWrite(ledPin, HIGH); // Turn on the LED 85 | delay(blinkInterval); 86 | digitalWrite(ledPin, LOW); // Turn off the LED 87 | delay(blinkInterval); 88 | } 89 | } 90 | 91 | void setup() { 92 | // Start the Serial communication to see some output 93 | Serial.begin(115200); 94 | delay(1000); 95 | 96 | // Initialize LED pin as an output 97 | pinMode(ledPin, OUTPUT); 98 | 99 | // Display wake up reason 100 | wakeup_reason(); 101 | 102 | Serial.print("timeWasSet: "); 103 | Serial.println(timeWasSet); 104 | 105 | // Check if time has been set 106 | if (timeWasSet) { 107 | // Blink the LED in a loop 108 | while (true) { 109 | blinkLED(3, 100); // Blink the LED 3 times with a 100ms interval 110 | 111 | Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format 112 | 113 | // Do the logging 114 | /* YOUR CODE HERE */ 115 | 116 | // Go to sleep again 117 | esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); 118 | 119 | Serial.println("Going to sleep now"); 120 | Serial.flush(); 121 | esp_deep_sleep_start(); 122 | } 123 | } 124 | 125 | // Set up the access point 126 | Serial.print("Setting up access point..."); 127 | WiFi.softAP(ssid, password); 128 | 129 | // Print the IP address 130 | IPAddress IP = WiFi.softAPIP(); 131 | Serial.print("AP IP address: "); 132 | Serial.println(IP); 133 | 134 | // Start the server 135 | server.begin(); 136 | } 137 | 138 | void loop() { 139 | // Check if a client has connected 140 | WiFiClient client = server.available(); 141 | 142 | if (client) { 143 | Serial.println("New client connected"); 144 | String currentLine = ""; // make a String to hold incoming data from the client 145 | 146 | while (client.connected()) { // loop while the client's connected 147 | if (client.available()) { // if there's bytes to read from the client, 148 | char c = client.read(); // read a byte, then 149 | Serial.write(c); // print it out the serial monitor 150 | if (c == '\n') { // if the byte is a newline character 151 | // if the current line is blank, you got two newline characters in a row. 152 | // that's the end of the client HTTP request, so send a response: 153 | if (currentLine.length() == 0) { 154 | // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) 155 | // and a content-type so the client knows what's coming, then a blank line: 156 | client.println("HTTP/1.1 200 OK"); 157 | client.println("Content-type:text/html"); 158 | client.println(); 159 | 160 | // the content of the HTTP response follows the header: 161 | client.println(""); 162 | client.println("ESP32 Web Server"); 163 | 164 | client.println(""); 165 | 166 | client.println("
"); 167 | 168 | client.println("

"); 169 | client.println("

"); 170 | client.println(""); 183 | 184 | client.println("
"); 185 | client.println(" "); 186 | client.println(" "); 187 | client.println("
"); 188 | 189 | client.println("
"); 190 | 191 | client.println(""); 192 | client.println(""); 193 | 194 | // The HTTP response ends with another blank line: 195 | client.println(); 196 | break; 197 | } else { // if you got a newline, then clear currentLine: 198 | currentLine = ""; 199 | } 200 | } else if (c != '\r') { // if you got anything else but a carriage return character, 201 | currentLine += c; // add it to the end of the currentLine 202 | } 203 | 204 | // Check if the line ends with "POST /syncTime" 205 | if (currentLine.endsWith("POST /syncTime")) { 206 | Serial.println(); 207 | Serial.println("syncTime requested"); 208 | 209 | // Read the POST request body 210 | String requestBody = ""; 211 | while (client.available()) { 212 | char c = client.read(); 213 | requestBody += c; 214 | } 215 | 216 | // Extract the epochTime value from the request body 217 | int epochTimeIndex = requestBody.indexOf("epochTime="); 218 | if (epochTimeIndex != -1) { 219 | String epochTimeStr = requestBody.substring(epochTimeIndex + 10); // Extract the value 220 | long epochTime = epochTimeStr.toInt(); // Convert to integer 221 | Serial.print("Epoch Time from request: "); 222 | Serial.println(epochTime); 223 | 224 | // Set the RTC time (if desired, depending on how you want to use this value) 225 | rtc.setTime(epochTime); 226 | 227 | timeWasSet = true; // Update timeWasSet flag 228 | } 229 | 230 | delay(1000); // Give some time to the client to receive the response 231 | 232 | // Set up deep sleep 233 | esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); 234 | 235 | Serial.println("Going to sleep now"); 236 | Serial.flush(); 237 | esp_deep_sleep_start(); 238 | } 239 | } 240 | } 241 | // close the connection: 242 | client.stop(); 243 | Serial.println("Client disconnected"); 244 | Serial.println(""); 245 | } 246 | } 247 | --------------------------------------------------------------------------------