DS3231 Real-Time-Clock, Temperature Sensor, and I2C (AT24C32) EEPROM Data Logger
A simple library to control a DS3231 and AT24C32 Module from an Arduino.
DS3231_Simple Class Reference

Simple DS3231 RTC and AT24C32 EEPROM Library. More...

#include <DS3231_Simple.h>

Classes

struct  DateTime
 

Public Member Functions

void begin ()
 Initialize.
 
DateTime read ()
 Read the current date and time, returning a structure containing that information.
 
uint8_t write (const DateTime &)
 Set the date and time from the settings in the given structure. More...
 
void promptForTimeAndDate (Stream &Serial)
 
uint8_t setAlarm (const DateTime &AlarmTime, uint8_t AlarmMode)
 Sets an alarm, the alarm will pull the SQW pin low (you can monitor with an interrupt). More...
 
uint8_t setAlarm (uint8_t AlarmMode)
 Set an alarm using the current date/time as it's basis. More...
 
uint8_t disableAlarms ()
 Disable any existing alarm settings. More...
 
uint8_t checkAlarms (uint8_t PauseClock=false)
 Determine if an alarm has triggered, also clears the alarm if so. More...
 
uint8_t getTemperature ()
 Get the temperature accurate to within 1 degree (C) More...
 
float getTemperatureFloat ()
 Get the temprature accurate to within 0.25 degrees (C) More...
 
void printTo (Stream &Printer)
 Print the current DateTime structure in ISO8601 Format. More...
 
void printTo (Stream &Printer, const DateTime &Timestamp)
 Print the given DateTime structure in ISO8601 Format. More...
 
void printDateTo_DMY (Stream &Printer, const DateTime &Timestamp, const char separator= '/')
 Print the date portion of the given DateTime structure in DD/MM/YYYY format.
 
void printDateTo_DMY (Stream &Printer)
 Print the date portion of the current DateTime structure in DD/MM/YYYY format.
 
void printDateTo_MDY (Stream &Printer, const DateTime &Timestamp, const char separator= '/')
 Print the date portion of the given DateTime structure in MM/DD/YYYY format.
 
void printDateTo_MDY (Stream &Printer)
 Print the date portion of the current DateTime structure in MM/DD/YYYY format.
 
void printDateTo_YMD (Stream &Printer, const DateTime &Timestamp, const char separator= '-')
 Print the date portion of the given DateTime structure in YYYY-MM-DD format.
 
void printDateTo_YMD (Stream &Printer)
 Print the date portion of the current DateTime structure in YYYY-MM-DD format.
 
void printTimeTo_HMS (Stream &Printer, const DateTime &Timestamp, const char hoursToMinutesSeparator= ':', const char minutesToSecondsSeparator= ':')
 Print the time portion of the given DateTime structure in HH:MM:SS format (24 Hour Clock) More...
 
void printTimeTo_HMS (Stream &Printer)
 Print the time portion of the current DateTime structure in HH:MM:SS format (24 Hour Clock) More...
 
void printTimeTo_HM (Stream &Printer, const DateTime &Timestamp, const char hoursToMinutesSeparator= ':')
 Print the time portion of the given DateTime structure in HH:MM format (24 Hour Clock) More...
 
void printTimeTo_HM (Stream &Printer)
 Print the time portion of the current DateTime structure in HH:MM format (24 Hour Clock) More...
 
void print12HourTimeTo_HMS (Stream &Printer, const DateTime &Timestamp, const char hoursToMinutesSeparator= ':', const char minutesToSecondsSeparator= ':')
 Print the time portion of the given DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock) More...
 
void print12HourTimeTo_HMS (Stream &Printer)
 Print the time portion of the current DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock) More...
 
void print12HourTimeTo_HM (Stream &Printer, const DateTime &Timestamp, const char hoursToMinutesSeparator= ':')
 Print the time portion of the given DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock) More...
 
void print12HourTimeTo_HM (Stream &Printer)
 Print the time portion of the current DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock) More...
 
uint8_t formatEEPROM ()
 Erase the EEPROM ready for storing log entries. More...
 
template<typename datatype >
uint8_t writeLog (const datatype &data)
 Write a log entry to the EEPROM, having current timestamp, with an attached data of arbitrary datatype (7 bytes max). More...
 
template<typename datatype >
uint8_t writeLog (const DateTime &timestamp, const datatype &data)
 Write a log entry to the EEPROM, having supplied timestamp, with an attached data of arbitrary datatype (7 bytes max). More...
 
uint8_t writeLog (const DateTime &timestamp, const uint8_t *data, uint8_t size=1)
 Write a log entry to the EEPROM, having supplied timestamp, with an attached data. More...
 
template<typename datatype >
uint8_t readLog (DateTime &timestamp, datatype &data)
 Read the oldest log entry and clear it from EEPROM. More...
 
uint8_t readLog (DateTime &timestamp, uint8_t *data, uint8_t size=1)
 Read the oldest log entry and clear it from EEPROM. More...
 
int8_t compareTimestamps (const DateTime &A, const DateTime &B)
 Compare two DateTime objects to determine which one is older. More...
 

Static Public Attributes

static const uint8_t ALARM_EVERY_SECOND = 0B11110001
 
static const uint8_t ALARM_MATCH_SECOND = 0B01110001
 
static const uint8_t ALARM_MATCH_SECOND_MINUTE = 0B00110001
 
static const uint8_t ALARM_MATCH_SECOND_MINUTE_HOUR = 0B00010001
 
static const uint8_t ALARM_MATCH_SECOND_MINUTE_HOUR_DATE = 0B00000001
 
static const uint8_t ALARM_MATCH_SECOND_MINUTE_HOUR_DOW = 0B00001001
 
static const uint8_t ALARM_EVERY_MINUTE = 0B01110010
 
static const uint8_t ALARM_MATCH_MINUTE = 0B00110010
 
static const uint8_t ALARM_MATCH_MINUTE_HOUR = 0B00010010
 
static const uint8_t ALARM_MATCH_MINUTE_HOUR_DATE = 0B00000010
 
static const uint8_t ALARM_MATCH_MINUTE_HOUR_DOW = 0B00001010
 
static const uint8_t ALARM_HOURLY = 0B00110011
 
static const uint8_t ALARM_DAILY = 0B00010011
 
static const uint8_t ALARM_WEEKLY = 0B00001011
 
static const uint8_t ALARM_MONTHLY = 0B00000011
 

Protected Member Functions

uint16_t findEEPROMWriteAddress ()
 Searches the EEPROM for the next place to store a block, sets eepromWriteAddress. More...
 
uint8_t makeEEPROMSpace (uint16_t Address, int8_t BytesRequired)
 Delete enough complete blocks to have enough free space for the given required number of bytes. More...
 
uint16_t findEEPROMReadAddress ()
 Find the oldest block to read (based on timestamp date), set eepromReadAddress. More...
 
uint16_t readLogFrom (uint16_t Address, DateTime &timestamp, uint8_t *data, uint8_t size=0)
 Read log timestamp and data from a given EEPROM address. More...
 
uint8_t writeBytePagewizeStart ()
 Start a "pagewize" write at the eepromWriteAddress. More...
 
uint8_t writeBytePagewize (const uint8_t data)
 Write a byte during a pagewize operation. More...
 
uint8_t writeBytePagewizeEnd ()
 End a pagewize write operation. More...
 
uint8_t readEEPROMByte (const uint16_t Address)
 Read a byte from the EEPROM. More...
 

Static Protected Member Functions

static uint8_t bcd2bin (uint8_t binaryRepresentation)
 
static uint8_t bin2bcd (uint8_t bcdRepresentation)
 
static uint8_t rtc_i2c_seek (const uint8_t Address)
 
static uint8_t rtc_i2c_write_byte (const uint8_t Address, const uint8_t Byte)
 
static uint8_t rtc_i2c_read_byte (const uint8_t Address, uint8_t &Byte)
 
static void print_zero_padded (Stream &Printer, uint8_t x)
 

Protected Attributes

uint16_t eepromWriteAddress = EEPROM_BYTES
 
uint16_t eepromReadAddress = EEPROM_BYTES
 

Static Protected Attributes

static const uint8_t RTC_ADDRESS = 0x68
 
static const uint8_t EEPROM_ADDRESS = 0x57
 
static const uint16_t EEPROM_SIZE_KBIT = 32768
 
static const uint8_t EEPROM_PAGE_SIZE = 32
 
static const uint16_t EEPROM_BYTES = EEPROM_SIZE_KBIT/8
 
static const uint8_t EEPROM_PAGES = EEPROM_BYTES/EEPROM_PAGE_SIZE
 

Detailed Description

Simple DS3231 RTC and AT24C32 EEPROM Library.

Implements a simple interface to read/set the clock and alarms of an DS3231 Real Time Clock, and also to utilise an often-companion AT24C32 EEPROM as a data logging storage for generic timestamped data.

Copyright (C) 2016 James Sleeman

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Author
James Sleeman, http://sparks.gogo.co.nz/ MIT License

Member Function Documentation

uint8_t DS3231_Simple::checkAlarms ( uint8_t  PauseClock = false)

Determine if an alarm has triggered, also clears the alarm if so.

If you do not pause the clock then be aware that there is a small chance that you may miss an alarm between the very short time that the alarms are checked and then cleared (ie, if an alarm is checked and is 0, and before we clear it, the alarm is triggered, but then we go and clear it).

If you pause the clock, then this won't happen, but your time keeping will not be so accurate because every time you check the alarm you will "get behind" a small amount.

Returns
0 For no alarm, 1 for Alarm 1, 2 for Alarm 2, and 3 for Both Alarms
int8_t DS3231_Simple::compareTimestamps ( const DateTime A,
const DateTime B 
)

Compare two DateTime objects to determine which one is older.

If A is older than B return -1 If A is equal to B return 0 If A is newer than B return 1

Returns
-1, 0 or 1
uint8_t DS3231_Simple::disableAlarms ( )

Disable any existing alarm settings.

Returns
Success True/False
uint16_t DS3231_Simple::findEEPROMReadAddress ( )
protected

Find the oldest block to read (based on timestamp date), set eepromReadAddress.

Note: Has to search entire EEPROM, slow.

Returns
eepromReadAddress
uint16_t DS3231_Simple::findEEPROMWriteAddress ( )
protected

Searches the EEPROM for the next place to store a block, sets eepromWriteAddress.

Returns
eepromWriteAddress
uint8_t DS3231_Simple::formatEEPROM ( )

Erase the EEPROM ready for storing log entries.

uint8_t DS3231_Simple::getTemperature ( )

Get the temperature accurate to within 1 degree (C)

float DS3231_Simple::getTemperatureFloat ( )

Get the temprature accurate to within 0.25 degrees (C)

uint8_t DS3231_Simple::makeEEPROMSpace ( uint16_t  Address,
int8_t  BytesRequired 
)
protected

Delete enough complete blocks to have enough free space for the given required number of bytes.

Returns
True/False for success/fail
void DS3231_Simple::print12HourTimeTo_HM ( Stream &  Printer,
const DateTime Timestamp,
const char  hoursToMinutesSeparator = ':' 
)

Print the time portion of the given DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock)

void DS3231_Simple::print12HourTimeTo_HM ( Stream &  Printer)
inline

Print the time portion of the current DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock)

void DS3231_Simple::print12HourTimeTo_HMS ( Stream &  Printer,
const DateTime Timestamp,
const char  hoursToMinutesSeparator = ':',
const char  minutesToSecondsSeparator = ':' 
)

Print the time portion of the given DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock)

void DS3231_Simple::print12HourTimeTo_HMS ( Stream &  Printer)
inline

Print the time portion of the current DateTime structure in HH:MM:SS [AM/PM] format (12 Hour Clock)

void DS3231_Simple::printTimeTo_HM ( Stream &  Printer,
const DateTime Timestamp,
const char  hoursToMinutesSeparator = ':' 
)

Print the time portion of the given DateTime structure in HH:MM format (24 Hour Clock)

void DS3231_Simple::printTimeTo_HM ( Stream &  Printer)
inline

Print the time portion of the current DateTime structure in HH:MM format (24 Hour Clock)

void DS3231_Simple::printTimeTo_HMS ( Stream &  Printer,
const DateTime Timestamp,
const char  hoursToMinutesSeparator = ':',
const char  minutesToSecondsSeparator = ':' 
)

Print the time portion of the given DateTime structure in HH:MM:SS format (24 Hour Clock)

void DS3231_Simple::printTimeTo_HMS ( Stream &  Printer)
inline

Print the time portion of the current DateTime structure in HH:MM:SS format (24 Hour Clock)

void DS3231_Simple::printTo ( Stream &  Printer)

Print the current DateTime structure in ISO8601 Format.

YYYY-MM-DDThh:mm:ss

https://www.w3.org/TR/NOTE-datetime

Example: Clock.printTo(Serial);

void DS3231_Simple::printTo ( Stream &  Printer,
const DateTime Timestamp 
)

Print the given DateTime structure in ISO8601 Format.

YYYY-MM-DDThh:mm:ss

https://www.w3.org/TR/NOTE-datetime

Example: Clock.printTo(Serial, MyDateAndTimeVaraible);

uint8_t DS3231_Simple::readEEPROMByte ( const uint16_t  Address)
protected

Read a byte from the EEPROM.

Parameters
AddressThe address of the EEPROM to read from.
Returns
The data byte read.
Note
There is limited error checking, if you provide an invalid address, or the EEPROM is not responding etc behaviour is undefined (return 0, return 1, might or might not block...).
template<typename datatype >
uint8_t DS3231_Simple::readLog ( DateTime timestamp,
datatype &  data 
)
inline

Read the oldest log entry and clear it from EEPROM.

Parameters
timestampVariable to put the timestamp of the log into.
dataVariable to put the data.
Note
No check is made as to if the type of "data" and the type of the data which is read is the same, there is nothing to stop you doing "writeLog( myFloat );" and subsequently "readLog( myInt );" but if you do so, results are going to be not what you expect!
uint8_t DS3231_Simple::readLog ( DateTime timestamp,
uint8_t *  data,
uint8_t  size = 1 
)

Read the oldest log entry and clear it from EEPROM.

Parameters
timestampVariable to put the timestamp of the log into.
dataPointer to buffer to put data associated with the log.
sizeSize of the data buffer. Maximum 7 bytes.
Note
If the data in the log entry is larger than the buffer, it will be truncated.
uint16_t DS3231_Simple::readLogFrom ( uint16_t  Address,
DateTime timestamp,
uint8_t *  data,
uint8_t  size = 0 
)
protected

Read log timestamp and data from a given EEPROM address.

Parameters
AddressByte address of log block
timestampDateTime structure to put the timestamp
dataMemory location to put the data associated with the log
sizeMax size of the data to read (any more is discarded)
uint8_t DS3231_Simple::setAlarm ( const DateTime AlarmTime,
uint8_t  AlarmMode 
)

Sets an alarm, the alarm will pull the SQW pin low (you can monitor with an interrupt).

Parameters
Thedate/time for the alarm, as appropriate for the alarm mode (example, for ALARM_MATCH_SECOND then AlarmTime.Second will be the matching criteria).
Themode of the alarm, from the following...

ALARM_EVERY_SECOND ALARM_MATCH_SECOND ALARM_MATCH_SECOND_MINUTE ALARM_MATCH_SECOND_MINUTE_HOUR ALARM_MATCH_SECOND_MINUTE_HOUR_DATE ALARM_MATCH_SECOND_MINUTE_HOUR_DOW

ALARM_EVERY_MINUTE ALARM_MATCH_MINUTE ALARM_MATCH_MINUTE_HOUR ALARM_MATCH_MINUTE_HOUR_DATE ALARM_MATCH_MINUTE_HOUR_DOW

ALARM_HOURLY ALARM_DAILY ALARM_WEEKLY ALARM_MONTHLY

uint8_t DS3231_Simple::setAlarm ( uint8_t  AlarmMode)

Set an alarm using the current date/time as it's basis.

Just a convenience function.

Parameters
Themode of the alarm, from the following...

ALARM_EVERY_SECOND ALARM_MATCH_SECOND ALARM_MATCH_SECOND_MINUTE ALARM_MATCH_SECOND_MINUTE_HOUR ALARM_MATCH_SECOND_MINUTE_HOUR_DATE ALARM_MATCH_SECOND_MINUTE_HOUR_DOW

ALARM_EVERY_MINUTE ALARM_MATCH_MINUTE ALARM_MATCH_MINUTE_HOUR ALARM_MATCH_MINUTE_HOUR_DATE ALARM_MATCH_MINUTE_HOUR_DOW

ALARM_HOURLY ALARM_DAILY ALARM_WEEKLY ALARM_MONTHLY

uint8_t DS3231_Simple::write ( const DateTime currentDate)

Set the date and time from the settings in the given structure.

Parameters
Thedate/time
uint8_t DS3231_Simple::writeBytePagewize ( const uint8_t  data)
protected

Write a byte during a pagewize operation.

Note that this function increments the eepromWriteAddress.

Parameters
dataByte to write.
See also
DS3231::writeBytePagewizeStart()
Returns
Success (boolean) 1/0, presently this method always reports success.
uint8_t DS3231_Simple::writeBytePagewizeEnd ( )
protected

End a pagewize write operation.

See also
DS3231::writeBytePagewizeStart()
Returns
Success (boolean) 1/0, this method will return 0 if Wire.endTransmission reports an error.
uint8_t DS3231_Simple::writeBytePagewizeStart ( )
protected

Start a "pagewize" write at the eepromWriteAddress.

Follow this call with 1 or more calls to writeBytePagewize() Finish with a call to writeBytePagewizeEnd()

Writes in the same page (or rather, 16 byte sections of a page) are performed as a single write, thence a new write is started for the next section.

This solves 2 problems, first the 32 byte Wire buffer which isn't large enough for a whole page of bytes plus the address bytes. Second the fact that the EEPROM loops back to the start of page when you run off the end of the page while writing (instead of to the start of the next page).

Note that you must not modify the eepromWriteAddress between a writeBytePagewizeStart() and a writeBytePagewizeEnd() or it's all going to get out of kilter.

Returns
Success (boolean) 1/0, presently this method always reports success.
template<typename datatype >
uint8_t DS3231_Simple::writeLog ( const datatype &  data)
inline

Write a log entry to the EEPROM, having current timestamp, with an attached data of arbitrary datatype (7 bytes max).

This method allows you to record a "log entry" which you can later retrieve.

The full timestamp is recorded along with one piece of data. The type of data you provide is up to you, as long as your data is less than 7 bytes (byte, int, float, char, or a 6 character string would all be fine).

To store more than one piece of data in a log, use a struct, again, in total your structure needs to occupy 7 bytes or less of memory.

Examples: Clock.writeLog(analogRead(A0)); Clock.writeLog( MyTimeAndDate, MyFloatVariable );

// Remember, 7 bytes max! struct MyDataStructure { unsigned int AnalogValue1; unsigned int AnalogValue2; }; MyDataStructure MyData; MyData.AnalogValue1 = 123; MyData.AnalogValue2 = 456; Clock.writeLog(MyDataStructure);

Parameters
dataThe data to store, any arbitrary scalar or structur datatype consisting not more than 7 bytes.
Note
To store a string or other pointer contents, you probably want to use DS3231::writeLog(const DateTime, const uint8_t *data, uint8_t size)
template<typename datatype >
uint8_t DS3231_Simple::writeLog ( const DateTime timestamp,
const datatype &  data 
)
inline

Write a log entry to the EEPROM, having supplied timestamp, with an attached data of arbitrary datatype (7 bytes max).

See also
DS3231::writeLog(const datatype & data)
Parameters
timestampThe timestamp to associate with the log entry.
dataThe data to store, any arbitrary datatype consisting not more than 7 bytes.
uint8_t DS3231_Simple::writeLog ( const DateTime timestamp,
const uint8_t *  data,
uint8_t  size = 1 
)

Write a log entry to the EEPROM, having supplied timestamp, with an attached data.

Parameters
timestampThe timestamp to associate with the log entry.
dataPointer to the data to store
sizeLength of data to store - max length is 7 bytes, this is not checked for compliance!

The documentation for this class was generated from the following files: