Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Fixing leap year, year < 2000, optimising #9

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 0 additions & 17 deletions README

This file was deleted.

20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# DS3231 library for the Arduino.

This library implements the following features:

* read/write of current time, both of the alarms, control/status registers, aging register
* read of the temperature register, and of any address from the chip.

Original Author : Petre Rodan <petre.rodan@simplex.ro>
Maintainer : Jorropo <jorropo.pgm@gmail.com>
Available from : https://github.com/Jorropo/ds3231
Original Repo : https://github.com/rodan/ds3231
License : GNU GPLv3

The DS3231 is a low-cost, extremely accurate I2C real-time clock
(RTC) with an integrated temperature-compensated crystal oscillator
(TCXO) and crystal.

Petre Rodan where original maintainer but it seems to be inactive.

## You can activate unix timestamp in config.h
8 changes: 4 additions & 4 deletions config.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef __config_h_
#define __config_h_
#define __config_h_

// comment this out if you need unixtime support
// this will add about 324bytes to your firmware
//#define CONFIG_UNIXTIME
// comment this out if you need unixtime support
// this will add about 756 bytes to your firmware
//#define CONFIG_UNIXTIME

#endif
64 changes: 21 additions & 43 deletions ds3231.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@

This library implements the following features:

- read/write of current time, both of the alarms,
- read/write of current time, both of the alarms,
control/status registers, aging register
- read of the temperature register, and of any address from the chip.

Author: Petre Rodan <petre.rodan@simplex.ro>
Available from: https://github.com/rodan/ds3231
The DS3231 is a low-cost, extremely accurate I2C real-time clock
(RTC) with an integrated temperature-compensated crystal oscillator

The DS3231 is a low-cost, extremely accurate I2C real-time clock
(RTC) with an integrated temperature-compensated crystal oscillator
(TCXO) and crystal.

GNU GPLv3 license:

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

*/

#include <Wire.h>
Expand All @@ -45,7 +45,7 @@
#endif
#else
#define PROGMEM
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
//#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#endif

/* control register 0Eh/8Eh
Expand All @@ -68,7 +68,7 @@ void DS3231_set(struct ts t)
{
uint8_t i, century;

if (t.year >= 2000) {
if (t.year > 1999) {
century = 0x80;
t.year_s = t.year - 2000;
} else {
Expand All @@ -80,7 +80,7 @@ void DS3231_set(struct ts t)

Wire.beginTransmission(DS3231_I2C_ADDR);
Wire.write(DS3231_TIME_CAL_ADDR);
for (i = 0; i <= 6; i++) {
for (i = 0; i < 7; i++) {
TimeDate[i] = dectobcd(TimeDate[i]);
if (i == 5)
TimeDate[5] += century;
Expand All @@ -102,7 +102,7 @@ void DS3231_get(struct ts *t)

Wire.requestFrom(DS3231_I2C_ADDR, 7);

for (i = 0; i <= 6; i++) {
for (i = 0; i < 7; i++) {
n = Wire.read();
if (i == 5) {
TimeDate[5] = bcdtodec(n & 0x1F);
Expand Down Expand Up @@ -240,7 +240,7 @@ float DS3231_get_treg()

// alarms

// flags are: A1M1 (seconds), A1M2 (minutes), A1M3 (hour),
// flags are: A1M1 (seconds), A1M2 (minutes), A1M3 (hour),
// A1M4 (day) 0 to enable, 1 to disable, DY/DT (dayofweek == 1/dayofmonth == 0)
void DS3231_set_a1(const uint8_t s, const uint8_t mi, const uint8_t h, const uint8_t d, const uint8_t * flags)
{
Expand All @@ -250,7 +250,7 @@ void DS3231_set_a1(const uint8_t s, const uint8_t mi, const uint8_t h, const uin
Wire.beginTransmission(DS3231_I2C_ADDR);
Wire.write(DS3231_ALARM1_ADDR);

for (i = 0; i <= 3; i++) {
for (i = 0; i < 4; i++) {
if (i == 3) {
Wire.write(dectobcd(t[3]) | (flags[3] << 7) | (flags[4] << 6));
} else
Expand All @@ -273,7 +273,7 @@ void DS3231_get_a1(char *buf, const uint8_t len)

Wire.requestFrom(DS3231_I2C_ADDR, 4);

for (i = 0; i <= 3; i++) {
for (i = 0; i < 4; i++) {
n[i] = Wire.read();
f[i] = (n[i] & 0x80) >> 7;
t[i] = bcdtodec(n[i] & 0x7F);
Expand Down Expand Up @@ -303,7 +303,7 @@ uint8_t DS3231_triggered_a1(void)
return DS3231_get_sreg() & DS3231_A1F;
}

// flags are: A2M2 (minutes), A2M3 (hour), A2M4 (day) 0 to enable, 1 to disable, DY/DT (dayofweek == 1/dayofmonth == 0) -
// flags are: A2M2 (minutes), A2M3 (hour), A2M4 (day) 0 to enable, 1 to disable, DY/DT (dayofweek == 1/dayofmonth == 0) -
void DS3231_set_a2(const uint8_t mi, const uint8_t h, const uint8_t d, const uint8_t * flags)
{
uint8_t t[3] = { mi, h, d };
Expand All @@ -312,7 +312,7 @@ void DS3231_set_a2(const uint8_t mi, const uint8_t h, const uint8_t d, const uin
Wire.beginTransmission(DS3231_I2C_ADDR);
Wire.write(DS3231_ALARM2_ADDR);

for (i = 0; i <= 2; i++) {
for (i = 0; i < 3; i++) {
if (i == 2) {
Wire.write(dectobcd(t[2]) | (flags[2] << 7) | (flags[3] << 6));
} else
Expand All @@ -335,7 +335,7 @@ void DS3231_get_a2(char *buf, const uint8_t len)

Wire.requestFrom(DS3231_I2C_ADDR, 3);

for (i = 0; i <= 2; i++) {
for (i = 0; i < 3; i++) {
n[i] = Wire.read();
f[i] = (n[i] & 0x80) >> 7;
t[i] = bcdtodec(n[i] & 0x7F);
Expand Down Expand Up @@ -366,33 +366,12 @@ uint8_t DS3231_triggered_a2(void)
// helpers

#ifdef CONFIG_UNIXTIME
const uint8_t days_in_month [12] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };

// returns the number of seconds since 01.01.1970 00:00:00 UTC, valid for 2000..FIXME
uint32_t get_unixtime(struct ts t)
{
uint8_t i;
uint16_t d;
int16_t y;
uint32_t rv;

if (t.year >= 2000) {
y = t.year - 2000;
} else {
return 0;
}

d = t.mday - 1;
for (i=1; i<t.mon; i++) {
d += pgm_read_byte(days_in_month + i - 1);
}
if (t.mon > 2 && y % 4 == 0) {
d++;
}
// count leap days
d += (365 * y + (y + 3) / 4);
rv = ((d * 24UL + t.hour) * 60 + t.min) * 60 + t.sec + SECONDS_FROM_1970_TO_2000;
return rv;
uint16_t y;
y = t.year - 1600; // cause this is the first year < at 1970 where year % 400 = 0
return (t.year - 1970) * 31536000 + (t.yday - 1 + (y / 4) - (y / 100) + (y / 400) - 89) * 86400 + t.hour * 3600 + t.min * 60 + t.sec;
}
#endif

Expand All @@ -412,4 +391,3 @@ uint8_t inp2toi(char *cmd, const uint16_t seek)
rv = (cmd[seek] - 48) * 10 + cmd[seek + 1] - 48;
return rv;
}

50 changes: 49 additions & 1 deletion ds3231.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
#define DS3231_A2F 0x2
#define DS3231_OSF 0x80


#ifndef DS3231_NEWLIB
//If not defined, use the old library
struct ts {
uint8_t sec; /* seconds */
uint8_t min; /* minutes */
Expand Down Expand Up @@ -87,4 +88,51 @@ uint8_t dectobcd(const uint8_t val);
uint8_t bcdtodec(const uint8_t val);
uint8_t inp2toi(char *cmd, const uint16_t seek);

#else
//Use the new one
class DS3231{
public:
DS3231();
~DS3231();
void init(const uint8_t creg);
void set(struct ts t);
void get(struct ts *t);

void set_addr(const uint8_t addr, const uint8_t val);
uint8_t get_addr(const uint8_t addr);

// control/status register
void set_creg(const uint8_t val);
void set_sreg(const uint8_t val);
uint8_t get_sreg(void);

// aging offset register
void set_aging(const int8_t val);
int8_t get_aging(void);

// temperature register
float get_treg(void);

// alarms
void set_a1(const uint8_t s, const uint8_t mi, const uint8_t h, const uint8_t d,
const uint8_t * flags);
void get_a1(char *buf, const uint8_t len);
void clear_a1f(void);
uint8_t triggered_a1(void);

void set_a2(const uint8_t mi, const uint8_t h, const uint8_t d, const uint8_t * flags);
void get_a2(char *buf, const uint8_t len);
void clear_a2f(void);
uint8_t triggered_a2(void);

// helpers
private:
uint32_t get_unixtime(struct ts t);
uint8_t dectobcd(const uint8_t val);
uint8_t bcdtodec(const uint8_t val);
uint8_t inp2toi(char *cmd, const uint16_t seek);

};

#endif //DS3231_NEWLIB
#endif
12 changes: 0 additions & 12 deletions examples/rtc_ds3231/Makefile

This file was deleted.

12 changes: 0 additions & 12 deletions examples/rtc_ds3231_alarm/Makefile

This file was deleted.

9 changes: 0 additions & 9 deletions examples/rtc_ds3231_alarm_every_5m/Makefile

This file was deleted.

33 changes: 33 additions & 0 deletions examples/simple_print/simple_print.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <Wire.h>
#include <ds3231.h>

ts t;

void setup() {
Wire.begin();
DS3231_init(DS3231_INTCN);
Serial.begin(9600);
while(!Serial){}
}

void loop() {
DS3231_get(&t);
Serial.print("Day : ");
Serial.print(t.mon);
Serial.print("/");
Serial.print(t.mday);
Serial.print("/");
Serial.println(t.year);
Serial.print("Hour : ");
Serial.print(t.hour);
Serial.print(":");
Serial.print(t.min);
Serial.print(".");
Serial.println(t.sec);
#ifdef CONFIG_UNIXTIME
Serial.print("Timestamp : ");
Serial.print(t.unixtime);
#endif
Serial.println();
delay(1000);
}
14 changes: 14 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
DS3232 KEYWORD1
begin KEYWORD2
get KEYWORD2
set KEYWORD2
read KEYWORD2
write KEYWORD2
writeRTC KEYWORD2
readRTC KEYWORD2
setAlarm KEYWORD2
alarmInterrupt KEYWORD2
alarm KEYWORD2
squareWave KEYWORD2
oscStopped KEYWORD2
temperature KEYWORD2