// Code by JeeLabs http://news.jeelabs.org/code/ // Extended by Fabio Cuomo https://github.com/FabioCuomo/FabioCuomo-DS3231/ // 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 DS3231_TEMP 0x11 #define SECONDS_PER_DAY 86400L #define SECONDS_FROM_1970_TO_2000 946684800 //Control register bits #define A1IE 0 #define A2IE 1 //Alarm mask bits #define A1M1 7 #define A1M2 7 #define A1M3 7 #define A1M4 7 #define A2M2 7 #define A2M3 7 #define A2M4 7 //DS3232 Register Addresses #define ALM1_SECONDS 0x07 #define ALM1_MINUTES 0x08 #define ALM1_HOURS 0x09 #define ALM1_DAYDATE 0x0A #define ALM2_MINUTES 0x0B #define ALM2_HOURS 0x0C #define ALM2_DAYDATE 0x0D //Other #define DYDT 6 //Day/Date flag bit in alarm Day/Date registers // 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 }; //Alarm masks enum Ds3231_ALARM_TYPES_t { ALM1_EVERY_SECOND = 0x0F, ALM1_MATCH_SECONDS = 0x0E, ALM1_MATCH_MINUTES = 0x0C, //match minutes *and* seconds ALM1_MATCH_HOURS = 0x08, //match hours *and* minutes, seconds ALM1_MATCH_DATE = 0x00, //match date *and* hours, minutes, seconds ALM1_MATCH_DAY = 0x10, //match day *and* hours, minutes, seconds ALM2_EVERY_MINUTE = 0x8E, ALM2_MATCH_MINUTES = 0x8C, //match minutes ALM2_MATCH_HOURS = 0x88, //match hours *and* minutes ALM2_MATCH_DATE = 0x80, //match date *and* hours, minutes ALM2_MATCH_DAY = 0x90, //match day *and* hours, minutes }; 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); float getTemp(); void setAlarm(Ds3231_ALARM_TYPES_t alarmType, byte seconds, byte minutes, byte hours, byte daydate); void setAlarm(Ds3231_ALARM_TYPES_t alarmType, byte minutes, byte hours, byte daydate); void armAlarm(byte alarmNumber, bool armed); void alarmInterrupt(byte alarmNumber, bool alarmEnabled); bool isArmed(byte alarmNumber); void clearAlarm(byte alarmNumber); }; // 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_