├── .gitattributes ├── README.md ├── .gitignore ├── SNTPtime.h ├── examples └── SNTPtimeESP │ └── SNTPtimeESP.ino └── SNTP.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SNTPtime 2 | Library for ESP8266 to get time from NTP servers using SNTP protocol 3 | 4 | This library is based on the native SNTP implementation of espressif. It has two main functions: 5 | 6 | setSNTPtime: This function reads the actual time from a NTP server and sets the internal ESP RTC to UTC 7 | getTime: This function reads the ESP internal clock, adjust it to the time zone and eventually 8 | to summer time and fills the structure dateTime. This function does not need network connection, but is reset during deep sleep. 9 | Pay attention: the internal RTC is not very precise and has to be synchrinized from time to time with a NTP server. 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /SNTPtime.h: -------------------------------------------------------------------------------- 1 | /* 2 | SNTP library for ESP8266 3 | 4 | 5 | This routine gets the unixtime from a NTP server and adjusts it to the time zone and the 6 | Middle European summer time if requested 7 | 8 | Copyright (c) 2016 Andreas Spiess 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | V1.0 2016-8-3 29 | 30 | */ 31 | 32 | #ifndef NTPtime_h 33 | #define NTPtime_h 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | 41 | #define DEBUG_ON 42 | 43 | 44 | 45 | struct strDateTime 46 | { 47 | byte hour; 48 | byte minute; 49 | byte second; 50 | int year; 51 | byte month; 52 | byte day; 53 | byte dayofWeek; 54 | boolean valid; 55 | }; 56 | 57 | class SNTPtime { 58 | public: 59 | SNTPtime(char *NTPServer); 60 | strDateTime getTime(double _timeZone, boolean _DayLightSaving); 61 | void printDateTime(strDateTime _dateTime); 62 | boolean setSNTPtime(); 63 | 64 | private: 65 | strDateTime ConvertUnixTimestamp( unsigned long _tempTimeStamp); 66 | boolean summerTime(unsigned long _timeStamp ); 67 | boolean daylightSavingTime(unsigned long _timeStamp); 68 | unsigned long adjustTimeZone(unsigned long _timeStamp, double _timeZone, byte _DayLightSavingSaving); 69 | }; 70 | #endif 71 | -------------------------------------------------------------------------------- /examples/SNTPtimeESP/SNTPtimeESP.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SNTPtime for ESP8266 4 | This routine gets the unixtime from a NTP server and adjusts it to the time zone and the 5 | Middle European summer time if requested 6 | 7 | Copyright (c) 2016 Andreas Spiess 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | V1.0 2016-6-28 28 | */ 29 | #include 30 | 31 | 32 | SNTPtime NTPch("ch.pool.ntp.org"); 33 | 34 | /* 35 | The structure contains following fields: 36 | struct strDateTime 37 | { 38 | byte hour; 39 | byte minute; 40 | byte second; 41 | int year; 42 | byte month; 43 | byte day; 44 | byte dayofWeek; 45 | boolean valid; 46 | }; 47 | */ 48 | strDateTime dateTime; 49 | 50 | void setup() { 51 | Serial.begin(115200); 52 | Serial.println(); 53 | Serial.println("Booted"); 54 | Serial.println("Connecting to Wi-Fi"); 55 | 56 | WiFi.mode(WIFI_STA); 57 | WiFi.begin (ssid, password); 58 | while (WiFi.status() != WL_CONNECTED) { 59 | Serial.print("."); 60 | delay(500); 61 | } 62 | Serial.println(); 63 | Serial.println("WiFi connected"); 64 | 65 | while (!NTPch.setSNTPtime()) Serial.print("."); // set internal clock 66 | Serial.println(); 67 | Serial.println("Time set"); 68 | } 69 | 70 | void loop() { 71 | 72 | // first parameter: Time zone; second parameter: 1 for European summer time; 2 for US daylight saving time (not implemented yet) 73 | dateTime = NTPch.getTime(1.0, 1); // get time from internal clock 74 | NTPch.printDateTime(dateTime); 75 | 76 | byte actualHour = dateTime.hour; 77 | byte actualMinute = dateTime.minute; 78 | byte actualsecond = dateTime.second; 79 | int actualyear = dateTime.year; 80 | byte actualMonth = dateTime.month; 81 | byte actualday = dateTime.day; 82 | byte actualdayofWeek = dateTime.dayofWeek; 83 | delay(1000); 84 | } 85 | -------------------------------------------------------------------------------- /SNTP.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SNTP library for ESP8266 3 | 4 | 5 | This routine gets the unixtime from a NTP server and adjusts it to the time zone and the 6 | Middle European summer time if requested 7 | 8 | Copyright (c) 2016 Andreas Spiess 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | V1.0 2016-8-3 29 | 30 | */ 31 | 32 | #include 33 | #include "SNTPtime.h" 34 | 35 | #define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) 36 | 37 | const int NTP_PACKET_SIZE = 48; 38 | byte _packetBuffer[ NTP_PACKET_SIZE]; 39 | static const uint8_t _monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 40 | 41 | char *_NTPserver=""; 42 | 43 | // NTPserver is the name of the NTPserver 44 | 45 | SNTPtime::SNTPtime(char *NTPserver) { 46 | _NTPserver = NTPserver; 47 | } 48 | 49 | // Converts a unix time stamp to a strDateTime structure 50 | strDateTime SNTPtime::ConvertUnixTimestamp( unsigned long _tempTimeStamp) { 51 | strDateTime _tempDateTime; 52 | uint8_t _year, _month, _monthLength; 53 | uint32_t _time; 54 | unsigned long _days; 55 | 56 | _time = (uint32_t)_tempTimeStamp; 57 | _tempDateTime.second = _time % 60; 58 | _time /= 60; // now it is minutes 59 | _tempDateTime.minute = _time % 60; 60 | _time /= 60; // now it is hours 61 | _tempDateTime.hour = _time % 24; 62 | _time /= 24; // now it is _days 63 | _tempDateTime.dayofWeek = ((_time + 4) % 7) + 1; // Sunday is day 1 64 | 65 | _year = 0; 66 | _days = 0; 67 | while ((unsigned)(_days += (LEAP_YEAR(_year) ? 366 : 365)) <= _time) { 68 | _year++; 69 | } 70 | _tempDateTime.year = _year; // year is offset from 1970 71 | 72 | _days -= LEAP_YEAR(_year) ? 366 : 365; 73 | _time -= _days; // now it is days in this year, starting at 0 74 | 75 | _days = 0; 76 | _month = 0; 77 | _monthLength = 0; 78 | for (_month = 0; _month < 12; _month++) { 79 | if (_month == 1) { // february 80 | if (LEAP_YEAR(_year)) { 81 | _monthLength = 29; 82 | } else { 83 | _monthLength = 28; 84 | } 85 | } else { 86 | _monthLength = _monthDays[_month]; 87 | } 88 | 89 | if (_time >= _monthLength) { 90 | _time -= _monthLength; 91 | } else { 92 | break; 93 | } 94 | } 95 | _tempDateTime.month = _month + 1; // jan is month 1 96 | _tempDateTime.day = _time + 1; // day of month 97 | _tempDateTime.year += 1970; 98 | 99 | return _tempDateTime; 100 | } 101 | 102 | 103 | // 104 | // Summertime calculates the daylight saving time for middle Europe. Input: Unixtime in UTC 105 | // 106 | boolean SNTPtime::summerTime(unsigned long _timeStamp ) { 107 | 108 | strDateTime _tempDateTime; 109 | _tempDateTime = ConvertUnixTimestamp(_timeStamp); 110 | // printTime("Innerhalb ", _tempDateTime); 111 | 112 | if (_tempDateTime.month < 3 || _tempDateTime.month > 10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez 113 | if (_tempDateTime.month > 3 && _tempDateTime.month < 10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep 114 | if (_tempDateTime.month == 3 && (_tempDateTime.hour + 24 * _tempDateTime.day) >= (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 4) % 7)) || _tempDateTime.month == 10 && (_tempDateTime.hour + 24 * _tempDateTime.day) < (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 1) % 7))) 115 | return true; 116 | else 117 | return false; 118 | } 119 | 120 | boolean SNTPtime::daylightSavingTime(unsigned long _timeStamp) { 121 | 122 | strDateTime _tempDateTime; 123 | _tempDateTime = ConvertUnixTimestamp(_timeStamp); 124 | 125 | // here the US code 126 | return false; 127 | } 128 | 129 | 130 | unsigned long SNTPtime::adjustTimeZone(unsigned long _timeStamp, double _timeZone, byte _DayLightSaving) { 131 | strDateTime _tempDateTime; 132 | _timeStamp += _timeZone * 3600; // adjust timezone 133 | if (_DayLightSaving ==1 && summerTime(_timeStamp)) _timeStamp += 3600; // European Summer time 134 | if (_DayLightSaving ==2 && daylightSavingTime(_timeStamp)) _timeStamp += 3600; // US daylight time 135 | return _timeStamp; 136 | } 137 | 138 | 139 | 140 | 141 | boolean SNTPtime::setSNTPtime() { 142 | 143 | unsigned long entry=millis(); 144 | do { 145 | configTime(0,0,_NTPserver); 146 | delay(500); 147 | } while (millis()-entry<5000 && time(NULL)<946684800); // 1.1.2000 148 | if (time(NULL)>100) return true; 149 | else return false; 150 | } 151 | 152 | // time zone is the difference to UTC in hours 153 | // if _isDayLightSaving is 0, time in timezone is returned 154 | // if _isDayLightSaving is 1, time will be adjusted to European Summer time 155 | 156 | 157 | strDateTime SNTPtime::getTime(double _timeZone, boolean _DayLightSaving) 158 | { 159 | unsigned long _unixTime = time(NULL); 160 | Serial.println(_unixTime); 161 | unsigned long _currentTimeStamp = adjustTimeZone(_unixTime, _timeZone, _DayLightSaving); 162 | strDateTime _dateTime = ConvertUnixTimestamp(_currentTimeStamp); 163 | 164 | return _dateTime; 165 | } 166 | 167 | void SNTPtime::printDateTime(strDateTime _dateTime) { 168 | 169 | Serial.print(_dateTime.year); 170 | Serial.print( "-"); 171 | Serial.print(_dateTime.month); 172 | Serial.print( "-"); 173 | Serial.print(_dateTime.day); 174 | Serial.print( "-"); 175 | Serial.print(_dateTime.dayofWeek); 176 | Serial.print( " "); 177 | 178 | Serial.print(_dateTime.hour); 179 | Serial.print( "H "); 180 | Serial.print(_dateTime.minute); 181 | Serial.print( "M "); 182 | Serial.print(_dateTime.second); 183 | Serial.print( "S "); 184 | Serial.println(); 185 | } 186 | --------------------------------------------------------------------------------