Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Incorporated DS3231 (Chronodot), DS3234 functions from Coobro

  • Loading branch information...
commit 6969a8affcd920bda9099863ec42b97715ee9187 1 parent 8b0c6e0
@MrAlvin authored
View
530 RTClib.cpp
@@ -2,10 +2,13 @@
// Released to the public domain! Enjoy!
#include <Wire.h>
+#include <SPI.h> // used by DS3234
#include <avr/pgmspace.h>
#include "RTClib.h"
#define DS1307_ADDRESS 0x68
+#define DS3231_ADDRESS 0x68
+
#define SECONDS_PER_DAY 86400L
#define SECONDS_FROM_1970_TO_2000 946684800
@@ -125,15 +128,37 @@ uint32_t DateTime::unixtime(void) const {
}
////////////////////////////////////////////////////////////////////////////////
-// RTC_DS1307 implementation
+// By Coobro
+const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
-static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }
+// as a string
+char* DateTime::toString(char* buf, int maxlen) const
+{
+ snprintf(buf,maxlen,"%s %02u %04u %02u:%02u:%02u",
+ months[m-1],
+ d,
+ 2000 + yOff,
+ hh,
+ mm,
+ ss
+ );
+ return buf;
+}
-uint8_t RTC_DS1307::begin(void) {
- return 1;
+void DateTime::operator+=(uint32_t additional)
+{
+ DateTime after = DateTime( unixtime() + additional );
+ *this = after;
}
+///////////////////////////////////////////////////////////////////////////////
+// BCD conversion tools
+
+static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
+static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }
+
+///////////////////////////////////////////////////////////////////////////////
+// Arduino 1.0 addition
#if (ARDUINO >= 100)
#define WW_ Wire.write
@@ -141,8 +166,25 @@ uint8_t RTC_DS1307::begin(void) {
#else
#define WW_ Wire.send
#define WR_ Wire.receive
+#endif
+
+#if ARDUINO < 100
+#define SEND(x) send(x)
+#define RECEIVE(x) receive(x)
+#else
+#define SEND(x) write(static_cast<uint8_t>(x))
+#define RECEIVE(x) read(x)
#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// RTC_DS1307 implementation
+
+uint8_t RTC_DS1307::begin(void) {
+ return 1;
+}
+
+
uint8_t RTC_DS1307::isrunning(void) {
Wire.beginTransmission(DS1307_ADDRESS);
WW_(i);
@@ -183,6 +225,484 @@ DateTime RTC_DS1307::now() {
return DateTime (y, m, d, hh, mm, ss);
}
+////////////////////////////////////////////////////////////////////////////////
+// RTC_DS3231 implementation
+
+uint8_t RTC_DS3231::begin(void)
+{
+ return 1;
+}
+
+uint8_t RTC_DS3231::isrunning(void)
+{
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0);
+ Wire.endTransmission();
+
+ Wire.requestFrom(DS3231_ADDRESS, 1);
+ uint8_t ss = Wire.RECEIVE();
+ return !(ss>>7);
+}
+
+void RTC_DS3231::adjust(const DateTime& dt)
+{
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0);
+ Wire.SEND(bin2bcd(dt.second()));
+ Wire.SEND(bin2bcd(dt.minute()));
+ Wire.SEND(bin2bcd(dt.hour()));
+ Wire.SEND(bin2bcd(0));
+ Wire.SEND(bin2bcd(dt.day()));
+ Wire.SEND(bin2bcd(dt.month()));
+ Wire.SEND(bin2bcd(dt.year() - 2000));
+ Wire.SEND(0);
+ Wire.endTransmission();
+}
+
+DateTime RTC_DS3231::now()
+{
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0);
+ Wire.endTransmission();
+
+ Wire.requestFrom(DS3231_ADDRESS, 19);
+
+ uint8_t ss = bcd2bin(Wire.RECEIVE() & 0x7F);
+ uint8_t mm = bcd2bin(Wire.RECEIVE());
+ uint8_t hh = bcd2bin(Wire.RECEIVE());
+ Wire.RECEIVE();
+ uint8_t d = bcd2bin(Wire.RECEIVE());
+ uint8_t m = bcd2bin(Wire.RECEIVE());
+ uint16_t y = bcd2bin(Wire.RECEIVE()) + 2000;
+
+ return DateTime (y, m, d, hh, mm, ss);
+}
+
+float RTC_DS3231::getTemperature() {
+ // Checks the internal thermometer on the DS3231 and returns the
+ // temperature as a floating-point value.
+ byte temp;
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0x11);
+ Wire.endTransmission();
+
+ Wire.requestFrom(DS3231_ADDRESS, 2);
+ temp = Wire.RECEIVE(); // Here's the MSB
+ return float(temp) + 0.25*(Wire.RECEIVE()>>6);
+}
+
+void RTC_DS3231::getA1Time(byte& A1Day, byte& A1Hour, byte& A1Minute, byte& A1Second, byte& AlarmBits, bool& A1Dy, bool& A1h12, bool& A1PM) {
+ byte temp_buffer;
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0x07);
+ Wire.endTransmission();
+
+ Wire.requestFrom(DS3231_ADDRESS, 4);
+
+ temp_buffer = Wire.RECEIVE(); // Get A1M1 and A1 Seconds
+ A1Second = bcd2bin(temp_buffer & 0b01111111);
+ // put A1M1 bit in position 0 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>7;
+
+ temp_buffer = Wire.RECEIVE(); // Get A1M2 and A1 minutes
+ A1Minute = bcd2bin(temp_buffer & 0b01111111);
+ // put A1M2 bit in position 1 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>6;
+
+ temp_buffer = Wire.RECEIVE(); // Get A1M3 and A1 Hour
+ // put A1M3 bit in position 2 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>5;
+ // determine A1 12/24 mode
+ A1h12 = temp_buffer & 0b01000000;
+ if (A1h12) {
+ A1PM = temp_buffer & 0b00100000; // determine am/pm
+ A1Hour = bcd2bin(temp_buffer & 0b00011111); // 12-hour
+ } else {
+ A1Hour = bcd2bin(temp_buffer & 0b00111111); // 24-hour
+ }
+
+ temp_buffer = Wire.RECEIVE(); // Get A1M4 and A1 Day/Date
+ // put A1M3 bit in position 3 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>4;
+ // determine A1 day or date flag
+ A1Dy = (temp_buffer & 0b01000000)>>6;
+ if (A1Dy) {
+ // alarm is by day of week, not date.
+ A1Day = bcd2bin(temp_buffer & 0b00001111);
+ } else {
+ // alarm is by date, not day of week.
+ A1Day = bcd2bin(temp_buffer & 0b00111111);
+ }
+}
+
+void RTC_DS3231::getA2Time(byte& A2Day, byte& A2Hour, byte& A2Minute, byte& AlarmBits, bool& A2Dy, bool& A2h12, bool& A2PM) {
+ byte temp_buffer;
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0x0b);
+ Wire.endTransmission();
+
+ Wire.requestFrom(DS3231_ADDRESS, 3);
+ temp_buffer = Wire.RECEIVE(); // Get A2M2 and A2 Minutes
+ A2Minute = bcd2bin(temp_buffer & 0b01111111);
+ // put A2M2 bit in position 4 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>3;
+
+ temp_buffer = Wire.RECEIVE(); // Get A2M3 and A2 Hour
+ // put A2M3 bit in position 5 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>2;
+ // determine A2 12/24 mode
+ A2h12 = temp_buffer & 0b01000000;
+ if (A2h12) {
+ A2PM = temp_buffer & 0b00100000; // determine am/pm
+ A2Hour = bcd2bin(temp_buffer & 0b00011111); // 12-hour
+ } else {
+ A2Hour = bcd2bin(temp_buffer & 0b00111111); // 24-hour
+ }
+
+ temp_buffer = Wire.RECEIVE(); // Get A2M4 and A1 Day/Date
+ // put A2M4 bit in position 6 of DS3231_AlarmBits.
+ AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>1;
+ // determine A2 day or date flag
+ A2Dy = (temp_buffer & 0b01000000)>>6;
+ if (A2Dy) {
+ // alarm is by day of week, not date.
+ A2Day = bcd2bin(temp_buffer & 0b00001111);
+ } else {
+ // alarm is by date, not day of week.
+ A2Day = bcd2bin(temp_buffer & 0b00111111);
+ }
+}
+
+void RTC_DS3231::setAlarm1Simple(byte hour, byte minute) {
+ setA1Time(0, hour, minute, 00, 0b00001000, false, false, false);
+}
+
+void RTC_DS3231::setAlarm2Simple(byte hour, byte minute) {
+ setA2Time(0, hour, minute, 0b00001000, false, false, false);
+}
+
+void RTC_DS3231::setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM) {
+ // Sets the alarm-1 date and time on the DS3231, using A1* information
+ byte temp_buffer;
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0x07); // A1 starts at 07h
+ // Send A1 second and A1M1
+ Wire.SEND(bin2bcd(A1Second) | ((AlarmBits & 0b00000001) << 7));
+ // Send A1 Minute and A1M2
+ Wire.SEND(bin2bcd(A1Minute) | ((AlarmBits & 0b00000010) << 6));
+ // Figure out A1 hour
+ if (A1h12) {
+ // Start by converting existing time to h12 if it was given in 24h.
+ if (A1Hour > 12) {
+ // well, then, this obviously isn't a h12 time, is it?
+ A1Hour = A1Hour - 12;
+ A1PM = true;
+ }
+ if (A1PM) {
+ // Afternoon
+ // Convert the hour to BCD and add appropriate flags.
+ temp_buffer = bin2bcd(A1Hour) | 0b01100000;
+ } else {
+ // Morning
+ // Convert the hour to BCD and add appropriate flags.
+ temp_buffer = bin2bcd(A1Hour) | 0b01000000;
+ }
+ } else {
+ // Now for 24h
+ temp_buffer = bin2bcd(A1Hour);
+ }
+ temp_buffer = temp_buffer | ((AlarmBits & 0b00000100)<<5);
+ // A1 hour is figured out, send it
+ Wire.SEND(temp_buffer);
+ // Figure out A1 day/date and A1M4
+ temp_buffer = ((AlarmBits & 0b00001000)<<4) | bin2bcd(A1Day);
+ if (A1Dy) {
+ // Set A1 Day/Date flag (Otherwise it's zero)
+ temp_buffer = temp_buffer | 0b01000000;
+ }
+ Wire.SEND(temp_buffer);
+ // All done!
+ Wire.endTransmission();
+}
+
+void RTC_DS3231::setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM) {
+ // Sets the alarm-2 date and time on the DS3231, using A2* information
+ byte temp_buffer;
+ Wire.beginTransmission(DS3231_ADDRESS);
+ Wire.SEND(0x0b); // A1 starts at 0bh
+ // Send A2 Minute and A2M2
+ Wire.SEND(bin2bcd(A2Minute) | ((AlarmBits & 0b00010000) << 3));
+ // Figure out A2 hour
+ if (A2h12) {
+ // Start by converting existing time to h12 if it was given in 24h.
+ if (A2Hour > 12) {
+ // well, then, this obviously isn't a h12 time, is it?
+ A2Hour = A2Hour - 12;
+ A2PM = true;
+ }
+ if (A2PM) {
+ // Afternoon
+ // Convert the hour to BCD and add appropriate flags.
+ temp_buffer = bin2bcd(A2Hour) | 0b01100000;
+ } else {
+ // Morning
+ // Convert the hour to BCD and add appropriate flags.
+ temp_buffer = bin2bcd(A2Hour) | 0b01000000;
+ }
+ } else {
+ // Now for 24h
+ temp_buffer = bin2bcd(A2Hour);
+ }
+ // add in A2M3 bit
+ temp_buffer = temp_buffer | ((AlarmBits & 0b00100000)<<2);
+ // A2 hour is figured out, send it
+ Wire.SEND(temp_buffer);
+ // Figure out A2 day/date and A2M4
+ temp_buffer = ((AlarmBits & 0b01000000)<<1) | bin2bcd(A2Day);
+ if (A2Dy) {
+ // Set A2 Day/Date flag (Otherwise it's zero)
+ temp_buffer = temp_buffer | 0b01000000;
+ }
+ Wire.SEND(temp_buffer);
+ // All done!
+ Wire.endTransmission();
+}
+
+void RTC_DS3231::turnOnAlarm(byte Alarm) {
+ // turns on alarm number "Alarm". Defaults to 2 if Alarm is not 1.
+ byte temp_buffer = readControlByte(0);
+ // modify control byte
+ if (Alarm == 1) {
+ temp_buffer = temp_buffer | 0b00000101;
+ } else {
+ temp_buffer = temp_buffer | 0b00000110;
+ }
+ writeControlByte(temp_buffer, 0);
+}
+
+void RTC_DS3231::turnOffAlarm(byte Alarm) {
+ // turns off alarm number "Alarm". Defaults to 2 if Alarm is not 1.
+ // Leaves interrupt pin alone.
+ byte temp_buffer = readControlByte(0);
+ // modify control byte
+ if (Alarm == 1) {
+ temp_buffer = temp_buffer & 0b11111110;
+ } else {
+ temp_buffer = temp_buffer & 0b11111101;
+ }
+ writeControlByte(temp_buffer, 0);
+}
+
+bool RTC_DS3231::checkAlarmEnabled(byte Alarm) {
+ // Checks whether the given alarm is enabled.
+ byte result = 0x0;
+ byte temp_buffer = readControlByte(0);
+ if (Alarm == 1) {
+ result = temp_buffer & 0b00000001;
+ } else {
+ result = temp_buffer & 0b00000010;
+ }
+ return result;
+}
+
+bool RTC_DS3231::checkIfAlarm(byte Alarm) {
+ // Checks whether alarm 1 or alarm 2 flag is on, returns T/F accordingly.
+ // Turns flag off, also.
+ // defaults to checking alarm 2, unless Alarm == 1.
+ byte result;
+ byte temp_buffer = readControlByte(1);
+ if (Alarm == 1) {
+ // Did alarm 1 go off?
+ result = temp_buffer & 0b00000001;
+ // clear flag
+ temp_buffer = temp_buffer & 0b11111110;
+ } else {
+ // Did alarm 2 go off?
+ result = temp_buffer & 0b00000010;
+ // clear flag
+ temp_buffer = temp_buffer & 0b11111101;
+ }
+ writeControlByte(temp_buffer, 1);
+ return result;
+}
+
+void RTC_DS3231::enableOscillator(bool TF, bool battery, byte frequency) {
+ // turns oscillator on or off. True is on, false is off.
+ // if battery is true, turns on even for battery-only operation,
+ // otherwise turns off if Vcc is off.
+ // frequency must be 0, 1, 2, or 3.
+ // 0 = 1 Hz
+ // 1 = 1.024 kHz
+ // 2 = 4.096 kHz
+ // 3 = 8.192 kHz (Default if frequency byte is out of range)
+ if (frequency > 3) frequency = 3;
+ // read control byte in, but zero out current state of RS2 and RS1.
+ byte temp_buffer = readControlByte(0) & 0b11100111;
+ if (battery) {
+ // turn on BBSQW flag
+ temp_buffer = temp_buffer | 0b01000000;
+ } else {
+ // turn off BBSQW flag
+ temp_buffer = temp_buffer & 0b10111111;
+ }
+ if (TF) {
+ // set ~EOSC to 0 and INTCN to zero.
+ temp_buffer = temp_buffer & 0b01111011;
+ } else {
+ // set ~EOSC to 1, leave INTCN as is.
+ temp_buffer = temp_buffer | 0b10000000;
+ }
+ // shift frequency into bits 3 and 4 and set.
+ frequency = frequency << 3;
+ temp_buffer = temp_buffer | frequency;
+ // And write the control bits
+ writeControlByte(temp_buffer, 0);
+}
+
+void RTC_DS3231::enable32kHz(bool TF) {
+ // turn 32kHz pin on or off
+ byte temp_buffer = readControlByte(1);
+ if (TF) {
+ // turn on 32kHz pin
+ temp_buffer = temp_buffer | 0b00001000;
+ } else {
+ // turn off 32kHz pin
+ temp_buffer = temp_buffer & 0b11110111;
+ }
+ writeControlByte(temp_buffer, 1);
+}
+
+bool RTC_DS3231::oscillatorCheck() {
+ // Returns false if the oscillator has been off for some reason.
+ // If this is the case, the time is probably not correct.
+ byte temp_buffer = readControlByte(1);
+ bool result = true;
+ if (temp_buffer & 0b10000000) {
+ // Oscillator Stop Flag (OSF) is set, so return false.
+ result = false;
+ }
+ return result;
+}
+
+byte RTC_DS3231::readControlByte(bool which) {
+ // Read selected control byte
+ // first byte (0) is 0x0e, second (1) is 0x0f
+ Wire.beginTransmission(DS3231_ADDRESS);
+ if (which) {
+ // second control byte
+ Wire.SEND(0x0f);
+ } else {
+ // first control byte
+ Wire.SEND(0x0e);
+ }
+ Wire.endTransmission();
+ Wire.requestFrom(DS3231_ADDRESS, 1);
+ return Wire.RECEIVE();
+}
+
+void RTC_DS3231::writeControlByte(byte control, bool which) {
+ // Write the selected control byte.
+ // which=false -> 0x0e, true->0x0f.
+ Wire.beginTransmission(DS3231_ADDRESS);
+ if (which) {
+ Wire.SEND(0x0f);
+ } else {
+ Wire.SEND(0x0e);
+ }
+ Wire.SEND(control);
+ Wire.endTransmission();
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// RTC_DS3234 implementation
+
+// Registers we use
+const int CONTROL_R = 0x0e;
+const int CONTROL_W = 0x8e;
+const int CONTROL_STATUS_R = 0x0f;
+const int CONTROL_STATUS_W = 0x8f;
+const int SECONDS_R = 0x00;
+const int SECONDS_W = 0x80;
+
+// Bits we use
+const int EOSC = 7;
+const int OSF = 7;
+
+uint8_t RTC_DS3234::begin(void)
+{
+ pinMode(cs_pin,OUTPUT);
+ cs(HIGH);
+ SPI.setBitOrder(MSBFIRST);
+
+ //Ugh! In order to get this to interop with other SPI devices,
+ //This has to be done in cs()
+ SPI.setDataMode(SPI_MODE1);
+
+ //Enable oscillator, disable square wave, alarms
+ cs(LOW);
+ SPI.transfer(CONTROL_W);
+ SPI.transfer(0x0);
+ cs(HIGH);
+ delay(1);
+
+ //Clear oscilator stop flag, 32kHz pin
+ cs(LOW);
+ SPI.transfer(CONTROL_STATUS_W);
+ SPI.transfer(0x0);
+ cs(HIGH);
+ delay(1);
+
+ return 1;
+}
+
+void RTC_DS3234::cs(int _value)
+{
+ SPI.setDataMode(SPI_MODE1);
+ digitalWrite(cs_pin,_value);
+}
+
+uint8_t RTC_DS3234::isrunning(void)
+{
+ cs(LOW);
+ SPI.transfer(CONTROL_R);
+ uint8_t ss = SPI.transfer(-1);
+ cs(HIGH);
+ return !(ss & _BV(OSF));
+}
+
+void RTC_DS3234::adjust(const DateTime& dt)
+{
+ cs(LOW);
+ SPI.transfer(SECONDS_W);
+ SPI.transfer(bin2bcd(dt.second()));
+ SPI.transfer(bin2bcd(dt.minute()));
+ SPI.transfer(bin2bcd(dt.hour()));
+ SPI.transfer(bin2bcd(dt.dayOfWeek()));
+ SPI.transfer(bin2bcd(dt.day()));
+ SPI.transfer(bin2bcd(dt.month()));
+ SPI.transfer(bin2bcd(dt.year() - 2000));
+ cs(HIGH);
+
+}
+
+DateTime RTC_DS3234::now()
+{
+ cs(LOW);
+ SPI.transfer(SECONDS_R);
+ uint8_t ss = bcd2bin(SPI.transfer(-1) & 0x7F);
+ uint8_t mm = bcd2bin(SPI.transfer(-1));
+ uint8_t hh = bcd2bin(SPI.transfer(-1));
+ SPI.transfer(-1);
+ uint8_t d = bcd2bin(SPI.transfer(-1));
+ uint8_t m = bcd2bin(SPI.transfer(-1));
+ uint16_t y = bcd2bin(SPI.transfer(-1)) + 2000;
+ cs(HIGH);
+
+ return DateTime (y, m, d, hh, mm, ss);
+}
+
+
////////////////////////////////////////////////////////////////////////////////
// RTC_Millis implementation
View
134 RTClib.h
@@ -1,6 +1,17 @@
// Code by JeeLabs http://news.jeelabs.org/code/
// Released to the public domain! Enjoy!
+// Additions by MrAlvin.
+// Merged text from: github/coobro/RTClib
+
+// Alarm code for DS3231 (Chronodot) heavily used/modified from Eric Ayars DS3231 library
+// His code is located at: http://hacks.ayars.org/2011/04/ds3231-real-time-clock.html
+
+#ifndef __RTCLIB_H__
+#define __RTCLIB_H__
+
+
+
// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
class DateTime {
public:
@@ -20,11 +31,18 @@ class DateTime {
long secondstime() const;
// 32-bit times as seconds since 1/1/1970
uint32_t unixtime(void) const;
-
+ // as a string
+ char* toString(char* buf, int maxlen) const;
+ // add additional time
+ void operator+=(uint32_t);
+
protected:
uint8_t yOff, m, d, hh, mm, ss;
};
+
+
+////////////////////////////////////////////////////////////////////////////////
// RTC based on the DS1307 chip connected via I2C and the Wire library
class RTC_DS1307 {
public:
@@ -34,6 +52,117 @@ class RTC_DS1307 {
static DateTime now();
};
+
+////////////////////////////////////////////////////////////////////////////////
+// RTC based on the DS3231 chip connected via I2C
+class RTC_DS3231
+{
+public:
+ uint8_t begin(void);
+ void adjust(const DateTime& dt);
+ uint8_t isrunning(void);
+ DateTime now();
+
+ // Temperature function
+
+ float getTemperature();
+
+ void getA1Time(byte& A1Day, byte& A1Hour, byte& A1Minute, byte& A1Second, byte& AlarmBits, bool& A1Dy, bool& A1h12, bool& A1PM);
+/* Retrieves everything you could want to know about alarm
+ * one.
+ * A1Dy true makes the alarm go on A1Day = Day of Week,
+ * A1Dy false makes the alarm go on A1Day = Date of month.
+ *
+ * byte AlarmBits sets the behavior of the alarms:
+ * Dy A1M4 A1M3 A1M2 A1M1 Rate
+ * X 1 1 1 1 Once per second
+ * X 1 1 1 0 Alarm when seconds match
+ * X 1 1 0 0 Alarm when min, sec match
+ * X 1 0 0 0 Alarm when hour, min, sec match
+ * 0 0 0 0 0 Alarm when date, h, m, s match
+ * 1 0 0 0 0 Alarm when DoW, h, m, s match
+ *
+ * Dy A2M4 A2M3 A2M2 Rate
+ * X 1 1 1 Once per minute (at seconds = 00)
+ * X 1 1 0 Alarm when minutes match
+ * X 1 0 0 Alarm when hours and minutes match
+ * 0 0 0 0 Alarm when date, hour, min match
+ * 1 0 0 0 Alarm when DoW, hour, min match
+ */
+ void getA2Time(byte& A2Day, byte& A2Hour, byte& A2Minute, byte& AlarmBits, bool& A2Dy, bool& A2h12, bool& A2PM);
+ // Same as getA1Time();, but A2 only goes on seconds == 00.
+ void setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM);
+ // Set the details for Alarm 1
+ void setAlarm1Simple(byte hour, byte minute);
+ // A simple hour/minute alarm.
+ void setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM);
+ // Set the details for Alarm 2
+ void setAlarm2Simple(byte hour, byte minute);
+ // A simple hour/minute alarm.
+ void turnOnAlarm(byte Alarm);
+ // Enables alarm 1 or 2 and the external interrupt pin.
+ // If Alarm != 1, it assumes Alarm == 2.
+ void turnOffAlarm(byte Alarm);
+ // Disables alarm 1 or 2 (default is 2 if Alarm != 1);
+ // and leaves the interrupt pin alone.
+ bool checkAlarmEnabled(byte Alarm);
+ // Returns T/F to indicate whether the requested alarm is
+ // enabled. Defaults to 2 if Alarm != 1.
+ bool checkIfAlarm(byte Alarm);
+ // Checks whether the indicated alarm (1 or 2, 2 default);
+ // has been activated.
+
+ // Oscillator functions
+
+ void enableOscillator(bool TF, bool battery, byte frequency);
+ // turns oscillator on or off. True is on, false is off.
+ // if battery is true, turns on even for battery-only operation,
+ // otherwise turns off if Vcc is off.
+ // frequency must be 0, 1, 2, or 3.
+ // 0 = 1 Hz
+ // 1 = 1.024 kHz
+ // 2 = 4.096 kHz
+ // 3 = 8.192 kHz (Default if frequency byte is out of range);
+ void enable32kHz(bool TF);
+ // Turns the 32kHz output pin on (true); or off (false).
+ bool oscillatorCheck();;
+ // Checks the status of the OSF (Oscillator Stop Flag);.
+ // If this returns false, then the clock is probably not
+ // giving you the correct time.
+ // The OSF is cleared by function setSecond();.
+
+protected:
+ void cs(int _value);
+
+private:
+ int cs_pin;
+ byte readControlByte(bool which);
+ // Read selected control byte: (0); reads 0x0e, (1) reads 0x0f
+ void writeControlByte(byte control, bool which);
+ // Write the selected control byte.
+ // which == false -> 0x0e, true->0x0f.
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// RTC based on the DS3234 chip connected via SPI and the SPI library
+class RTC_DS3234
+{
+public:
+ RTC_DS3234(int _cs_pin): cs_pin(_cs_pin) {}
+ uint8_t begin(void);
+ void adjust(const DateTime& dt);
+ uint8_t isrunning(void);
+ DateTime now();
+
+protected:
+ void cs(int _value);
+
+private:
+ int cs_pin;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
// 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 {
@@ -41,7 +170,10 @@ class RTC_Millis {
static void begin(const DateTime& dt) { adjust(dt); }
static void adjust(const DateTime& dt);
static DateTime now();
+ RTC_Millis(void) { adjust(DateTime(2000,1,1,0,0,0)); }
protected:
static long offset;
};
+
+#endif // __RTCLIB_H__
View
1  examples/datecalc/datecalc.pde
@@ -1,6 +1,7 @@
// Simple date conversions and calculations
#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
#include "RTClib.h"
void showDate(const char* txt, const DateTime& dt) {
View
3  examples/ds1307/ds1307.pde
@@ -1,6 +1,7 @@
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
#include "RTClib.h"
RTC_DS1307 RTC;
@@ -58,4 +59,4 @@ void loop () {
Serial.println();
delay(3000);
-}
+}
View
49 examples/ds3231/ds3231.pde
@@ -0,0 +1,49 @@
+// Date, Time and Alarm functions using a DS3231 RTC connected via I2C and Wire lib
+
+#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
+#include <RTClib.h>
+
+RTC_DS3231 RTC;
+
+void setup () {
+ Serial.begin(57600);
+ Wire.begin();
+ RTC.begin();
+
+ RTC.adjust(DateTime(__DATE__, __TIME__));
+ if (! RTC.isrunning()) {
+ Serial.println("RTC is NOT running!");
+ // following line sets the RTC to the date & time this sketch was compiled
+ RTC.adjust(DateTime(__DATE__, __TIME__));
+ }
+ DateTime now = RTC.now();
+ RTC.setAlarm1Simple(21, 58);
+ RTC.turnOnAlarm(1);
+ if (RTC.checkAlarmEnabled(1)) {
+ Serial.println("Alarm Enabled");
+ }
+}
+
+void loop () {
+ DateTime now = RTC.now();
+
+ Serial.print(now.year(), DEC);
+ Serial.print('/');
+ Serial.print(now.month(), DEC);
+ Serial.print('/');
+ Serial.print(now.day(), DEC);
+ Serial.print(' ');
+ Serial.print(now.hour(), DEC);
+ Serial.print(':');
+ Serial.print(now.minute(), DEC);
+ Serial.print(':');
+ Serial.print(now.second(), DEC);
+ Serial.println();
+
+ if (RTC.checkIfAlarm(1)) {
+ Serial.println("Alarm Triggered");
+ }
+ Serial.println();
+ delay(3000);
+}
View
63 examples/ds3231_interrupt/ds3231_interrupt.pde
@@ -0,0 +1,63 @@
+// Date, Time and Alarm functions using a DS3231 RTC connected via I2C and Wire lib
+
+#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
+#include <avr/sleep.h>
+#include <RTClib.h>
+
+
+RTC_DS3231 RTC;
+int INTERRUPT_PIN = 2;
+volatile int state = LOW;
+
+void setup () {
+ pinMode(INTERRUPT_PIN, INPUT);
+ //pull up the interrupt pin
+ digitalWrite(INTERRUPT_PIN, HIGH);
+
+ Serial.begin(57600);
+ Wire.begin();
+ RTC.begin();
+
+ RTC.adjust(DateTime(__DATE__, __TIME__));
+ DateTime now = RTC.now();
+ RTC.setAlarm1Simple(22, 11);
+ RTC.setAlarm2Simple(11, 10);
+ RTC.turnOnAlarm(1);
+ RTC.turnOnAlarm(2);
+ if (RTC.checkAlarmEnabled(1) && RTC.checkAlarmEnabled(2)) {
+ Serial.println("Alarms Enabled");
+ }
+ attachInterrupt(0, logData, LOW);
+}
+
+void loop () {
+ DateTime now = RTC.now();
+ if (RTC.checkIfAlarm(1) || RTC.checkIfAlarm(2)) {
+ Serial.println("Alarm Triggered");
+ }
+
+ Serial.print(now.hour(), DEC);
+ Serial.print(':');
+ Serial.print(now.minute(), DEC);
+ Serial.print(':');
+ Serial.println(now.second(), DEC);
+ Serial.println("Going to Sleep");
+ delay(600);
+ sleepNow();
+ Serial.println("AWAKE");
+}
+
+void sleepNow() {
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ sleep_enable();
+ attachInterrupt(0,logData, LOW);
+ sleep_mode();
+ //HERE AFTER WAKING UP
+ sleep_disable();
+ detachInterrupt(0);
+}
+
+void logData() {
+ //do something quick, flip a flag, and handle in loop();
+}
View
57 examples/ds3234/ds3234.pde
@@ -0,0 +1,57 @@
+// Date and time functions using a DS3234 RTC connected via SPI
+
+#include <SPI.h>
+#include <Wire.h> // not used here, but needed to prevent a RTClib compile error
+#include <RTClib.h>
+
+
+// Avoid spurious warnings
+#undef PROGMEM
+#define PROGMEM __attribute__(( section(".progmem.data") ))
+#undef PSTR
+#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))
+
+// Create an RTC instance, using the chip select pin it's connected to
+RTC_DS3234 RTC(8);
+
+void setup () {
+ Serial.begin(57600);
+ Serial.println("RTClib/examples/ds3234/");
+ SPI.begin();
+ RTC.begin();
+
+ if (! RTC.isrunning()) {
+ Serial.println("RTC is NOT running!");
+ Serial.print("Setting time to... ");
+ Serial.print(__DATE__);
+ Serial.print(' ');
+ Serial.println(__TIME__);
+ // following line sets the RTC to the date & time this sketch was compiled
+ RTC.adjust(DateTime(__DATE__, __TIME__));
+ }
+}
+
+void loop () {
+ const int len = 32;
+ static char buf[len];
+
+ DateTime now = RTC.now();
+
+ Serial.println(now.toString(buf,len));
+
+ Serial.print(" since midnight 1/1/1970 = ");
+ Serial.print(now.unixtime());
+ Serial.print("s = ");
+ Serial.print(now.unixtime() / 86400L);
+ Serial.println("d");
+
+ // calculate a date which is 7 days and 30 seconds into the future
+ DateTime future (now.unixtime() + 7 * 86400L + 30 );
+
+ Serial.print(" now + 7d + 30s: ");
+ Serial.println(future.toString(buf,len));
+
+ Serial.println();
+ delay(3000);
+}
+
View
5 examples/gettime/gettime.pde
@@ -2,11 +2,10 @@
#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
#include "RTClib.h"
-RTC_DS1307 RTC; // Uncommnt this line if you are using the DS1307 chip or only use the basic functions of DS1337, DS1340, Chronodot (DS3132)
-// RTC_DS1340 RTC; // Uncomment this line if you are using the DS1340 chip
-// Chronodot RTC; // Uncomment this line if you are using the Chronodot (DS3132)
+RTC_DS1307 RTC; // Uncommnt this line if you are using the DS1307 chip or only use the basic functions of DS1337, DS1340, Chronodot (DS3231)
void setup () {
View
5 examples/settime/settime.pde
@@ -1,9 +1,8 @@
// Set date and time using a DS1307 RTC connected via I2C
-//
-// Connect SCL to Uno-Analog 0
-// Connect SDA to Uno-Analog 1
+
#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
#include "RTClib.h"
RTC_DS1307 RTC; // Setup an instance of DS1307 naming it RTC
View
1  examples/softrtc/softrtc.pde
@@ -1,6 +1,7 @@
// Date and time functions using just software, based on millis() & timer
#include <Wire.h>
+#include <SPI.h> // not used here, but needed to prevent a RTClib compile error
#include "RTClib.h"
RTC_Millis RTC;
View
16 keywords.txt
@@ -8,6 +8,8 @@
DateTime KEYWORD1
RTC_DS1307 KEYWORD1
+RTC_DS3231 KEYWORD1
+RTC_DS3234 KEYWORD1
RTC_Millis KEYWORD1
#######################################
@@ -27,6 +29,20 @@ begin KEYWORD2
adjust KEYWORD2
isrunning KEYWORD2
now KEYWORD2
+getTemperature KEYWORD2
+getA1Time KEYWORD2
+getA2Time KEYWORD2
+setA1Time KEYWORD2
+setA2Time KEYWORD2
+setAlarm1Simple KEYWORD2
+setAlarm2Simple KEYWORD2
+turnOnAlarm KEYWORD2
+turnOffAlarm KEYWORD2
+checkAlarmEnabled KEYWORD2
+checkIfAlarm KEYWORD2
+enableOscillator KEYWORD2
+enable32kHz KEYWORD2
+oscillatorCheck KEYWORD2
#######################################
# Constants (LITERAL1)
Please sign in to comment.
Something went wrong with that request. Please try again.