// Code by JeeLabs http://news.jeelabs.org/code/ // Released to the public domain! Enjoy! #ifndef _RTCLIB_H_ #define _RTCLIB_H_ #include class TimeSpan; #define PCF8523_ADDRESS 0x68 #define PCF8523_CLKOUTCONTROL 0x0F #define PCF8523_CONTROL_3 0x02 #define DS1307_ADDRESS 0x68 #define DS1307_CONTROL 0x07 #define DS1307_NVRAM 0x08 #define DS3231_ADDRESS 0x68 #define DS3231_CONTROL 0x0E #define DS3231_STATUSREG 0x0F #define SECONDS_PER_DAY 86400L #define SECONDS_FROM_1970_TO_2000 946684800 // Simple general-purpose date/time class (no TZ / DST / leap second handling!) class DateTime { public: DateTime (uint32_t t =0); DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour =0, uint8_t min =0, uint8_t sec =0); DateTime (const DateTime& copy); DateTime (const char* date, const char* time); DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time); uint16_t year() const { return 2000 + yOff; } uint8_t month() const { return m; } uint8_t day() const { return d; } uint8_t hour() const { return hh; } uint8_t minute() const { return mm; } uint8_t second() const { return ss; } uint8_t dayOfTheWeek() const; // 32-bit times as seconds since 1/1/2000 long secondstime() const; // 32-bit times as seconds since 1/1/1970 uint32_t unixtime(void) const; DateTime operator+(const TimeSpan& span); DateTime operator-(const TimeSpan& span); TimeSpan operator-(const DateTime& right); protected: uint8_t yOff, m, d, hh, mm, ss; }; // Timespan which can represent changes in time with seconds accuracy. class TimeSpan { public: TimeSpan (int32_t seconds = 0); TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds); TimeSpan (const TimeSpan& copy); int16_t days() const { return _seconds / 86400L; } int8_t hours() const { return _seconds / 3600 % 24; } int8_t minutes() const { return _seconds / 60 % 60; } int8_t seconds() const { return _seconds % 60; } int32_t totalseconds() const { return _seconds; } TimeSpan operator+(const TimeSpan& right); TimeSpan operator-(const TimeSpan& right); protected: int32_t _seconds; }; // RTC based on the DS1307 chip connected via I2C and the Wire library enum Ds1307SqwPinMode { OFF = 0x00, ON = 0x80, SquareWave1HZ = 0x10, SquareWave4kHz = 0x11, SquareWave8kHz = 0x12, SquareWave32kHz = 0x13 }; class RTC_DS1307 { public: boolean begin(void); static void adjust(const DateTime& dt); uint8_t isrunning(void); static DateTime now(); static Ds1307SqwPinMode readSqwPinMode(); static void writeSqwPinMode(Ds1307SqwPinMode mode); uint8_t readnvram(uint8_t address); void readnvram(uint8_t* buf, uint8_t size, uint8_t address); void writenvram(uint8_t address, uint8_t data); void writenvram(uint8_t address, uint8_t* buf, uint8_t size); }; // RTC based on the DS3231 chip connected via I2C and the Wire library enum Ds3231SqwPinMode { DS3231_OFF = 0x01, DS3231_SquareWave1Hz = 0x00, DS3231_SquareWave1kHz = 0x08, DS3231_SquareWave4kHz = 0x10, DS3231_SquareWave8kHz = 0x18 }; class RTC_DS3231 { public: boolean begin(void); static void adjust(const DateTime& dt); bool lostPower(void); static DateTime now(); static Ds3231SqwPinMode readSqwPinMode(); static void writeSqwPinMode(Ds3231SqwPinMode mode); }; // RTC based on the PCF8523 chip connected via I2C and the Wire library enum Pcf8523SqwPinMode { PCF8523_OFF = 7, PCF8523_SquareWave1HZ = 6, PCF8523_SquareWave32HZ = 5, PCF8523_SquareWave1kHz = 4, PCF8523_SquareWave4kHz = 3, PCF8523_SquareWave8kHz = 2, PCF8523_SquareWave16kHz = 1, PCF8523_SquareWave32kHz = 0 }; class RTC_PCF8523 { public: boolean begin(void); void adjust(const DateTime& dt); boolean initialized(void); static DateTime now(); Pcf8523SqwPinMode readSqwPinMode(); void writeSqwPinMode(Pcf8523SqwPinMode mode); }; // RTC using the internal millis() clock, has to be initialized before use // NOTE: this clock won't be correct once the millis() timer rolls over (>49d?) class RTC_Millis { public: static void begin(const DateTime& dt) { adjust(dt); } static void adjust(const DateTime& dt); static DateTime now(); protected: static long offset; }; #endif // _RTCLIB_H_