├── DateStrings.cpp ├── Readme.md ├── Time.cpp ├── TimeLib.h ├── docs └── issue_template.md ├── examples ├── Processing │ └── SyncArduinoClock │ │ ├── SyncArduinoClock.pde │ │ └── readme.txt ├── TimeArduinoDue │ └── TimeArduinoDue.ino ├── TimeGPS │ └── TimeGPS.ino ├── TimeNTP │ └── TimeNTP.ino ├── TimeNTP_ENC28J60 │ └── TimeNTP_ENC28J60.ino ├── TimeNTP_ESP8266WiFi │ └── TimeNTP_ESP8266WiFi.ino ├── TimeRTC │ └── TimeRTC.ino ├── TimeRTCLog │ └── TimeRTCLog.ino ├── TimeRTCSet │ └── TimeRTCSet.ino ├── TimeSerial │ └── TimeSerial.ino ├── TimeSerialDateStrings │ └── TimeSerialDateStrings.ino └── TimeTeensy3 │ └── TimeTeensy3.ino ├── keywords.txt ├── library.json └── library.properties /DateStrings.cpp: -------------------------------------------------------------------------------- 1 | /* DateStrings.cpp 2 | * Definitions for date strings for use with the Time library 3 | * 4 | * Updated for Arduino 1.5.7 18 July 2014 5 | * 6 | * No memory is consumed in the sketch if your code does not call any of the string methods 7 | * You can change the text of the strings, make sure the short strings are each exactly 3 characters 8 | * the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in TimeLib.h 9 | * 10 | */ 11 | 12 | #include 13 | 14 | // Arduino.h should properly define PROGMEM, PGM_P, strcpy_P, pgm_read_byte, pgm_read_ptr 15 | // But not all platforms define these as they should. If you find a platform needing these 16 | // defined, or if any this becomes unnecessary as platforms improve, please send a pull req. 17 | #if defined(ESP8266) 18 | #undef PROGMEM 19 | #define PROGMEM 20 | #endif 21 | 22 | #include "TimeLib.h" 23 | 24 | 25 | // the short strings for each day or month must be exactly dt_SHORT_STR_LEN 26 | #define dt_SHORT_STR_LEN 3 // the length of short strings 27 | 28 | static char buffer[dt_MAX_STRING_LEN+1]; // must be big enough for longest string and the terminating null 29 | 30 | const char monthStr0[] PROGMEM = ""; 31 | const char monthStr1[] PROGMEM = "January"; 32 | const char monthStr2[] PROGMEM = "February"; 33 | const char monthStr3[] PROGMEM = "March"; 34 | const char monthStr4[] PROGMEM = "April"; 35 | const char monthStr5[] PROGMEM = "May"; 36 | const char monthStr6[] PROGMEM = "June"; 37 | const char monthStr7[] PROGMEM = "July"; 38 | const char monthStr8[] PROGMEM = "August"; 39 | const char monthStr9[] PROGMEM = "September"; 40 | const char monthStr10[] PROGMEM = "October"; 41 | const char monthStr11[] PROGMEM = "November"; 42 | const char monthStr12[] PROGMEM = "December"; 43 | 44 | const PROGMEM char * const PROGMEM monthNames_P[] = 45 | { 46 | monthStr0,monthStr1,monthStr2,monthStr3,monthStr4,monthStr5,monthStr6, 47 | monthStr7,monthStr8,monthStr9,monthStr10,monthStr11,monthStr12 48 | }; 49 | 50 | const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec"; 51 | 52 | const char dayStr0[] PROGMEM = "Err"; 53 | const char dayStr1[] PROGMEM = "Sunday"; 54 | const char dayStr2[] PROGMEM = "Monday"; 55 | const char dayStr3[] PROGMEM = "Tuesday"; 56 | const char dayStr4[] PROGMEM = "Wednesday"; 57 | const char dayStr5[] PROGMEM = "Thursday"; 58 | const char dayStr6[] PROGMEM = "Friday"; 59 | const char dayStr7[] PROGMEM = "Saturday"; 60 | 61 | const PROGMEM char * const PROGMEM dayNames_P[] = 62 | { 63 | dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7 64 | }; 65 | 66 | const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThuFriSat"; 67 | 68 | /* functions to return date strings */ 69 | 70 | char* monthStr(uint8_t month) 71 | { 72 | strcpy_P(buffer, (PGM_P)pgm_read_ptr(&(monthNames_P[month]))); 73 | return buffer; 74 | } 75 | 76 | char* monthShortStr(uint8_t month) 77 | { 78 | for (int i=0; i < dt_SHORT_STR_LEN; i++) 79 | buffer[i] = pgm_read_byte(&(monthShortNames_P[i+ (month*dt_SHORT_STR_LEN)])); 80 | buffer[dt_SHORT_STR_LEN] = 0; 81 | return buffer; 82 | } 83 | 84 | char* dayStr(uint8_t day) 85 | { 86 | strcpy_P(buffer, (PGM_P)pgm_read_ptr(&(dayNames_P[day]))); 87 | return buffer; 88 | } 89 | 90 | char* dayShortStr(uint8_t day) 91 | { 92 | uint8_t index = day*dt_SHORT_STR_LEN; 93 | for (int i=0; i < dt_SHORT_STR_LEN; i++) 94 | buffer[i] = pgm_read_byte(&(dayShortNames_P[index + i])); 95 | buffer[dt_SHORT_STR_LEN] = 0; 96 | return buffer; 97 | } 98 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Arduino Time Library 2 | 3 | Time is a library that provides timekeeping functionality for Arduino. 4 | 5 | Using the Arduino Library Manager, install "*Time* by *Michael Margolis*". 6 | 7 | The code is derived from the Playground DateTime library but is updated 8 | to provide an API that is more flexible and easier to use. 9 | 10 | A primary goal was to enable date and time functionality that can be used with 11 | a variety of external time sources with minimum differences required in sketch logic. 12 | 13 | Example sketches illustrate how similar sketch code can be used with: a Real Time Clock, 14 | internet NTP time service, GPS time data, and Serial time messages from a computer 15 | for time synchronization. 16 | 17 | ## Functionality 18 | 19 | To use the Time library in an Arduino sketch, include TimeLib.h. 20 | 21 | ```c 22 | #include 23 | ``` 24 | 25 | The functions available in the library include 26 | 27 | ```c 28 | hour(); // the hour now (0-23) 29 | minute(); // the minute now (0-59) 30 | second(); // the second now (0-59) 31 | day(); // the day now (1-31) 32 | weekday(); // day of the week (1-7), Sunday is day 1 33 | month(); // the month now (1-12) 34 | year(); // the full four digit year: (2009, 2010 etc) 35 | ``` 36 | 37 | there are also functions to return the hour in 12-hour format 38 | 39 | ```c 40 | hourFormat12(); // the hour now in 12 hour format 41 | isAM(); // returns true if time now is AM 42 | isPM(); // returns true if time now is PM 43 | 44 | now(); // returns the current time as seconds since Jan 1 1970 45 | ``` 46 | 47 | The time and date functions can take an optional parameter for the time. This prevents 48 | errors if the time rolls over between elements. For example, if a new minute begins 49 | between getting the minute and second, the values will be inconsistent. Using the 50 | following functions eliminates this problem 51 | 52 | ```c 53 | time_t t = now(); // store the current time in time variable t 54 | hour(t); // returns the hour for the given time t 55 | minute(t); // returns the minute for the given time t 56 | second(t); // returns the second for the given time t 57 | day(t); // the day for the given time t 58 | weekday(t); // day of the week for the given time t 59 | month(t); // the month for the given time t 60 | year(t); // the year for the given time t 61 | ``` 62 | 63 | Functions for managing the timer services are: 64 | 65 | ```c 66 | setTime(t); // set the system time to the give time t 67 | setTime(hr,min,sec,day,mnth,yr); // alternative to above, yr is 2 or 4 digit yr 68 | // (2010 or 10 sets year to 2010) 69 | adjustTime(adjustment); // adjust system time by adding the adjustment value 70 | timeStatus(); // indicates if time has been set and recently synchronized 71 | // returns one of the following enumerations: 72 | timeNotSet // the time has never been set, the clock started on Jan 1, 1970 73 | timeNeedsSync // the time had been set but a sync attempt did not succeed 74 | timeSet // the time is set and is synced 75 | ``` 76 | 77 | Time and Date values are not valid if the status is `timeNotSet`. Otherwise, values can be used but 78 | the returned time may have drifted if the status is `timeNeedsSync`. 79 | 80 | ```c 81 | setSyncProvider(getTimeFunction); // set the external time provider 82 | setSyncInterval(interval); // set the number of seconds between re-sync 83 | ``` 84 | 85 | There are many convenience macros in the `time.h` file for time constants and conversion 86 | of time units. 87 | 88 | To use the library, copy the download to the Library directory. 89 | 90 | ## Examples 91 | 92 | The Time directory contains the Time library and some example sketches 93 | illustrating how the library can be used with various time sources: 94 | 95 | - `TimeSerial.pde` shows Arduino as a clock without external hardware. 96 | It is synchronized by time messages sent over the serial port. 97 | A companion Processing sketch will automatically provide these messages 98 | if it is running and connected to the Arduino serial port. 99 | 100 | - `TimeSerialDateStrings.pde` adds day and month name strings to the sketch above. 101 | Short (3 characters) and long strings are available to print the days of 102 | the week and names of the months. 103 | 104 | - `TimeRTC` uses a DS1307 real-time clock to provide time synchronization. 105 | The basic [DS1307RTC library][1] must be downloaded and installed, 106 | in order to run this sketch. 107 | 108 | - `TimeRTCSet` is similar to the above and adds the ability to set the Real Time Clock. 109 | 110 | - `TimeRTCLog` demonstrates how to calculate the difference between times. 111 | It is a very simple logger application that monitors events on digital pins 112 | and prints (to the serial port) the time of an event and the time period since 113 | the previous event. 114 | 115 | - `TimeNTP` uses the Arduino Ethernet shield to access time using the internet NTP time service. 116 | The NTP protocol uses UDP and the UdpBytewise library is required, see: 117 | 118 | 119 | - `TimeGPS` gets time from a GPS. 120 | This requires the TinyGPS library from Mikal Hart: 121 | 122 | 123 | ## Differences 124 | 125 | Differences between this code and the playground DateTime library 126 | although the Time library is based on the DateTime codebase, the API has changed. 127 | Changes in the Time library API: 128 | 129 | - time elements are functions returning `int` (they are variables in DateTime) 130 | - Years start from 1970 131 | - days of the week and months start from 1 (they start from 0 in DateTime) 132 | - DateStrings do not require a separate library 133 | - time elements can be accessed non-atomically (in DateTime they are always atomic) 134 | - function added to automatically sync time with external source 135 | - `localTime` and `maketime` parameters changed, `localTime` renamed to `breakTime` 136 | 137 | ## Technical Notes 138 | 139 | Internal system time is based on the standard Unix `time_t`. 140 | The value is the number of seconds since Jan 1, 1970. 141 | System time begins at zero when the sketch starts. 142 | 143 | The internal time can be automatically synchronized at regular intervals to an external time source. 144 | This is enabled by calling the `setSyncProvider(provider)` function - the provider argument is 145 | the address of a function that returns the current time as a `time_t`. 146 | See the sketches in the examples directory for usage. 147 | 148 | The default interval for re-syncing the time is 5 minutes but can be changed by calling the 149 | `setSyncInterval(interval)` method to set the number of seconds between re-sync attempts. 150 | 151 | The Time library defines a structure for holding time elements that is a compact version of the C `tm` structure. 152 | All the members of the Arduino `tm` structure are bytes and the year is offset from 1970. 153 | Convenience macros provide conversion to and from the Arduino format. 154 | 155 | Low-level functions to convert between system time and individual time elements are provided: 156 | 157 | ```c 158 | breakTime(time, &tm); // break time_t into elements stored in tm struct 159 | makeTime(&tm); // return time_t from elements stored in tm struct 160 | ``` 161 | 162 | This [DS1307RTC library][1] provides an example of how a time provider 163 | can use the low-level functions to interface with the Time library. 164 | 165 | [1]: 166 | -------------------------------------------------------------------------------- /Time.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | time.c - low level time and date functions 3 | Copyright (c) Michael Margolis 2009-2014 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | 1.0 6 Jan 2010 - initial release 20 | 1.1 12 Feb 2010 - fixed leap year calculation error 21 | 1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this) 22 | 1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update 23 | status, updated examples for Arduino 1.0, fixed ARM 24 | compatibility issues, added TimeArduinoDue and TimeTeensy3 25 | examples, add error checking and messages to RTC examples, 26 | add examples to DS1307RTC library. 27 | 1.4 5 Sep 2014 - compatibility with Arduino 1.5.7 28 | */ 29 | 30 | #if ARDUINO >= 100 31 | #include 32 | #else 33 | #include 34 | #endif 35 | 36 | #include "TimeLib.h" 37 | 38 | static tmElements_t tm; // a cache of time elements 39 | static time_t cacheTime; // the time the cache was updated 40 | static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds 41 | 42 | void refreshCache(time_t t) { 43 | if (t != cacheTime) { 44 | breakTime(t, tm); 45 | cacheTime = t; 46 | } 47 | } 48 | 49 | int hour() { // the hour now 50 | return hour(now()); 51 | } 52 | 53 | int hour(time_t t) { // the hour for the given time 54 | refreshCache(t); 55 | return tm.Hour; 56 | } 57 | 58 | int hourFormat12() { // the hour now in 12 hour format 59 | return hourFormat12(now()); 60 | } 61 | 62 | int hourFormat12(time_t t) { // the hour for the given time in 12 hour format 63 | refreshCache(t); 64 | if( tm.Hour == 0 ) 65 | return 12; // 12 midnight 66 | else if( tm.Hour > 12) 67 | return tm.Hour - 12 ; 68 | else 69 | return tm.Hour ; 70 | } 71 | 72 | uint8_t isAM() { // returns true if time now is AM 73 | return !isPM(now()); 74 | } 75 | 76 | uint8_t isAM(time_t t) { // returns true if given time is AM 77 | return !isPM(t); 78 | } 79 | 80 | uint8_t isPM() { // returns true if PM 81 | return isPM(now()); 82 | } 83 | 84 | uint8_t isPM(time_t t) { // returns true if PM 85 | return (hour(t) >= 12); 86 | } 87 | 88 | int minute() { 89 | return minute(now()); 90 | } 91 | 92 | int minute(time_t t) { // the minute for the given time 93 | refreshCache(t); 94 | return tm.Minute; 95 | } 96 | 97 | int second() { 98 | return second(now()); 99 | } 100 | 101 | int second(time_t t) { // the second for the given time 102 | refreshCache(t); 103 | return tm.Second; 104 | } 105 | 106 | int day(){ 107 | return(day(now())); 108 | } 109 | 110 | int day(time_t t) { // the day for the given time (0-6) 111 | refreshCache(t); 112 | return tm.Day; 113 | } 114 | 115 | int weekday() { // Sunday is day 1 116 | return weekday(now()); 117 | } 118 | 119 | int weekday(time_t t) { 120 | refreshCache(t); 121 | return tm.Wday; 122 | } 123 | 124 | int month(){ 125 | return month(now()); 126 | } 127 | 128 | int month(time_t t) { // the month for the given time 129 | refreshCache(t); 130 | return tm.Month; 131 | } 132 | 133 | int year() { // as in Processing, the full four digit year: (2009, 2010 etc) 134 | return year(now()); 135 | } 136 | 137 | int year(time_t t) { // the year for the given time 138 | refreshCache(t); 139 | return tmYearToCalendar(tm.Year); 140 | } 141 | 142 | /*============================================================================*/ 143 | /* functions to convert to and from system time */ 144 | /* These are for interfacing with time services and are not normally needed in a sketch */ 145 | 146 | // leap year calculator expects year argument as years offset from 1970 147 | #define LEAP_YEAR(Y) ( ((1970+(Y))>0) && !((1970+(Y))%4) && ( ((1970+(Y))%100) || !((1970+(Y))%400) ) ) 148 | 149 | static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 150 | 151 | void breakTime(time_t timeInput, tmElements_t &tm){ 152 | // break the given time_t into time components 153 | // this is a more compact version of the C library localtime function 154 | // note that year is offset from 1970 !!! 155 | 156 | uint8_t year; 157 | uint8_t month, monthLength; 158 | uint32_t time; 159 | unsigned long days; 160 | 161 | time = (uint32_t)timeInput; 162 | tm.Second = time % 60; 163 | time /= 60; // now it is minutes 164 | tm.Minute = time % 60; 165 | time /= 60; // now it is hours 166 | tm.Hour = time % 24; 167 | time /= 24; // now it is days 168 | tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 169 | 170 | year = 0; 171 | days = 0; 172 | while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { 173 | year++; 174 | } 175 | tm.Year = year; // year is offset from 1970 176 | 177 | days -= LEAP_YEAR(year) ? 366 : 365; 178 | time -= days; // now it is days in this year, starting at 0 179 | 180 | days=0; 181 | month=0; 182 | monthLength=0; 183 | for (month=0; month<12; month++) { 184 | if (month==1) { // february 185 | if (LEAP_YEAR(year)) { 186 | monthLength=29; 187 | } else { 188 | monthLength=28; 189 | } 190 | } else { 191 | monthLength = monthDays[month]; 192 | } 193 | 194 | if (time >= monthLength) { 195 | time -= monthLength; 196 | } else { 197 | break; 198 | } 199 | } 200 | tm.Month = month + 1; // jan is month 1 201 | tm.Day = time + 1; // day of month 202 | } 203 | 204 | time_t makeTime(const tmElements_t &tm){ 205 | // assemble time elements into time_t 206 | // note year argument is offset from 1970 (see macros in time.h to convert to other formats) 207 | // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 208 | 209 | int i; 210 | uint32_t seconds; 211 | 212 | // seconds from 1970 till 1 jan 00:00:00 of the given year 213 | seconds= tm.Year*(SECS_PER_DAY * 365); 214 | for (i = 0; i < tm.Year; i++) { 215 | if (LEAP_YEAR(i)) { 216 | seconds += SECS_PER_DAY; // add extra days for leap years 217 | } 218 | } 219 | 220 | // add days for this year, months start from 1 221 | for (i = 1; i < tm.Month; i++) { 222 | if ( (i == 2) && LEAP_YEAR(tm.Year)) { 223 | seconds += SECS_PER_DAY * 29; 224 | } else { 225 | seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 226 | } 227 | } 228 | seconds+= (tm.Day-1) * SECS_PER_DAY; 229 | seconds+= tm.Hour * SECS_PER_HOUR; 230 | seconds+= tm.Minute * SECS_PER_MIN; 231 | seconds+= tm.Second; 232 | return (time_t)seconds; 233 | } 234 | /*=====================================================*/ 235 | /* Low level system time functions */ 236 | 237 | static uint32_t sysTime = 0; 238 | static uint32_t prevMillis = 0; 239 | static uint32_t nextSyncTime = 0; 240 | static timeStatus_t Status = timeNotSet; 241 | 242 | getExternalTime getTimePtr; // pointer to external sync function 243 | //setExternalTime setTimePtr; // not used in this version 244 | 245 | #ifdef TIME_DRIFT_INFO // define this to get drift data 246 | time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync 247 | #endif 248 | 249 | 250 | time_t now() { 251 | // calculate number of seconds passed since last call to now() 252 | while (millis() - prevMillis >= 1000) { 253 | // millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference 254 | sysTime++; 255 | prevMillis += 1000; 256 | #ifdef TIME_DRIFT_INFO 257 | sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift 258 | #endif 259 | } 260 | if (nextSyncTime <= sysTime) { 261 | if (getTimePtr != 0) { 262 | time_t t = getTimePtr(); 263 | if (t != 0) { 264 | setTime(t); 265 | } else { 266 | nextSyncTime = sysTime + syncInterval; 267 | Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync; 268 | } 269 | } 270 | } 271 | return (time_t)sysTime; 272 | } 273 | 274 | void setTime(time_t t) { 275 | #ifdef TIME_DRIFT_INFO 276 | if(sysUnsyncedTime == 0) 277 | sysUnsyncedTime = t; // store the time of the first call to set a valid Time 278 | #endif 279 | 280 | sysTime = (uint32_t)t; 281 | nextSyncTime = (uint32_t)t + syncInterval; 282 | Status = timeSet; 283 | prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) 284 | } 285 | 286 | void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ 287 | // year can be given as full four digit year or two digts (2010 or 10 for 2010); 288 | //it is converted to years since 1970 289 | if( yr > 99) 290 | yr = yr - 1970; 291 | else 292 | yr += 30; 293 | tm.Year = yr; 294 | tm.Month = mnth; 295 | tm.Day = dy; 296 | tm.Hour = hr; 297 | tm.Minute = min; 298 | tm.Second = sec; 299 | setTime(makeTime(tm)); 300 | } 301 | 302 | void adjustTime(long adjustment) { 303 | sysTime += adjustment; 304 | } 305 | 306 | // indicates if time has been set and recently synchronized 307 | timeStatus_t timeStatus() { 308 | now(); // required to actually update the status 309 | return Status; 310 | } 311 | 312 | void setSyncProvider( getExternalTime getTimeFunction){ 313 | getTimePtr = getTimeFunction; 314 | nextSyncTime = sysTime; 315 | now(); // this will sync the clock 316 | } 317 | 318 | void setSyncInterval(time_t interval){ // set the number of seconds between re-sync 319 | syncInterval = (uint32_t)interval; 320 | nextSyncTime = sysTime + syncInterval; 321 | } 322 | -------------------------------------------------------------------------------- /TimeLib.h: -------------------------------------------------------------------------------- 1 | /* 2 | time.h - low level time and date functions 3 | */ 4 | 5 | /* 6 | July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this) 7 | - fixed daysToTime_t macro (thanks maniacbug) 8 | */ 9 | 10 | #ifndef _Time_h 11 | #ifdef __cplusplus 12 | #define _Time_h 13 | 14 | #include 15 | #ifndef __AVR__ 16 | #include // for __time_t_defined, but avr libc lacks sys/types.h 17 | #endif 18 | 19 | 20 | #if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc 21 | typedef unsigned long time_t; 22 | #endif 23 | 24 | 25 | // This ugly hack allows us to define C++ overloaded functions, when included 26 | // from within an extern "C", as newlib's sys/stat.h does. Actually it is 27 | // intended to include "time.h" from the C library (on ARM, but AVR does not 28 | // have that file at all). On Mac and Windows, the compiler will find this 29 | // "Time.h" instead of the C library "time.h", so we may cause other weird 30 | // and unpredictable effects by conflicting with the C library header "time.h", 31 | // but at least this hack lets us define C++ functions as intended. Hopefully 32 | // nothing too terrible will result from overriding the C library header?! 33 | extern "C++" { 34 | typedef enum {timeNotSet, timeNeedsSync, timeSet 35 | } timeStatus_t ; 36 | 37 | typedef enum { 38 | dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday 39 | } timeDayOfWeek_t; 40 | 41 | typedef enum { 42 | tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields 43 | } tmByteFields; 44 | 45 | typedef struct { 46 | uint8_t Second; 47 | uint8_t Minute; 48 | uint8_t Hour; 49 | uint8_t Wday; // day of week, sunday is day 1 50 | uint8_t Day; 51 | uint8_t Month; 52 | uint8_t Year; // offset from 1970; 53 | } tmElements_t, TimeElements, *tmElementsPtr_t; 54 | 55 | //convenience macros to convert to and from tm years 56 | #define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year 57 | #define CalendarYrToTm(Y) ((Y) - 1970) 58 | #define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000 59 | #define y2kYearToTm(Y) ((Y) + 30) 60 | 61 | typedef time_t(*getExternalTime)(); 62 | //typedef void (*setExternalTime)(const time_t); // not used in this version 63 | 64 | 65 | /*==============================================================================*/ 66 | /* Useful Constants */ 67 | #define SECS_PER_MIN ((time_t)(60UL)) 68 | #define SECS_PER_HOUR ((time_t)(3600UL)) 69 | #define SECS_PER_DAY ((time_t)(SECS_PER_HOUR * 24UL)) 70 | #define DAYS_PER_WEEK ((time_t)(7UL)) 71 | #define SECS_PER_WEEK ((time_t)(SECS_PER_DAY * DAYS_PER_WEEK)) 72 | #define SECS_PER_YEAR ((time_t)(SECS_PER_DAY * 365UL)) // TODO: ought to handle leap years 73 | #define SECS_YR_2000 ((time_t)(946684800UL)) // the time at the start of y2k 74 | 75 | /* Useful Macros for getting elapsed time */ 76 | #define numberOfSeconds(_time_) ((_time_) % SECS_PER_MIN) 77 | #define numberOfMinutes(_time_) (((_time_) / SECS_PER_MIN) % SECS_PER_MIN) 78 | #define numberOfHours(_time_) (((_time_) % SECS_PER_DAY) / SECS_PER_HOUR) 79 | #define dayOfWeek(_time_) ((((_time_) / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday 80 | #define elapsedDays(_time_) ((_time_) / SECS_PER_DAY) // this is number of days since Jan 1 1970 81 | #define elapsedSecsToday(_time_) ((_time_) % SECS_PER_DAY) // the number of seconds since last midnight 82 | // The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 83 | // Always set the correct time before setting alarms 84 | #define previousMidnight(_time_) (((_time_) / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day 85 | #define nextMidnight(_time_) (previousMidnight(_time_) + SECS_PER_DAY) // time at the end of the given day 86 | #define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY)) // note that week starts on day 1 87 | #define previousSunday(_time_) ((_time_) - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time 88 | #define nextSunday(_time_) (previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time 89 | 90 | 91 | /* Useful Macros for converting elapsed time to a time_t */ 92 | #define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN) 93 | #define hoursToTime_t ((H)) ( (H) * SECS_PER_HOUR) 94 | #define daysToTime_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011 95 | #define weeksToTime_t ((W)) ( (W) * SECS_PER_WEEK) 96 | 97 | /*============================================================================*/ 98 | /* time and date functions */ 99 | int hour(); // the hour now 100 | int hour(time_t t); // the hour for the given time 101 | int hourFormat12(); // the hour now in 12 hour format 102 | int hourFormat12(time_t t); // the hour for the given time in 12 hour format 103 | uint8_t isAM(); // returns true if time now is AM 104 | uint8_t isAM(time_t t); // returns true the given time is AM 105 | uint8_t isPM(); // returns true if time now is PM 106 | uint8_t isPM(time_t t); // returns true the given time is PM 107 | int minute(); // the minute now 108 | int minute(time_t t); // the minute for the given time 109 | int second(); // the second now 110 | int second(time_t t); // the second for the given time 111 | int day(); // the day now 112 | int day(time_t t); // the day for the given time 113 | int weekday(); // the weekday now (Sunday is day 1) 114 | int weekday(time_t t); // the weekday for the given time 115 | int month(); // the month now (Jan is month 1) 116 | int month(time_t t); // the month for the given time 117 | int year(); // the full four digit year: (2009, 2010 etc) 118 | int year(time_t t); // the year for the given time 119 | 120 | time_t now(); // return the current time as seconds since Jan 1 1970 121 | void setTime(time_t t); 122 | void setTime(int hr,int min,int sec,int day, int month, int yr); 123 | void adjustTime(long adjustment); 124 | 125 | /* date strings */ 126 | #define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null) 127 | char* monthStr(uint8_t month); 128 | char* dayStr(uint8_t day); 129 | char* monthShortStr(uint8_t month); 130 | char* dayShortStr(uint8_t day); 131 | 132 | /* time sync functions */ 133 | timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized 134 | void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider 135 | void setSyncInterval(time_t interval); // set the number of seconds between re-sync 136 | 137 | /* low level functions to convert to and from system time */ 138 | void breakTime(time_t time, tmElements_t &tm); // break time_t into elements 139 | time_t makeTime(const tmElements_t &tm); // convert time elements into time_t 140 | 141 | } // extern "C++" 142 | #endif // __cplusplus 143 | #endif /* _Time_h */ 144 | 145 | -------------------------------------------------------------------------------- /docs/issue_template.md: -------------------------------------------------------------------------------- 1 | Please use this form only to report code defects or bugs. 2 | 3 | For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using. 4 | 5 | Arduino: forum.arduino.cc 6 | Teensy: forum.pjrc.com 7 | ESP8266: www.esp8266.com 8 | ESP32: www.esp32.com 9 | Adafruit Feather/Metro/Trinket: forums.adafruit.com 10 | Particle Photon: community.particle.io 11 | 12 | If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum. This is not the place to ask for support or help, even directly related to this code. Only use this form you are certain you have discovered a defect in this code! 13 | 14 | Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software. 15 | 16 | 17 | ----------------------------- Remove above ----------------------------- 18 | 19 | 20 | 21 | ### Description 22 | 23 | Describe your problem. 24 | 25 | 26 | 27 | ### Steps To Reproduce Problem 28 | 29 | Please give detailed instructions needed for anyone to attempt to reproduce the problem. 30 | 31 | 32 | 33 | ### Hardware & Software 34 | 35 | Board 36 | Shields / modules used 37 | Arduino IDE version 38 | Teensyduino version (if using Teensy) 39 | Version info & package name (from Tools > Boards > Board Manager) 40 | Operating system & version 41 | Any other software or hardware? 42 | 43 | 44 | ### Arduino Sketch 45 | 46 | ```cpp 47 | // Change the code below by your sketch (please try to give the smallest code which demonstrates the problem) 48 | #include 49 | 50 | // libraries: give links/details so anyone can compile your code for the same result 51 | 52 | void setup() { 53 | } 54 | 55 | void loop() { 56 | } 57 | ``` 58 | 59 | 60 | ### Errors or Incorrect Output 61 | 62 | If you see any errors or incorrect output, please show it here. Please use copy & paste to give an exact copy of the message. Details matter, so please show (not merely describe) the actual message or error exactly as it appears. 63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/Processing/SyncArduinoClock/SyncArduinoClock.pde: -------------------------------------------------------------------------------- 1 | /** 2 | * SyncArduinoClock. 3 | * 4 | * SyncArduinoClock is a Processing sketch that responds to Arduino 5 | * requests for time synchronization messages. Run this in the 6 | * Processing environment (not in Arduino) on your PC or Mac. 7 | * 8 | * Download TimeSerial onto Arduino and you should see the time 9 | * message displayed when you run SyncArduinoClock in Processing. 10 | * The Arduino time is set from the time on your computer through the 11 | * Processing sketch. 12 | * 13 | * portIndex must be set to the port connected to the Arduino 14 | * 15 | * The current time is sent in response to request message from Arduino 16 | * or by clicking the display window 17 | * 18 | * The time message is 11 ASCII text characters; a header (the letter 'T') 19 | * followed by the ten digit system time (unix time) 20 | */ 21 | 22 | 23 | import processing.serial.*; 24 | import java.util.Date; 25 | import java.util.Calendar; 26 | import java.util.GregorianCalendar; 27 | 28 | public static final short portIndex = 0; // select the com port, 0 is the first port 29 | public static final String TIME_HEADER = "T"; //header for arduino serial time message 30 | public static final char TIME_REQUEST = 7; // ASCII bell character 31 | public static final char LF = 10; // ASCII linefeed 32 | public static final char CR = 13; // ASCII linefeed 33 | Serial myPort; // Create object from Serial class 34 | 35 | void setup() { 36 | size(200, 200); 37 | println(Serial.list()); 38 | println(" Connecting to -> " + Serial.list()[portIndex]); 39 | myPort = new Serial(this,Serial.list()[portIndex], 9600); 40 | println(getTimeNow()); 41 | } 42 | 43 | void draw() 44 | { 45 | textSize(20); 46 | textAlign(CENTER); 47 | fill(0); 48 | text("Click to send\nTime Sync", 0, 75, 200, 175); 49 | if ( myPort.available() > 0) { // If data is available, 50 | char val = char(myPort.read()); // read it and store it in val 51 | if(val == TIME_REQUEST){ 52 | long t = getTimeNow(); 53 | sendTimeMessage(TIME_HEADER, t); 54 | } 55 | else 56 | { 57 | if(val == LF) 58 | ; //igonore 59 | else if(val == CR) 60 | println(); 61 | else 62 | print(val); // echo everying but time request 63 | } 64 | } 65 | } 66 | 67 | void mousePressed() { 68 | sendTimeMessage( TIME_HEADER, getTimeNow()); 69 | } 70 | 71 | 72 | void sendTimeMessage(String header, long time) { 73 | String timeStr = String.valueOf(time); 74 | myPort.write(header); // send header and time to arduino 75 | myPort.write(timeStr); 76 | myPort.write('\n'); 77 | } 78 | 79 | long getTimeNow(){ 80 | // java time is in ms, we want secs 81 | Date d = new Date(); 82 | Calendar cal = new GregorianCalendar(); 83 | long current = d.getTime()/1000; 84 | long timezone = cal.get(cal.ZONE_OFFSET)/1000; 85 | long daylight = cal.get(cal.DST_OFFSET)/1000; 86 | return current + timezone + daylight; 87 | } 88 | -------------------------------------------------------------------------------- /examples/Processing/SyncArduinoClock/readme.txt: -------------------------------------------------------------------------------- 1 | SyncArduinoClock is a Processing sketch that responds to Arduino requests for 2 | time synchronization messages. 3 | 4 | The portIndex must be set the Serial port connected to Arduino. 5 | 6 | Download TimeSerial.pde onto Arduino and you should see the time 7 | message displayed when you run SyncArduinoClock in Processing. 8 | The Arduino time is set from the time on your computer through the 9 | Processing sketch. 10 | -------------------------------------------------------------------------------- /examples/TimeArduinoDue/TimeArduinoDue.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeRTC.pde 3 | * example code illustrating Time library with Real Time Clock. 4 | * 5 | * This example requires Markus Lange's Arduino Due RTC Library 6 | * https://github.com/MarkusLange/Arduino-Due-RTC-Library 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | // Select the Slowclock source 13 | //RTC_clock rtc_clock(RC); 14 | RTC_clock rtc_clock(XTAL); 15 | 16 | void setup() { 17 | Serial.begin(9600); 18 | rtc_clock.init(); 19 | if (rtc_clock.date_already_set() == 0) { 20 | // Unfortunately, the Arduino Due hardware does not seem to 21 | // be designed to maintain the RTC clock state when the 22 | // board resets. Markus described it thusly: "Uhh the Due 23 | // does reset with the NRSTB pin. This resets the full chip 24 | // with all backup regions including RTC, RTT and SC. Only 25 | // if the reset is done with the NRST pin will these regions 26 | // stay with their old values." 27 | rtc_clock.set_time(__TIME__); 28 | rtc_clock.set_date(__DATE__); 29 | // However, this might work on other unofficial SAM3X boards 30 | // with different reset circuitry than Arduino Due? 31 | } 32 | setSyncProvider(getArduinoDueTime); 33 | if(timeStatus()!= timeSet) 34 | Serial.println("Unable to sync with the RTC"); 35 | else 36 | Serial.println("RTC has set the system time"); 37 | } 38 | 39 | time_t getArduinoDueTime() 40 | { 41 | return rtc_clock.unixtime(); 42 | } 43 | 44 | void loop() 45 | { 46 | digitalClockDisplay(); 47 | delay(1000); 48 | } 49 | 50 | void digitalClockDisplay(){ 51 | // digital clock display of the time 52 | Serial.print(hour()); 53 | printDigits(minute()); 54 | printDigits(second()); 55 | Serial.print(" "); 56 | Serial.print(day()); 57 | Serial.print(" "); 58 | Serial.print(month()); 59 | Serial.print(" "); 60 | Serial.print(year()); 61 | Serial.println(); 62 | } 63 | 64 | void printDigits(int digits){ 65 | // utility function for digital clock display: prints preceding colon and leading 0 66 | Serial.print(":"); 67 | if(digits < 10) 68 | Serial.print('0'); 69 | Serial.print(digits); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /examples/TimeGPS/TimeGPS.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeGPS.pde 3 | * example code illustrating time synced from a GPS 4 | * 5 | */ 6 | 7 | #include 8 | #include // http://arduiniana.org/libraries/TinyGPS/ 9 | #include 10 | // TinyGPS and SoftwareSerial libraries are the work of Mikal Hart 11 | 12 | SoftwareSerial SerialGPS = SoftwareSerial(10, 11); // receive on pin 10 13 | TinyGPS gps; 14 | 15 | // To use a hardware serial port, which is far more efficient than 16 | // SoftwareSerial, uncomment this line and remove SoftwareSerial 17 | //#define SerialGPS Serial1 18 | 19 | // Offset hours from gps time (UTC) 20 | const int offset = 1; // Central European Time 21 | //const int offset = -5; // Eastern Standard Time (USA) 22 | //const int offset = -4; // Eastern Daylight Time (USA) 23 | //const int offset = -8; // Pacific Standard Time (USA) 24 | //const int offset = -7; // Pacific Daylight Time (USA) 25 | 26 | // Ideally, it should be possible to learn the time zone 27 | // based on the GPS position data. However, that would 28 | // require a complex library, probably incorporating some 29 | // sort of database using Eric Muller's time zone shape 30 | // maps, at http://efele.net/maps/tz/ 31 | 32 | time_t prevDisplay = 0; // when the digital clock was displayed 33 | 34 | void setup() 35 | { 36 | Serial.begin(9600); 37 | while (!Serial) ; // Needed for Leonardo only 38 | SerialGPS.begin(4800); 39 | Serial.println("Waiting for GPS time ... "); 40 | } 41 | 42 | void loop() 43 | { 44 | while (SerialGPS.available()) { 45 | if (gps.encode(SerialGPS.read())) { // process gps messages 46 | // when TinyGPS reports new data... 47 | unsigned long age; 48 | int Year; 49 | byte Month, Day, Hour, Minute, Second; 50 | gps.crack_datetime(&Year, &Month, &Day, &Hour, &Minute, &Second, NULL, &age); 51 | if (age < 500) { 52 | // set the Time to the latest GPS reading 53 | setTime(Hour, Minute, Second, Day, Month, Year); 54 | adjustTime(offset * SECS_PER_HOUR); 55 | } 56 | } 57 | } 58 | if (timeStatus()!= timeNotSet) { 59 | if (now() != prevDisplay) { //update the display only if the time has changed 60 | prevDisplay = now(); 61 | digitalClockDisplay(); 62 | } 63 | } 64 | } 65 | 66 | void digitalClockDisplay(){ 67 | // digital clock display of the time 68 | Serial.print(hour()); 69 | printDigits(minute()); 70 | printDigits(second()); 71 | Serial.print(" "); 72 | Serial.print(day()); 73 | Serial.print(" "); 74 | Serial.print(month()); 75 | Serial.print(" "); 76 | Serial.print(year()); 77 | Serial.println(); 78 | } 79 | 80 | void printDigits(int digits) { 81 | // utility function for digital clock display: prints preceding colon and leading 0 82 | Serial.print(":"); 83 | if(digits < 10) 84 | Serial.print('0'); 85 | Serial.print(digits); 86 | } 87 | 88 | -------------------------------------------------------------------------------- /examples/TimeNTP/TimeNTP.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Time_NTP.pde 3 | * Example showing time sync to NTP time source 4 | * 5 | * This sketch uses the Ethernet library 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 14 | // NTP Servers: 15 | IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov 16 | // IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov 17 | // IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov 18 | 19 | 20 | const int timeZone = 1; // Central European Time 21 | //const int timeZone = -5; // Eastern Standard Time (USA) 22 | //const int timeZone = -4; // Eastern Daylight Time (USA) 23 | //const int timeZone = -8; // Pacific Standard Time (USA) 24 | //const int timeZone = -7; // Pacific Daylight Time (USA) 25 | 26 | 27 | EthernetUDP Udp; 28 | unsigned int localPort = 8888; // local port to listen for UDP packets 29 | 30 | void setup() 31 | { 32 | Serial.begin(9600); 33 | while (!Serial) ; // Needed for Leonardo only 34 | delay(250); 35 | Serial.println("TimeNTP Example"); 36 | if (Ethernet.begin(mac) == 0) { 37 | // no point in carrying on, so do nothing forevermore: 38 | while (1) { 39 | Serial.println("Failed to configure Ethernet using DHCP"); 40 | delay(10000); 41 | } 42 | } 43 | Serial.print("IP number assigned by DHCP is "); 44 | Serial.println(Ethernet.localIP()); 45 | Udp.begin(localPort); 46 | Serial.println("waiting for sync"); 47 | setSyncProvider(getNtpTime); 48 | } 49 | 50 | time_t prevDisplay = 0; // when the digital clock was displayed 51 | 52 | void loop() 53 | { 54 | if (timeStatus() != timeNotSet) { 55 | if (now() != prevDisplay) { //update the display only if time has changed 56 | prevDisplay = now(); 57 | digitalClockDisplay(); 58 | } 59 | } 60 | } 61 | 62 | void digitalClockDisplay(){ 63 | // digital clock display of the time 64 | Serial.print(hour()); 65 | printDigits(minute()); 66 | printDigits(second()); 67 | Serial.print(" "); 68 | Serial.print(day()); 69 | Serial.print(" "); 70 | Serial.print(month()); 71 | Serial.print(" "); 72 | Serial.print(year()); 73 | Serial.println(); 74 | } 75 | 76 | void printDigits(int digits){ 77 | // utility for digital clock display: prints preceding colon and leading 0 78 | Serial.print(":"); 79 | if(digits < 10) 80 | Serial.print('0'); 81 | Serial.print(digits); 82 | } 83 | 84 | /*-------- NTP code ----------*/ 85 | 86 | const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message 87 | byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets 88 | 89 | time_t getNtpTime() 90 | { 91 | while (Udp.parsePacket() > 0) ; // discard any previously received packets 92 | Serial.println("Transmit NTP Request"); 93 | sendNTPpacket(timeServer); 94 | uint32_t beginWait = millis(); 95 | while (millis() - beginWait < 1500) { 96 | int size = Udp.parsePacket(); 97 | if (size >= NTP_PACKET_SIZE) { 98 | Serial.println("Receive NTP Response"); 99 | Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer 100 | unsigned long secsSince1900; 101 | // convert four bytes starting at location 40 to a long integer 102 | secsSince1900 = (unsigned long)packetBuffer[40] << 24; 103 | secsSince1900 |= (unsigned long)packetBuffer[41] << 16; 104 | secsSince1900 |= (unsigned long)packetBuffer[42] << 8; 105 | secsSince1900 |= (unsigned long)packetBuffer[43]; 106 | return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; 107 | } 108 | } 109 | Serial.println("No NTP Response :-("); 110 | return 0; // return 0 if unable to get the time 111 | } 112 | 113 | // send an NTP request to the time server at the given address 114 | void sendNTPpacket(IPAddress &address) 115 | { 116 | // set all bytes in the buffer to 0 117 | memset(packetBuffer, 0, NTP_PACKET_SIZE); 118 | // Initialize values needed to form NTP request 119 | // (see URL above for details on the packets) 120 | packetBuffer[0] = 0b11100011; // LI, Version, Mode 121 | packetBuffer[1] = 0; // Stratum, or type of clock 122 | packetBuffer[2] = 6; // Polling Interval 123 | packetBuffer[3] = 0xEC; // Peer Clock Precision 124 | // 8 bytes of zero for Root Delay & Root Dispersion 125 | packetBuffer[12] = 49; 126 | packetBuffer[13] = 0x4E; 127 | packetBuffer[14] = 49; 128 | packetBuffer[15] = 52; 129 | // all NTP fields have been given values, now 130 | // you can send a packet requesting a timestamp: 131 | Udp.beginPacket(address, 123); //NTP requests are to port 123 132 | Udp.write(packetBuffer, NTP_PACKET_SIZE); 133 | Udp.endPacket(); 134 | } 135 | 136 | -------------------------------------------------------------------------------- /examples/TimeNTP_ENC28J60/TimeNTP_ENC28J60.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Time_NTP.pde 3 | * Example showing time sync to NTP time source 4 | * 5 | * Also shows how to handle DST automatically. 6 | * 7 | * This sketch uses the EtherCard library: 8 | * http://jeelabs.org/pub/docs/ethercard/ 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 15 | 16 | // NTP Server 17 | const char timeServer[] PROGMEM = "pool.ntp.org"; 18 | 19 | const int utcOffset = 1; // Central European Time 20 | //const int utcOffset = -5; // Eastern Standard Time (USA) 21 | //const int utcOffset = -4; // Eastern Daylight Time (USA) 22 | //const int utcOffset = -8; // Pacific Standard Time (USA) 23 | //const int utcOffset = -7; // Pacific Daylight Time (USA) 24 | 25 | // Packet buffer, must be big enough to packet and payload 26 | #define BUFFER_SIZE 550 27 | byte Ethernet::buffer[BUFFER_SIZE]; 28 | 29 | const unsigned int remotePort = 123; 30 | 31 | void setup() 32 | { 33 | Serial.begin(9600); 34 | 35 | while (!Serial) // Needed for Leonardo only 36 | ; 37 | delay(250); 38 | 39 | Serial.println("TimeNTP_ENC28J60 Example"); 40 | 41 | if (ether.begin(BUFFER_SIZE, mac) == 0) { 42 | // no point in carrying on, so do nothing forevermore: 43 | while (1) { 44 | Serial.println("Failed to access Ethernet controller"); 45 | delay(10000); 46 | } 47 | } 48 | 49 | if (!ether.dhcpSetup()) { 50 | // no point in carrying on, so do nothing forevermore: 51 | while (1) { 52 | Serial.println("Failed to configure Ethernet using DHCP"); 53 | delay(10000); 54 | } 55 | } 56 | 57 | ether.printIp("IP number assigned by DHCP is ", ether.myip); 58 | 59 | Serial.println("waiting for sync"); 60 | //setSyncProvider(getNtpTime); // Use this for GMT time 61 | setSyncProvider(getDstCorrectedTime); // Use this for local, DST-corrected time 62 | } 63 | 64 | time_t prevDisplay = 0; // when the digital clock was displayed 65 | 66 | void loop() 67 | { 68 | if (timeStatus() != timeNotSet) { 69 | if (now() != prevDisplay) { //update the display only if time has changed 70 | prevDisplay = now(); 71 | digitalClockDisplay(); 72 | } 73 | } 74 | } 75 | 76 | void digitalClockDisplay(){ 77 | // digital clock display of the time 78 | Serial.print(hour()); 79 | printDigits(minute()); 80 | printDigits(second()); 81 | Serial.print(" "); 82 | Serial.print(day()); 83 | Serial.print(" "); 84 | Serial.print(month()); 85 | Serial.print(" "); 86 | Serial.print(year()); 87 | Serial.println(); 88 | } 89 | 90 | void printDigits(int digits){ 91 | // utility for digital clock display: prints preceding colon and leading 0 92 | Serial.print(":"); 93 | if(digits < 10) 94 | Serial.print('0'); 95 | Serial.print(digits); 96 | } 97 | 98 | /*-------- NTP code ----------*/ 99 | 100 | // SyncProvider that returns UTC time 101 | time_t getNtpTime() 102 | { 103 | // Send request 104 | Serial.println("Transmit NTP Request"); 105 | if (!ether.dnsLookup(timeServer)) { 106 | Serial.println("DNS failed"); 107 | return 0; // return 0 if unable to get the time 108 | } else { 109 | //ether.printIp("SRV: ", ether.hisip); 110 | ether.ntpRequest(ether.hisip, remotePort); 111 | 112 | // Wait for reply 113 | uint32_t beginWait = millis(); 114 | while (millis() - beginWait < 1500) { 115 | word len = ether.packetReceive(); 116 | ether.packetLoop(len); 117 | 118 | unsigned long secsSince1900 = 0L; 119 | if (len > 0 && ether.ntpProcessAnswer(&secsSince1900, remotePort)) { 120 | Serial.println("Receive NTP Response"); 121 | return secsSince1900 - 2208988800UL; 122 | } 123 | } 124 | 125 | Serial.println("No NTP Response :-("); 126 | return 0; 127 | } 128 | } 129 | 130 | /* Alternative SyncProvider that automatically handles Daylight Saving Time (DST) periods, 131 | * at least in Europe, see below. 132 | */ 133 | time_t getDstCorrectedTime (void) { 134 | time_t t = getNtpTime (); 135 | 136 | if (t > 0) { 137 | TimeElements tm; 138 | breakTime (t, tm); 139 | t += (utcOffset + dstOffset (tm.Day, tm.Month, tm.Year + 1970, tm.Hour)) * SECS_PER_HOUR; 140 | } 141 | 142 | return t; 143 | } 144 | 145 | /* This function returns the DST offset for the current UTC time. 146 | * This is valid for the EU, for other places see 147 | * http://www.webexhibits.org/daylightsaving/i.html 148 | * 149 | * Results have been checked for 2012-2030 (but should work since 150 | * 1996 to 2099) against the following references: 151 | * - http://www.uniquevisitor.it/magazine/ora-legale-italia.php 152 | * - http://www.calendario-365.it/ora-legale-orario-invernale.html 153 | */ 154 | byte dstOffset (byte d, byte m, unsigned int y, byte h) { 155 | // Day in March that DST starts on, at 1 am 156 | byte dstOn = (31 - (5 * y / 4 + 4) % 7); 157 | 158 | // Day in October that DST ends on, at 2 am 159 | byte dstOff = (31 - (5 * y / 4 + 1) % 7); 160 | 161 | if ((m > 3 && m < 10) || 162 | (m == 3 && (d > dstOn || (d == dstOn && h >= 1))) || 163 | (m == 10 && (d < dstOff || (d == dstOff && h <= 1)))) 164 | return 1; 165 | else 166 | return 0; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeNTP_ESP8266WiFi.ino 3 | * Example showing time sync to NTP time source 4 | * 5 | * This sketch uses the ESP8266WiFi library 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | const char ssid[] = "*************"; // your network SSID (name) 13 | const char pass[] = "********"; // your network password 14 | 15 | // NTP Servers: 16 | static const char ntpServerName[] = "us.pool.ntp.org"; 17 | //static const char ntpServerName[] = "time.nist.gov"; 18 | //static const char ntpServerName[] = "time-a.timefreq.bldrdoc.gov"; 19 | //static const char ntpServerName[] = "time-b.timefreq.bldrdoc.gov"; 20 | //static const char ntpServerName[] = "time-c.timefreq.bldrdoc.gov"; 21 | 22 | const int timeZone = 1; // Central European Time 23 | //const int timeZone = -5; // Eastern Standard Time (USA) 24 | //const int timeZone = -4; // Eastern Daylight Time (USA) 25 | //const int timeZone = -8; // Pacific Standard Time (USA) 26 | //const int timeZone = -7; // Pacific Daylight Time (USA) 27 | 28 | 29 | WiFiUDP Udp; 30 | unsigned int localPort = 8888; // local port to listen for UDP packets 31 | 32 | time_t getNtpTime(); 33 | void digitalClockDisplay(); 34 | void printDigits(int digits); 35 | void sendNTPpacket(IPAddress &address); 36 | 37 | void setup() 38 | { 39 | Serial.begin(9600); 40 | while (!Serial) ; // Needed for Leonardo only 41 | delay(250); 42 | Serial.println("TimeNTP Example"); 43 | Serial.print("Connecting to "); 44 | Serial.println(ssid); 45 | WiFi.begin(ssid, pass); 46 | 47 | while (WiFi.status() != WL_CONNECTED) { 48 | delay(500); 49 | Serial.print("."); 50 | } 51 | 52 | Serial.print("IP number assigned by DHCP is "); 53 | Serial.println(WiFi.localIP()); 54 | Serial.println("Starting UDP"); 55 | Udp.begin(localPort); 56 | Serial.print("Local port: "); 57 | Serial.println(Udp.localPort()); 58 | Serial.println("waiting for sync"); 59 | setSyncProvider(getNtpTime); 60 | setSyncInterval(300); 61 | } 62 | 63 | time_t prevDisplay = 0; // when the digital clock was displayed 64 | 65 | void loop() 66 | { 67 | if (timeStatus() != timeNotSet) { 68 | if (now() != prevDisplay) { //update the display only if time has changed 69 | prevDisplay = now(); 70 | digitalClockDisplay(); 71 | } 72 | } 73 | } 74 | 75 | void digitalClockDisplay() 76 | { 77 | // digital clock display of the time 78 | Serial.print(hour()); 79 | printDigits(minute()); 80 | printDigits(second()); 81 | Serial.print(" "); 82 | Serial.print(day()); 83 | Serial.print("."); 84 | Serial.print(month()); 85 | Serial.print("."); 86 | Serial.print(year()); 87 | Serial.println(); 88 | } 89 | 90 | void printDigits(int digits) 91 | { 92 | // utility for digital clock display: prints preceding colon and leading 0 93 | Serial.print(":"); 94 | if (digits < 10) 95 | Serial.print('0'); 96 | Serial.print(digits); 97 | } 98 | 99 | /*-------- NTP code ----------*/ 100 | 101 | const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message 102 | byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets 103 | 104 | time_t getNtpTime() 105 | { 106 | IPAddress ntpServerIP; // NTP server's ip address 107 | 108 | while (Udp.parsePacket() > 0) ; // discard any previously received packets 109 | Serial.println("Transmit NTP Request"); 110 | // get a random server from the pool 111 | WiFi.hostByName(ntpServerName, ntpServerIP); 112 | Serial.print(ntpServerName); 113 | Serial.print(": "); 114 | Serial.println(ntpServerIP); 115 | sendNTPpacket(ntpServerIP); 116 | uint32_t beginWait = millis(); 117 | while (millis() - beginWait < 1500) { 118 | int size = Udp.parsePacket(); 119 | if (size >= NTP_PACKET_SIZE) { 120 | Serial.println("Receive NTP Response"); 121 | Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer 122 | unsigned long secsSince1900; 123 | // convert four bytes starting at location 40 to a long integer 124 | secsSince1900 = (unsigned long)packetBuffer[40] << 24; 125 | secsSince1900 |= (unsigned long)packetBuffer[41] << 16; 126 | secsSince1900 |= (unsigned long)packetBuffer[42] << 8; 127 | secsSince1900 |= (unsigned long)packetBuffer[43]; 128 | return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; 129 | } 130 | } 131 | Serial.println("No NTP Response :-("); 132 | return 0; // return 0 if unable to get the time 133 | } 134 | 135 | // send an NTP request to the time server at the given address 136 | void sendNTPpacket(IPAddress &address) 137 | { 138 | // set all bytes in the buffer to 0 139 | memset(packetBuffer, 0, NTP_PACKET_SIZE); 140 | // Initialize values needed to form NTP request 141 | // (see URL above for details on the packets) 142 | packetBuffer[0] = 0b11100011; // LI, Version, Mode 143 | packetBuffer[1] = 0; // Stratum, or type of clock 144 | packetBuffer[2] = 6; // Polling Interval 145 | packetBuffer[3] = 0xEC; // Peer Clock Precision 146 | // 8 bytes of zero for Root Delay & Root Dispersion 147 | packetBuffer[12] = 49; 148 | packetBuffer[13] = 0x4E; 149 | packetBuffer[14] = 49; 150 | packetBuffer[15] = 52; 151 | // all NTP fields have been given values, now 152 | // you can send a packet requesting a timestamp: 153 | Udp.beginPacket(address, 123); //NTP requests are to port 123 154 | Udp.write(packetBuffer, NTP_PACKET_SIZE); 155 | Udp.endPacket(); 156 | } 157 | -------------------------------------------------------------------------------- /examples/TimeRTC/TimeRTC.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeRTC.pde 3 | * example code illustrating Time library with Real Time Clock. 4 | * 5 | */ 6 | 7 | #include 8 | #include 9 | #include // a basic DS1307 library that returns time as a time_t 10 | 11 | void setup() { 12 | Serial.begin(9600); 13 | while (!Serial) ; // wait until Arduino Serial Monitor opens 14 | setSyncProvider(RTC.get); // the function to get the time from the RTC 15 | if(timeStatus()!= timeSet) 16 | Serial.println("Unable to sync with the RTC"); 17 | else 18 | Serial.println("RTC has set the system time"); 19 | } 20 | 21 | void loop() 22 | { 23 | if (timeStatus() == timeSet) { 24 | digitalClockDisplay(); 25 | } else { 26 | Serial.println("The time has not been set. Please run the Time"); 27 | Serial.println("TimeRTCSet example, or DS1307RTC SetTime example."); 28 | Serial.println(); 29 | delay(4000); 30 | } 31 | delay(1000); 32 | } 33 | 34 | void digitalClockDisplay(){ 35 | // digital clock display of the time 36 | Serial.print(hour()); 37 | printDigits(minute()); 38 | printDigits(second()); 39 | Serial.print(" "); 40 | Serial.print(day()); 41 | Serial.print(" "); 42 | Serial.print(month()); 43 | Serial.print(" "); 44 | Serial.print(year()); 45 | Serial.println(); 46 | } 47 | 48 | void printDigits(int digits){ 49 | // utility function for digital clock display: prints preceding colon and leading 0 50 | Serial.print(":"); 51 | if(digits < 10) 52 | Serial.print('0'); 53 | Serial.print(digits); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /examples/TimeRTCLog/TimeRTCLog.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeRTCLogger.ino 3 | * example code illustrating adding and subtracting Time. 4 | * 5 | * this sketch logs pin state change events 6 | * the time of the event and time since the previous event is calculated and sent to the serial port. 7 | */ 8 | 9 | #include 10 | #include 11 | #include // a basic DS1307 library that returns time as a time_t 12 | 13 | const int nbrInputPins = 6; // monitor 6 digital pins 14 | const int inputPins[nbrInputPins] = {2,3,4,5,6,7}; // pins to monitor 15 | boolean state[nbrInputPins] ; // the state of the monitored pins 16 | time_t prevEventTime[nbrInputPins] ; // the time of the previous event 17 | 18 | void setup() { 19 | Serial.begin(9600); 20 | setSyncProvider(RTC.get); // the function to sync the time from the RTC 21 | for (int i=0; i < nbrInputPins; i++) { 22 | pinMode( inputPins[i], INPUT); 23 | // uncomment these lines if pull-up resistors are wanted 24 | // pinMode( inputPins[i], INPUT_PULLUP); 25 | // state[i] = HIGH; 26 | } 27 | } 28 | 29 | void loop() 30 | { 31 | for (int i=0; i < nbrInputPins; i++) { 32 | boolean val = digitalRead(inputPins[i]); 33 | if (val != state[i]) { 34 | time_t duration = 0; // the time since the previous event 35 | state[i] = val; 36 | time_t timeNow = now(); 37 | if (prevEventTime[i] > 0) { 38 | // if this was not the first state change, calculate the time from the previous change 39 | duration = timeNow - prevEventTime[i]; 40 | } 41 | logEvent(inputPins[i], val, timeNow, duration ); // log the event 42 | prevEventTime[i] = timeNow; // store the time for this event 43 | } 44 | } 45 | } 46 | 47 | void logEvent( int pin, boolean state, time_t timeNow, time_t duration) 48 | { 49 | Serial.print("Pin "); 50 | Serial.print(pin); 51 | if (state == HIGH) { 52 | Serial.print(" went High at "); 53 | } else { 54 | Serial.print(" went Low at "); 55 | } 56 | showTime(timeNow); 57 | if (duration > 0) { 58 | // only display duration if greater than 0 59 | Serial.print(", Duration was "); 60 | showDuration(duration); 61 | } 62 | Serial.println(); 63 | } 64 | 65 | 66 | void showTime(time_t t) 67 | { 68 | // display the given time 69 | Serial.print(hour(t)); 70 | printDigits(minute(t)); 71 | printDigits(second(t)); 72 | Serial.print(" "); 73 | Serial.print(day(t)); 74 | Serial.print(" "); 75 | Serial.print(month(t)); 76 | Serial.print(" "); 77 | Serial.print(year(t)); 78 | } 79 | 80 | void printDigits(int digits){ 81 | // utility function for digital clock display: prints preceding colon and leading 0 82 | Serial.print(":"); 83 | if(digits < 10) 84 | Serial.print('0'); 85 | Serial.print(digits); 86 | } 87 | 88 | void showDuration(time_t duration) 89 | { 90 | // prints the duration in days, hours, minutes and seconds 91 | if (duration >= SECS_PER_DAY) { 92 | Serial.print(duration / SECS_PER_DAY); 93 | Serial.print(" day(s) "); 94 | duration = duration % SECS_PER_DAY; 95 | } 96 | if (duration >= SECS_PER_HOUR) { 97 | Serial.print(duration / SECS_PER_HOUR); 98 | Serial.print(" hour(s) "); 99 | duration = duration % SECS_PER_HOUR; 100 | } 101 | if (duration >= SECS_PER_MIN) { 102 | Serial.print(duration / SECS_PER_MIN); 103 | Serial.print(" minute(s) "); 104 | duration = duration % SECS_PER_MIN; 105 | } 106 | Serial.print(duration); 107 | Serial.print(" second(s) "); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /examples/TimeRTCSet/TimeRTCSet.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeRTCSet.pde 3 | * example code illustrating Time library with Real Time Clock. 4 | * 5 | * RTC clock is set in response to serial port time message 6 | * A Processing example sketch to set the time is included in the download 7 | * On Linux, you can use "date +T%s > /dev/ttyACM0" (UTC time zone) 8 | */ 9 | 10 | #include 11 | #include 12 | #include // a basic DS1307 library that returns time as a time_t 13 | 14 | 15 | void setup() { 16 | Serial.begin(9600); 17 | while (!Serial) ; // Needed for Leonardo only 18 | setSyncProvider(RTC.get); // the function to get the time from the RTC 19 | if (timeStatus() != timeSet) 20 | Serial.println("Unable to sync with the RTC"); 21 | else 22 | Serial.println("RTC has set the system time"); 23 | } 24 | 25 | void loop() 26 | { 27 | if (Serial.available()) { 28 | time_t t = processSyncMessage(); 29 | if (t != 0) { 30 | RTC.set(t); // set the RTC and the system time to the received value 31 | setTime(t); 32 | } 33 | } 34 | digitalClockDisplay(); 35 | delay(1000); 36 | } 37 | 38 | void digitalClockDisplay(){ 39 | // digital clock display of the time 40 | Serial.print(hour()); 41 | printDigits(minute()); 42 | printDigits(second()); 43 | Serial.print(" "); 44 | Serial.print(day()); 45 | Serial.print(" "); 46 | Serial.print(month()); 47 | Serial.print(" "); 48 | Serial.print(year()); 49 | Serial.println(); 50 | } 51 | 52 | void printDigits(int digits){ 53 | // utility function for digital clock display: prints preceding colon and leading 0 54 | Serial.print(":"); 55 | if(digits < 10) 56 | Serial.print('0'); 57 | Serial.print(digits); 58 | } 59 | 60 | /* code to process time sync messages from the serial port */ 61 | #define TIME_HEADER "T" // Header tag for serial time sync message 62 | 63 | unsigned long processSyncMessage() { 64 | unsigned long pctime = 0L; 65 | const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 66 | 67 | if(Serial.find(TIME_HEADER)) { 68 | pctime = Serial.parseInt(); 69 | return pctime; 70 | if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013) 71 | pctime = 0L; // return 0 to indicate that the time is not valid 72 | } 73 | } 74 | return pctime; 75 | } 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/TimeSerial/TimeSerial.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeSerial.pde 3 | * example code illustrating Time library set through serial port messages. 4 | * 5 | * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970) 6 | * you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013 7 | T1357041600 8 | * 9 | * A Processing example sketch to automatically send the messages is included in the download 10 | * On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone) 11 | */ 12 | 13 | #include 14 | 15 | #define TIME_HEADER "T" // Header tag for serial time sync message 16 | #define TIME_REQUEST 7 // ASCII bell character requests a time sync message 17 | 18 | void setup() { 19 | Serial.begin(9600); 20 | while (!Serial) ; // Needed for Leonardo only 21 | pinMode(13, OUTPUT); 22 | setSyncProvider( requestSync); //set function to call when sync required 23 | Serial.println("Waiting for sync message"); 24 | } 25 | 26 | void loop(){ 27 | if (Serial.available()) { 28 | processSyncMessage(); 29 | } 30 | if (timeStatus()!= timeNotSet) { 31 | digitalClockDisplay(); 32 | } 33 | if (timeStatus() == timeSet) { 34 | digitalWrite(13, HIGH); // LED on if synced 35 | } else { 36 | digitalWrite(13, LOW); // LED off if needs refresh 37 | } 38 | delay(1000); 39 | } 40 | 41 | void digitalClockDisplay(){ 42 | // digital clock display of the time 43 | Serial.print(hour()); 44 | printDigits(minute()); 45 | printDigits(second()); 46 | Serial.print(" "); 47 | Serial.print(day()); 48 | Serial.print(" "); 49 | Serial.print(month()); 50 | Serial.print(" "); 51 | Serial.print(year()); 52 | Serial.println(); 53 | } 54 | 55 | void printDigits(int digits){ 56 | // utility function for digital clock display: prints preceding colon and leading 0 57 | Serial.print(":"); 58 | if(digits < 10) 59 | Serial.print('0'); 60 | Serial.print(digits); 61 | } 62 | 63 | 64 | void processSyncMessage() { 65 | unsigned long pctime; 66 | const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 67 | 68 | if(Serial.find(TIME_HEADER)) { 69 | pctime = Serial.parseInt(); 70 | if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013) 71 | setTime(pctime); // Sync Arduino clock to the time received on the serial port 72 | } 73 | } 74 | } 75 | 76 | time_t requestSync() 77 | { 78 | Serial.write(TIME_REQUEST); 79 | return 0; // the time will be sent later in response to serial mesg 80 | } 81 | 82 | -------------------------------------------------------------------------------- /examples/TimeSerialDateStrings/TimeSerialDateStrings.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeSerialDateStrings.pde 3 | * example code illustrating Time library date strings 4 | * 5 | * This sketch adds date string functionality to TimeSerial sketch 6 | * Also shows how to handle different messages 7 | * 8 | * A message starting with a time header sets the time 9 | * A Processing example sketch to automatically send the messages is inclided in the download 10 | * On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone) 11 | * 12 | * A message starting with a format header sets the date format 13 | 14 | * send: Fs\n for short date format 15 | * send: Fl\n for long date format 16 | */ 17 | 18 | #include 19 | 20 | // single character message tags 21 | #define TIME_HEADER 'T' // Header tag for serial time sync message 22 | #define FORMAT_HEADER 'F' // Header tag indicating a date format message 23 | #define FORMAT_SHORT 's' // short month and day strings 24 | #define FORMAT_LONG 'l' // (lower case l) long month and day strings 25 | 26 | #define TIME_REQUEST 7 // ASCII bell character requests a time sync message 27 | 28 | static boolean isLongFormat = true; 29 | 30 | void setup() { 31 | Serial.begin(9600); 32 | while (!Serial) ; // Needed for Leonardo only 33 | setSyncProvider( requestSync); //set function to call when sync required 34 | Serial.println("Waiting for sync message"); 35 | } 36 | 37 | void loop(){ 38 | if (Serial.available() > 1) { // wait for at least two characters 39 | char c = Serial.read(); 40 | if( c == TIME_HEADER) { 41 | processSyncMessage(); 42 | } 43 | else if( c== FORMAT_HEADER) { 44 | processFormatMessage(); 45 | } 46 | } 47 | if (timeStatus()!= timeNotSet) { 48 | digitalClockDisplay(); 49 | } 50 | delay(1000); 51 | } 52 | 53 | void digitalClockDisplay() { 54 | // digital clock display of the time 55 | Serial.print(hour()); 56 | printDigits(minute()); 57 | printDigits(second()); 58 | Serial.print(" "); 59 | if(isLongFormat) 60 | Serial.print(dayStr(weekday())); 61 | else 62 | Serial.print(dayShortStr(weekday())); 63 | Serial.print(" "); 64 | Serial.print(day()); 65 | Serial.print(" "); 66 | if(isLongFormat) 67 | Serial.print(monthStr(month())); 68 | else 69 | Serial.print(monthShortStr(month())); 70 | Serial.print(" "); 71 | Serial.print(year()); 72 | Serial.println(); 73 | } 74 | 75 | void printDigits(int digits) { 76 | // utility function for digital clock display: prints preceding colon and leading 0 77 | Serial.print(":"); 78 | if(digits < 10) 79 | Serial.print('0'); 80 | Serial.print(digits); 81 | } 82 | 83 | void processFormatMessage() { 84 | char c = Serial.read(); 85 | if( c == FORMAT_LONG){ 86 | isLongFormat = true; 87 | Serial.println(F("Setting long format")); 88 | } 89 | else if( c == FORMAT_SHORT) { 90 | isLongFormat = false; 91 | Serial.println(F("Setting short format")); 92 | } 93 | } 94 | 95 | void processSyncMessage() { 96 | unsigned long pctime; 97 | const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 - paul, perhaps we define in time.h? 98 | 99 | pctime = Serial.parseInt(); 100 | if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013) 101 | setTime(pctime); // Sync Arduino clock to the time received on the serial port 102 | } 103 | } 104 | 105 | time_t requestSync() { 106 | Serial.write(TIME_REQUEST); 107 | return 0; // the time will be sent later in response to serial mesg 108 | } 109 | -------------------------------------------------------------------------------- /examples/TimeTeensy3/TimeTeensy3.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TimeRTC.pde 3 | * example code illustrating Time library with Real Time Clock. 4 | * 5 | */ 6 | 7 | #include 8 | 9 | void setup() { 10 | // set the Time library to use Teensy 3.0's RTC to keep time 11 | setSyncProvider(getTeensy3Time); 12 | 13 | Serial.begin(115200); 14 | while (!Serial); // Wait for Arduino Serial Monitor to open 15 | delay(100); 16 | if (timeStatus()!= timeSet) { 17 | Serial.println("Unable to sync with the RTC"); 18 | } else { 19 | Serial.println("RTC has set the system time"); 20 | } 21 | } 22 | 23 | void loop() { 24 | if (Serial.available()) { 25 | time_t t = processSyncMessage(); 26 | if (t != 0) { 27 | Teensy3Clock.set(t); // set the RTC 28 | setTime(t); 29 | } 30 | } 31 | digitalClockDisplay(); 32 | delay(1000); 33 | } 34 | 35 | void digitalClockDisplay() { 36 | // digital clock display of the time 37 | Serial.print(hour()); 38 | printDigits(minute()); 39 | printDigits(second()); 40 | Serial.print(" "); 41 | Serial.print(day()); 42 | Serial.print(" "); 43 | Serial.print(month()); 44 | Serial.print(" "); 45 | Serial.print(year()); 46 | Serial.println(); 47 | } 48 | 49 | time_t getTeensy3Time() 50 | { 51 | return Teensy3Clock.get(); 52 | } 53 | 54 | /* code to process time sync messages from the serial port */ 55 | #define TIME_HEADER "T" // Header tag for serial time sync message 56 | 57 | unsigned long processSyncMessage() { 58 | unsigned long pctime = 0L; 59 | const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 60 | 61 | if(Serial.find(TIME_HEADER)) { 62 | pctime = Serial.parseInt(); 63 | return pctime; 64 | if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013) 65 | pctime = 0L; // return 0 to indicate that the time is not valid 66 | } 67 | } 68 | return pctime; 69 | } 70 | 71 | void printDigits(int digits){ 72 | // utility function for digital clock display: prints preceding colon and leading 0 73 | Serial.print(":"); 74 | if(digits < 10) 75 | Serial.print('0'); 76 | Serial.print(digits); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Time 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | time_t KEYWORD1 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | now KEYWORD2 13 | second KEYWORD2 14 | minute KEYWORD2 15 | hour KEYWORD2 16 | day KEYWORD2 17 | month KEYWORD2 18 | year KEYWORD2 19 | isAM KEYWORD2 20 | isPM KEYWORD2 21 | weekday KEYWORD2 22 | setTime KEYWORD2 23 | adjustTime KEYWORD2 24 | setSyncProvider KEYWORD2 25 | setSyncInterval KEYWORD2 26 | timeStatus KEYWORD2 27 | TimeLib KEYWORD2 28 | ####################################### 29 | # Instances (KEYWORD2) 30 | ####################################### 31 | 32 | ####################################### 33 | # Constants (LITERAL1) 34 | ####################################### 35 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Time", 3 | "description": "Time keeping library", 4 | "keywords": "Time, date, hour, minute, second, day, week, month, year, RTC", 5 | "authors": [ 6 | { 7 | "name": "Michael Margolis" 8 | }, 9 | { 10 | "name": "Paul Stoffregen", 11 | "email": "paul@pjrc.com", 12 | "url": "http://www.pjrc.com", 13 | "maintainer": true 14 | } 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/PaulStoffregen/Time" 19 | }, 20 | "version": "1.6.1", 21 | "homepage": "http://playground.arduino.cc/Code/Time", 22 | "frameworks": "Arduino", 23 | "examples": [ 24 | "examples/*/*.ino" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Time 2 | version=1.6.1 3 | author=Michael Margolis 4 | maintainer=Paul Stoffregen 5 | sentence=Timekeeping functionality for Arduino 6 | paragraph=Date and Time functions, with provisions to synchronize to external time sources like GPS and NTP (Internet). This library is often used together with TimeAlarms and DS1307RTC. 7 | category=Timing 8 | url=http://playground.arduino.cc/Code/Time/ 9 | includes=TimeLib.h 10 | architectures=* 11 | 12 | --------------------------------------------------------------------------------