From 2a96c87e1eb53d988ed23e326a94de5aafb49bfb Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Wed, 14 May 2014 12:03:41 -0600 Subject: [PATCH 01/11] rename examples to *.ino: Arduino 1.0 --- examples/datecalc/{datecalc.pde => datecalc.ino} | 0 examples/ds1307/{ds1307.pde => ds1307.ino} | 0 examples/ds3234/{ds3234.pde => ds3234.ino} | 0 examples/softrtc/{softrtc.pde => softrtc.ino} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/datecalc/{datecalc.pde => datecalc.ino} (100%) rename examples/ds1307/{ds1307.pde => ds1307.ino} (100%) rename examples/ds3234/{ds3234.pde => ds3234.ino} (100%) rename examples/softrtc/{softrtc.pde => softrtc.ino} (100%) diff --git a/examples/datecalc/datecalc.pde b/examples/datecalc/datecalc.ino similarity index 100% rename from examples/datecalc/datecalc.pde rename to examples/datecalc/datecalc.ino diff --git a/examples/ds1307/ds1307.pde b/examples/ds1307/ds1307.ino similarity index 100% rename from examples/ds1307/ds1307.pde rename to examples/ds1307/ds1307.ino diff --git a/examples/ds3234/ds3234.pde b/examples/ds3234/ds3234.ino similarity index 100% rename from examples/ds3234/ds3234.pde rename to examples/ds3234/ds3234.ino diff --git a/examples/softrtc/softrtc.pde b/examples/softrtc/softrtc.ino similarity index 100% rename from examples/softrtc/softrtc.pde rename to examples/softrtc/softrtc.ino From 5852b4d59cd721cf3b77895cd9c3d864c93b38b8 Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Wed, 14 May 2014 16:34:23 -0600 Subject: [PATCH 02/11] Added alarm functions based on Petre Rodan's ds3234 library; have not tested them yet --- RTC_DS3234.cpp | 150 +++++++++++++++++++++++++++++++++++++++++++++++++ RTC_DS3234.h | 30 +++++++++- 2 files changed, 179 insertions(+), 1 deletion(-) diff --git a/RTC_DS3234.cpp b/RTC_DS3234.cpp index bee37017..4e3c45af 100644 --- a/RTC_DS3234.cpp +++ b/RTC_DS3234.cpp @@ -27,6 +27,18 @@ const int SECONDS_W = 0x80; const int EOSC = 7; const int OSF = 7; +// Alarm enable -- mostly commented out becaause 1 and 2 are alarm numbers, so can be written in functions in an intuitive way in decimal +//const int A1IE = 0x01; // bit 0: Alarm1 interrupt enable (1 to enable) +//const int A2IE = 0x02; // bit 1: Alarm2 interrupt enable (1 to enable) +const int INTCN = 0x04; // bit 2: Interrupt control (1 for use of the alarms and to disable square wave) + +// Alarm status +//const int A1F = 0x01; // bit 0: Alarm 1 Flag - (1 if alarm 1 was triggered) +//const int A2F = 0x02; +//const int DS3234_OSF = 0x80; // Not using oscillator stop flag + + + uint8_t RTC_DS3234::begin(void) { pinMode(cs_pin,OUTPUT); @@ -84,6 +96,144 @@ void RTC_DS3234::adjust(const DateTime& dt) } +// Alarms from DS3234 library by Petre Rodan, with enabling functions by Andy +// Wickert so the user doesn't have to know which register to use and the +// end code looks cleaner (even if it requires more functions up here) +// CS pin setting removed, since this is part of RTClib, in which these are +// defined already + +void RTC_DS3234::set_alarm_1(const uint8_t s, const uint8_t mi, const uint8_t h, const uint8_t d, const uint8_t * flags) +// flags are: A1M1 (seconds), A1M2 (minutes), A1M3 (hour), +// A1M4 (day) 0 to enable, 1 to disable, DY/DT (dayofweek == 1/dayofmonth == 0) +// +// flags define what calendar component to be checked against the current time in order +// to trigger the alarm - see datasheet +// A1M1 (seconds) (0 to enable, 1 to disable) +// A1M2 (minutes) (0 to enable, 1 to disable) +// A1M3 (hour) (0 to enable, 1 to disable) +// A1M4 (day) (0 to enable, 1 to disable) +// DY/DT (dayofweek == 1/dayofmonth == 0) +// +// So in short, if the mask bits are "1", the alarm will always go off +// regardless of this factor; if the mask bits are 0, they will check your +// value for this. So every minute on the "30 s" requires, e.g., +// set_alarm_1(alarm_pin, 30, 0, 0, 0, {0, 1, 1, 1, 1}) +{ + bool t[4] = { s, mi, h, d }; + uint8_t i; + + for (i = 0; i <= 3; i++) { + digitalWrite(cs_pin, LOW); + SPI.transfer(i + 0x87); + if (i == 3) { + SPI.transfer(dectobcd(t[3]) | (flags[3] << 7) | (flags[4] << 6)); + } else + SPI.transfer(dectobcd(t[i]) | (flags[i] << 7)); + digitalWrite(cs_pin, HIGH); + } +} + +void RTC_DS3234::set_alarm_2(const uint8_t mi, const uint8_t h, const uint8_t d, + const uint8_t * flags) +// flags are: A2M2 (minutes), A2M3 (hour), A2M4 (day) 0 to enable, 1 to disable, DY/DT (dayofweek == 1/dayofmonth == 0) - +// +// flags define what calendar component to be checked against the current time in order +// to trigger the alarm +// A2M2 (minutes) (0 to enable, 1 to disable) +// A2M3 (hour) (0 to enable, 1 to disable) +// A2M4 (day) (0 to enable, 1 to disable) +// DY/DT (dayofweek == 1/dayofmonth == 0) +// +// See notes from Alarm 1 +{ + uint8_t t[3] = { mi, h, d }; + uint8_t i; + + for (i = 0; i <= 2; i++) { + digitalWrite(cs_pin, LOW); + SPI.transfer(i + 0x8B); + if (i == 2) { + SPI.transfer(dectobcd(t[2]) | (flags[2] << 7) | (flags[3] << 6)); + } else + SPI.transfer(dectobcd(t[i]) | (flags[i] << 7)); + digitalWrite(cs_pin, HIGH); + } +} + +void RTC_DS3234::enable_alarm(const uint8_t alarm_number) +// Written like this thanks to the fact that these A1IE and A2IE are binary 1 +// and 2, which are also decimal 1 and 2: so just pass the number of that alarm +// INTCN is the interrupt enable bit +{ + set_addr(0x8E, INTCN | alarm_number); +} + +// when the alarm flag is cleared the pulldown on INT is also released +void RTC_DS3234::clear_alarm_flag(const uint8_t alarm_number) +{ + uint8_t reg_val; + reg_val = get_addr(0x0F) & ~alarm_number; + set_addr(0x8F, reg_val); +} + +// Temperature +float RTC_DS3234::get_temperature_degC() +{ + float temp_degC; + uint8_t temp_msb, temp_lsb; + int8_t nint; + + temp_msb = get_addr(0x11); + temp_lsb = get_addr(0x12) >> 6; + if ((temp_msb & 0x80) != 0) + nint = temp_msb | ~((1 << 8) - 1); // if negative get two's complement + else + nint = temp_msb; + + temp_degC = 0.25 * temp_lsb + nint; + + return temp_degC; +} + +// Addressing + +uint8_t RTC_DS3234::get_addr(const uint8_t addr) +{ + uint8_t rv; + + digitalWrite(cs_pin, LOW); + SPI.transfer(addr); + rv = SPI.transfer(0x00); + digitalWrite(cs_pin, HIGH); + return rv; +} + +void RTC_DS3234::set_addr(const uint8_t addr, const uint8_t val) +{ + digitalWrite(cs_pin, LOW); + SPI.transfer(addr); + SPI.transfer(val); + digitalWrite(cs_pin, HIGH); +} + +// helpers from DS3234 library by Petre Rodan -- just 1 now for setting the +// alarms + +uint8_t RTC_DS3234::dectobcd(const uint8_t val) +{ + return ((val / 10 * 16) + (val % 10)); +} + +/* +Uncomment if I decide to include the "get" functions. +uint8_t RTC_DS3234::bcdtodec(const uint8_t val) +{ + return ((val / 16 * 10) + (val % 16)); +} +*/ + +// end helpers + DateTime RTC_DS3234::now() { cs(LOW); diff --git a/RTC_DS3234.h b/RTC_DS3234.h index 00328005..9d921f6e 100644 --- a/RTC_DS3234.h +++ b/RTC_DS3234.h @@ -15,12 +15,40 @@ class RTC_DS3234 void adjust(const DateTime& dt); uint8_t isrunning(void); DateTime now(); - protected: void cs(int _value); + // control/status register -- might just break out into separate functions though + // void DS3234_set_creg(const uint8_t pin, const uint8_t val); + + // temperature register + float get_temperature_degC(); + + // alarms + // 1 + void set_alarm_1(const uint8_t s, const uint8_t mi, const uint8_t h, const uint8_t d, const uint8_t * flags); + void enable_alarm_1(); + //void get_alarm_1(const uint8_t pin, char *buf, const uint8_t len); + //void clear_a1f(const uint8_t pin); + //uint8_t triggered_a1(const uint8_t pin); + // 2 + void set_alarm_2(const uint8_t mi, const uint8_t h, const uint8_t d, const uint8_t * flags); + void enable_alarm_2(); + //void get_alarm_2(const uint8_t pin, char *buf, const uint8_t len); + //void clear_a2f(const uint8_t pin); + //uint8_t triggered_a2(const uint8_t pin); + // Both + void enable_alarm(const uint8_t alarm_number); // Sets the bits to enable that alarm's interrupt; may inadvertently disable other alarm...? + void clear_alarm_flag(const uint8_t alarm_number); // Clears alarm flags; release pulldown on INTERRUPT pin + private: int cs_pin; + // Control register -- get and set bits/bytes + uint8_t get_addr(const uint8_t addr); + void set_addr(const uint8_t addr, const uint8_t val); + // Helpers + uint8_t dectobcd(const uint8_t); + //uint8_t bcdtodec(const uint8_t); // currently unused }; #endif // __RTC_DS3234_H__ From b1db4bcd7cf001752407871ff9fa6f64b67a435c Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Wed, 14 May 2014 16:37:56 -0600 Subject: [PATCH 03/11] Create README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..6e4b9231 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +RTClib +====== + +A fork of Jeelab's fantastic RTC library. + +Forked from adafruit to maniacbug to NorthernWidget, where it is being modifed by awickert to include alarm functions for the DS3234 SPI high-accuracy real-time clock. From fbd00564f70d0f4bc0b4f9f1f9143fa040596ac3 Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Thu, 15 May 2014 11:05:45 -0600 Subject: [PATCH 04/11] Move functions for external use out of 'protected' --- RTC_DS3234.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/RTC_DS3234.h b/RTC_DS3234.h index 9d921f6e..da2b4ed4 100644 --- a/RTC_DS3234.h +++ b/RTC_DS3234.h @@ -15,11 +15,6 @@ class RTC_DS3234 void adjust(const DateTime& dt); uint8_t isrunning(void); DateTime now(); -protected: - void cs(int _value); - - // control/status register -- might just break out into separate functions though - // void DS3234_set_creg(const uint8_t pin, const uint8_t val); // temperature register float get_temperature_degC(); @@ -41,6 +36,12 @@ class RTC_DS3234 void enable_alarm(const uint8_t alarm_number); // Sets the bits to enable that alarm's interrupt; may inadvertently disable other alarm...? void clear_alarm_flag(const uint8_t alarm_number); // Clears alarm flags; release pulldown on INTERRUPT pin +protected: + void cs(int _value); + + // control/status register -- might just break out into separate functions though + // void DS3234_set_creg(const uint8_t pin, const uint8_t val); + private: int cs_pin; // Control register -- get and set bits/bytes From f5806bfbbc51301d442bc2cb25c2e3125bf3a3a1 Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Thu, 15 May 2014 11:07:10 -0600 Subject: [PATCH 05/11] SPI_MODE3 per SparkFun comments on the DeadOn RTC --- RTC_DS3234.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RTC_DS3234.cpp b/RTC_DS3234.cpp index 4e3c45af..96c85d5e 100644 --- a/RTC_DS3234.cpp +++ b/RTC_DS3234.cpp @@ -47,7 +47,7 @@ uint8_t RTC_DS3234::begin(void) //Ugh! In order to get this to interop with other SPI devices, //This has to be done in cs() - SPI.setDataMode(SPI_MODE1); + SPI.setDataMode(SPI_MODE3); //Enable oscillator, disable square wave, alarms cs(LOW); @@ -68,7 +68,7 @@ uint8_t RTC_DS3234::begin(void) void RTC_DS3234::cs(int _value) { - SPI.setDataMode(SPI_MODE1); + SPI.setDataMode(SPI_MODE3); digitalWrite(cs_pin,_value); } From 12f0246ae0f972c10bb3c498f35ba22912378b54 Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Thu, 15 May 2014 11:43:02 -0600 Subject: [PATCH 06/11] Changed my additions to use the built-in cs function: pin + SPI_MODE --- RTC_DS3234.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/RTC_DS3234.cpp b/RTC_DS3234.cpp index 96c85d5e..94ac131f 100644 --- a/RTC_DS3234.cpp +++ b/RTC_DS3234.cpp @@ -1,6 +1,9 @@ // Code by JeeLabs http://news.jeelabs.org/code/ // Released to the public domain! Enjoy! +// SPI_MODE1 --> SPI_Mode3 by ADW; fails in my test if another SPI device is +// attached and it is in SPI_MODE1, even if that devices CSpin is OUTPUT, HIGH + #if ARDUINO < 100 #include #else @@ -123,13 +126,13 @@ void RTC_DS3234::set_alarm_1(const uint8_t s, const uint8_t mi, const uint8_t h, uint8_t i; for (i = 0; i <= 3; i++) { - digitalWrite(cs_pin, LOW); + cs(LOW); SPI.transfer(i + 0x87); if (i == 3) { SPI.transfer(dectobcd(t[3]) | (flags[3] << 7) | (flags[4] << 6)); } else SPI.transfer(dectobcd(t[i]) | (flags[i] << 7)); - digitalWrite(cs_pin, HIGH); + cs(HIGH); } } @@ -151,12 +154,12 @@ void RTC_DS3234::set_alarm_2(const uint8_t mi, const uint8_t h, const uint8_t d, for (i = 0; i <= 2; i++) { digitalWrite(cs_pin, LOW); - SPI.transfer(i + 0x8B); + cs(LOW); if (i == 2) { SPI.transfer(dectobcd(t[2]) | (flags[2] << 7) | (flags[3] << 6)); } else SPI.transfer(dectobcd(t[i]) | (flags[i] << 7)); - digitalWrite(cs_pin, HIGH); + cs(HIGH); } } @@ -165,15 +168,19 @@ void RTC_DS3234::enable_alarm(const uint8_t alarm_number) // and 2, which are also decimal 1 and 2: so just pass the number of that alarm // INTCN is the interrupt enable bit { + cs(LOW); set_addr(0x8E, INTCN | alarm_number); + cs(HIGH); } // when the alarm flag is cleared the pulldown on INT is also released void RTC_DS3234::clear_alarm_flag(const uint8_t alarm_number) { uint8_t reg_val; + cs(LOW); reg_val = get_addr(0x0F) & ~alarm_number; set_addr(0x8F, reg_val); + cs(HIGH); } // Temperature @@ -183,8 +190,10 @@ float RTC_DS3234::get_temperature_degC() uint8_t temp_msb, temp_lsb; int8_t nint; + cs(LOW); temp_msb = get_addr(0x11); temp_lsb = get_addr(0x12) >> 6; + cs(HIGH); if ((temp_msb & 0x80) != 0) nint = temp_msb | ~((1 << 8) - 1); // if negative get two's complement else @@ -200,20 +209,17 @@ float RTC_DS3234::get_temperature_degC() uint8_t RTC_DS3234::get_addr(const uint8_t addr) { uint8_t rv; - - digitalWrite(cs_pin, LOW); + // no CS here because it is being set outside of this function SPI.transfer(addr); rv = SPI.transfer(0x00); - digitalWrite(cs_pin, HIGH); return rv; } void RTC_DS3234::set_addr(const uint8_t addr, const uint8_t val) { - digitalWrite(cs_pin, LOW); + // no CS here because it is being set outside of this function SPI.transfer(addr); SPI.transfer(val); - digitalWrite(cs_pin, HIGH); } // helpers from DS3234 library by Petre Rodan -- just 1 now for setting the From 549c0dd3c7f4b3a12403891d5c2cc50baa63ad2e Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Thu, 15 May 2014 13:52:46 -0600 Subject: [PATCH 07/11] Turn CS off and on in subsidiary functions as well -- seems to be necessary, though I don't know why, when they are called in the middle of other functions that do this in a way that encompasses the sub-function call. --- RTC_DS3234.cpp | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/RTC_DS3234.cpp b/RTC_DS3234.cpp index 94ac131f..a9da0556 100644 --- a/RTC_DS3234.cpp +++ b/RTC_DS3234.cpp @@ -178,11 +178,38 @@ void RTC_DS3234::clear_alarm_flag(const uint8_t alarm_number) { uint8_t reg_val; cs(LOW); - reg_val = get_addr(0x0F) & ~alarm_number; - set_addr(0x8F, reg_val); + uint8_t addr_in = get_addr(0x0F); + reg_val = addr_in & ~alarm_number; + set_addr(0x8F, 0); cs(HIGH); } +/* +// Old one in case I did something wrong here +void Logger::DS3234_clear_a1f() +{ + uint8_t reg_val; + + DS3234_A1F = 0x1; + reg_val = DS3234_get_sreg(CSpinRTC) & ~DS3234_A1F; + DS3234_set_sreg(pin, reg_val); +} + +uint8_t Logger::DS3234_get_sreg(const uint8_t pin) +{ + uint8_t rv; + rv = DS3234_get_addr(pin, 0x0f); + return rv; +} + +void DS3234_set_sreg(const uint8_t pin, const uint8_t sreg) +{ + DS3234_set_addr(pin, 0x8F, sreg); +} +*/ + + + // Temperature float RTC_DS3234::get_temperature_degC() { @@ -209,17 +236,19 @@ float RTC_DS3234::get_temperature_degC() uint8_t RTC_DS3234::get_addr(const uint8_t addr) { uint8_t rv; - // no CS here because it is being set outside of this function + cs(LOW); // Somehow this is still needed in spite of the fact that this works within other functions that already do this... strange SPI.transfer(addr); rv = SPI.transfer(0x00); + cs(HIGH); return rv; } void RTC_DS3234::set_addr(const uint8_t addr, const uint8_t val) { - // no CS here because it is being set outside of this function + cs(LOW); // Somehow this is still needed in spite of the fact that this works within other functions that already do this... strange SPI.transfer(addr); SPI.transfer(val); + cs(HIGH); } // helpers from DS3234 library by Petre Rodan -- just 1 now for setting the From 14d99d236aa9ff19ab47aa7091fad504d1c02727 Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Fri, 16 May 2014 17:47:01 -0600 Subject: [PATCH 08/11] Functions for clock setting --- RTC_DS3234.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++---- RTC_DS3234.h | 26 +++++++++++- 2 files changed, 128 insertions(+), 8 deletions(-) diff --git a/RTC_DS3234.cpp b/RTC_DS3234.cpp index a9da0556..d0625fae 100644 --- a/RTC_DS3234.cpp +++ b/RTC_DS3234.cpp @@ -129,9 +129,9 @@ void RTC_DS3234::set_alarm_1(const uint8_t s, const uint8_t mi, const uint8_t h, cs(LOW); SPI.transfer(i + 0x87); if (i == 3) { - SPI.transfer(dectobcd(t[3]) | (flags[3] << 7) | (flags[4] << 6)); + SPI.transfer(decToBcd(t[3]) | (flags[3] << 7) | (flags[4] << 6)); } else - SPI.transfer(dectobcd(t[i]) | (flags[i] << 7)); + SPI.transfer(decToBcd(t[i]) | (flags[i] << 7)); cs(HIGH); } } @@ -156,9 +156,9 @@ void RTC_DS3234::set_alarm_2(const uint8_t mi, const uint8_t h, const uint8_t d, digitalWrite(cs_pin, LOW); cs(LOW); if (i == 2) { - SPI.transfer(dectobcd(t[2]) | (flags[2] << 7) | (flags[3] << 6)); + SPI.transfer(decToBcd(t[2]) | (flags[2] << 7) | (flags[3] << 6)); } else - SPI.transfer(dectobcd(t[i]) | (flags[i] << 7)); + SPI.transfer(decToBcd(t[i]) | (flags[i] << 7)); cs(HIGH); } } @@ -251,10 +251,10 @@ void RTC_DS3234::set_addr(const uint8_t addr, const uint8_t val) cs(HIGH); } -// helpers from DS3234 library by Petre Rodan -- just 1 now for setting the -// alarms +// helpers modified from the DS3234 library by Petre Rodan and the DS3231 +// library by Eric Ayars -- just 1 now for setting the alarms -uint8_t RTC_DS3234::dectobcd(const uint8_t val) +uint8_t RTC_DS3234::decToBcd(const uint8_t val) { return ((val / 10 * 16) + (val % 10)); } @@ -269,6 +269,102 @@ uint8_t RTC_DS3234::bcdtodec(const uint8_t val) // end helpers +// Clock-setting-related functions, based on Eric Ayars' DS3231 library +// and Andy Wickert's work with it for the ALog Bottle Logger + +void RTC_DS3234::setClockMode(bool h12) { + // sets the mode to 12-hour (true) or 24-hour (false). + // One thing that bothers me about how I've written this is that + // if the read and right happen at the right hourly millisecnd, + // the clock will be set back an hour. Not sure how to do it better, + // though, and as long as one doesn't set the mode frequently it's + // a very minimal risk. + // It's zero risk if you call this BEFORE setting the hour, since + // the setHour() function doesn't change this mode. + + uint8_t temp_buffer; + + cs(LOW); + // Start by reading byte 0x02. + temp_buffer = get_addr(0x02); + // Set the flag to the requested value: + if (h12) { + temp_buffer = temp_buffer | 0x01000000; + } + else { + temp_buffer = temp_buffer & 0x10111111; + } + // Write the byte + set_addr(0x02, temp_buffer); + cs(HIGH); + +} + +void RTC_DS3234::setSecond(byte Second) { + // Sets the seconds + // This function also resets the Oscillator Stop Flag, which is set + // whenever power is interrupted. + set_addr(0x80, decToBcd(Second)); + // Clear oscillator stop flag + byte temp_buffer = get_addr(0x0F); // read the control byte + set_addr(0x8F, temp_buffer & 0b01111111); +} + +void RTC_DS3234::setMinute(uint8_t Minute) { + // Sets the minutes + set_addr(0x81, decToBcd(Minute)); +} + +void RTC_DS3234::setHour(uint8_t Hour) { + // Sets the hour, without changing 12/24h mode. + // The hour must be in 24h format. + + // Start by figuring out what the 12/24 mode is + bool h12 = get_addr(0x02) & 0b01000000; + // if h12 is true, it's 12h mode; false is 24h. + + if (h12) { + // 12 hour + if (Hour > 12) + { + Hour = decToBcd(Hour-12) | 0b01100000; + } + else + { + Hour = decToBcd(Hour) & 0b11011111; + } + } + else + { + // 24 hour + Hour = decToBcd(Hour) & 0b10111111; + } + + set_addr(0x82, decToBcd(Hour)); +} + +void RTC_DS3234::setDoW(uint8_t DoW) { + // Sets the Day of Week + set_addr(0x83, decToBcd(DoW)); +} + +void RTC_DS3234::setDate(uint8_t Date) { + // Sets the Date + set_addr(0x84, decToBcd(Date)); +} + +void RTC_DS3234::setMonth(uint8_t Month) { + // Sets the month + set_addr(0x85, decToBcd(Month)); +} + +void RTC_DS3234::setYear(uint8_t Year) { + // Sets the year + set_addr(0x86, decToBcd(Year)); +} + +// End clock-setting functions based on Eric Ayars' DS3231 library + DateTime RTC_DS3234::now() { cs(LOW); diff --git a/RTC_DS3234.h b/RTC_DS3234.h index da2b4ed4..b12f6ae6 100644 --- a/RTC_DS3234.h +++ b/RTC_DS3234.h @@ -36,6 +36,30 @@ class RTC_DS3234 void enable_alarm(const uint8_t alarm_number); // Sets the bits to enable that alarm's interrupt; may inadvertently disable other alarm...? void clear_alarm_flag(const uint8_t alarm_number); // Clears alarm flags; release pulldown on INTERRUPT pin + // Time-setting functions + // Note that none of these check for sensibility: You can set the + // date to July 42nd and strange things will probably result. + + void setSecond(uint8_t Second); + // In addition to setting the seconds, this clears the + // "Oscillator Stop Flag". + void setMinute(uint8_t Minute); + // Sets the minute + void setHour(uint8_t Hour); + // Sets the hour + void setDoW(uint8_t DoW); + // Sets the Day of the Week (1-7); + void setDate(uint8_t Date); + // Sets the Date of the Month + void setMonth(uint8_t Month); + // Sets the Month of the year + void setYear(uint8_t Year); + // Last two digits of the year + void setClockMode(bool h12); + // Set 12/24h mode. True is 12-h, false is 24-hour. + + + protected: void cs(int _value); @@ -48,7 +72,7 @@ class RTC_DS3234 uint8_t get_addr(const uint8_t addr); void set_addr(const uint8_t addr, const uint8_t val); // Helpers - uint8_t dectobcd(const uint8_t); + uint8_t decToBcd(const uint8_t); //uint8_t bcdtodec(const uint8_t); // currently unused }; From b201f7ffe97ce97853deddc30397e6c53e46f091 Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Fri, 16 May 2014 17:53:44 -0600 Subject: [PATCH 09/11] Clock-setting example like the one that I modified for the DS3231 library --- examples/set_echo/set_echo.ino | 146 +++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 examples/set_echo/set_echo.ino diff --git a/examples/set_echo/set_echo.ino b/examples/set_echo/set_echo.ino new file mode 100644 index 00000000..b9e458d3 --- /dev/null +++ b/examples/set_echo/set_echo.ino @@ -0,0 +1,146 @@ +/* + +Sets the time and prints back time stamps for 5 seconds + +Based on DS3231_set.pde +by Eric Ayars +4/11 + +Added printing back of time stamps and increased baud rate +Andy Wickert +5/15/2011 + +Ported to the DS3234, using my modification of RTClib +Contribs in backwards order through time: +Andy Wickert, maniacbug, Petre Rodan, jeelabs, adafruit +5/16/2014 -- whoa, 3 years already! + +*/ + +#include +#include +#include +#include + +RTC_DS3234 Clock(47); + +byte Year; +byte Month; +byte Date; +byte DoW; +byte Hour; +byte Minute; +byte Second; + +bool Century=false; +bool h12; +bool PM; + +void GetDateStuff(byte& Year, byte& Month, byte& Day, byte& DoW, + byte& Hour, byte& Minute, byte& Second) { + // Call this if you notice something coming in on + // the serial port. The stuff coming in should be in + // the order YYMMDDwHHMMSS, with an 'x' at the end. + boolean GotString = false; + char InChar; + byte Temp1, Temp2; + char InString[20]; + + byte j=0; + while (!GotString) { + if (Serial.available()) { + InChar = Serial.read(); + InString[j] = InChar; + j += 1; + if (InChar == 'x') { + GotString = true; + } + } + } + Serial.println(InString); + // Read Year first + Temp1 = (byte)InString[0] -48; + Temp2 = (byte)InString[1] -48; + Year = Temp1*10 + Temp2; + // now month + Temp1 = (byte)InString[2] -48; + Temp2 = (byte)InString[3] -48; + Month = Temp1*10 + Temp2; + // now date + Temp1 = (byte)InString[4] -48; + Temp2 = (byte)InString[5] -48; + Day = Temp1*10 + Temp2; + // now Day of Week + DoW = (byte)InString[6] - 48; + // now Hour + Temp1 = (byte)InString[7] -48; + Temp2 = (byte)InString[8] -48; + Hour = Temp1*10 + Temp2; + // now Minute + Temp1 = (byte)InString[9] -48; + Temp2 = (byte)InString[10] -48; + Minute = Temp1*10 + Temp2; + // now Second + Temp1 = (byte)InString[11] -48; + Temp2 = (byte)InString[12] -48; + Second = Temp1*10 + Temp2; +} + +DateTime now; +const int len = 32; +static char buf[len]; + +void setup() { + // Start the serial port + Serial.begin(57600); + + // Start the I2C interface + SPI.begin(); + Clock.begin(); +} + +void loop() { + + // If something is coming in on the serial line, it's + // a time correction so set the clock accordingly. + if (Serial.available()) { + GetDateStuff(Year, Month, Date, DoW, Hour, Minute, Second); + + Serial.println(); + Serial.println("Transferred time from computer to board:"); + Serial.print(Year); + Serial.print(F("-")); + Serial.print(Month); + Serial.print(F("-")); + Serial.print(Date); + Serial.print(F(" ")); + Serial.print(Hour); //24-hr + Serial.print(F(":")); + Serial.print(Minute); + Serial.print(F(":")); + Serial.println(Second); + Serial.println(); + + Clock.setClockMode(false); // set to 24h + //setClockMode(true); // set to 12h + + Clock.setYear(Year); + Clock.setMonth(Month); + Clock.setDate(Date); + Clock.setDoW(DoW); + Clock.setHour(Hour); + Clock.setMinute(Minute); + Clock.setSecond(Second); + + // Give time at next five seconds + for (int i=0; i<5; i++){ + delay(1000); + now = Clock.now(); + Serial.println(now.unixtime()); + Serial.println(now.toString(buf,len)); + Serial.println(); + } + + } + delay(1000); +} From 9231a5dc8cd8de687cd14a1bf5f0b9e30962674c Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Fri, 16 May 2014 18:31:07 -0600 Subject: [PATCH 10/11] contrib order --- examples/set_echo/set_echo.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/set_echo/set_echo.ino b/examples/set_echo/set_echo.ino index b9e458d3..86bcbe7c 100644 --- a/examples/set_echo/set_echo.ino +++ b/examples/set_echo/set_echo.ino @@ -12,7 +12,7 @@ Andy Wickert Ported to the DS3234, using my modification of RTClib Contribs in backwards order through time: -Andy Wickert, maniacbug, Petre Rodan, jeelabs, adafruit +Andy Wickert, maniacbug, Petre Rodan, adafruit, jeelabs 5/16/2014 -- whoa, 3 years already! */ From e8d3b6d9a3963c61dc12ab2b0362bb7e0417776c Mon Sep 17 00:00:00 2001 From: Andy Wickert Date: Tue, 10 Jun 2014 14:32:02 -0600 Subject: [PATCH 11/11] Used function to switch from int to DS3234 registers twice by mistake for setting hours: removed second instance and now working correctly. --- RTC_DS3234.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RTC_DS3234.cpp b/RTC_DS3234.cpp index d0625fae..7d4a00d6 100644 --- a/RTC_DS3234.cpp +++ b/RTC_DS3234.cpp @@ -340,7 +340,7 @@ void RTC_DS3234::setHour(uint8_t Hour) { Hour = decToBcd(Hour) & 0b10111111; } - set_addr(0x82, decToBcd(Hour)); + set_addr(0x82, Hour); } void RTC_DS3234::setDoW(uint8_t DoW) {