Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

First commit

  • Loading branch information...
commit f8a1ab0d65f84a18c42ff398da2520c3a63230b7 0 parents
Limor "Ladyada" Fried authored March 11, 2010
166  RTClib.cpp
... ...
@@ -0,0 +1,166 @@
  1
+#include <Wire.h>
  2
+#include <avr/pgmspace.h>
  3
+#include "RTClib.h"
  4
+#include <WProgram.h>
  5
+
  6
+#define DS1307_ADDRESS 0x68
  7
+#define SECONDS_PER_DAY 86400L
  8
+
  9
+////////////////////////////////////////////////////////////////////////////////
  10
+// utility code, some of this could be exposed in the DateTime API if needed
  11
+
  12
+static uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  13
+
  14
+// number of days since 2000/01/01, valid for 2001..2099
  15
+static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
  16
+    if (y >= 2000)
  17
+        y -= 2000;
  18
+    uint16_t days = d;
  19
+    for (uint8_t i = 1; i < m; ++i)
  20
+        days += pgm_read_byte(daysInMonth + i - 1);
  21
+    if (m > 2 && y % 4 == 0)
  22
+        ++days;
  23
+    return days + 365 * y + (y + 3) / 4 - 1;
  24
+}
  25
+
  26
+static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
  27
+    return ((days * 24L + h) * 60 + m) * 60 + s;
  28
+}
  29
+
  30
+////////////////////////////////////////////////////////////////////////////////
  31
+// DateTime implementation - ignores time zones and DST changes
  32
+// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second
  33
+
  34
+DateTime::DateTime (long t) {
  35
+    ss = t % 60;
  36
+    t /= 60;
  37
+    mm = t % 60;
  38
+    t /= 60;
  39
+    hh = t % 24;
  40
+    uint16_t days = t / 24;
  41
+    uint8_t leap;
  42
+    for (yOff = 0; ; ++yOff) {
  43
+        leap = yOff % 4 == 0;
  44
+        if (days < 365 + leap)
  45
+            break;
  46
+        days -= 365 + leap;
  47
+    }
  48
+    for (m = 1; ; ++m) {
  49
+        uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1);
  50
+        if (leap && m == 2)
  51
+            ++daysPerMonth;
  52
+        if (days < daysPerMonth)
  53
+            break;
  54
+        days -= daysPerMonth;
  55
+    }
  56
+    d = days + 1;
  57
+}
  58
+
  59
+DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
  60
+    if (year >= 2000)
  61
+        year -= 2000;
  62
+    yOff = year;
  63
+    m = month;
  64
+    d = day;
  65
+    hh = hour;
  66
+    mm = min;
  67
+    ss = sec;
  68
+}
  69
+
  70
+static uint8_t conv2d(const char* p) {
  71
+    uint8_t v = 0;
  72
+    if ('0' <= *p && *p <= '9')
  73
+        v = *p - '0';
  74
+    return 10 * v + *++p - '0';
  75
+}
  76
+
  77
+// A convenient constructor for using "the compiler's time":
  78
+//   DateTime now (__DATE__, __TIME__);
  79
+// NOTE: using PSTR would further reduce the RAM footprint
  80
+DateTime::DateTime (const char* date, const char* time) {
  81
+    // sample input: date = "Dec 26 2009", time = "12:34:56"
  82
+    yOff = conv2d(date + 9);
  83
+    // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 
  84
+    switch (date[0]) {
  85
+        case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break;
  86
+        case 'F': m = 2; break;
  87
+        case 'A': m = date[2] == 'r' ? 4 : 8; break;
  88
+        case 'M': m = date[2] == 'r' ? 3 : 5; break;
  89
+        case 'S': m = 9; break;
  90
+        case 'O': m = 10; break;
  91
+        case 'N': m = 11; break;
  92
+        case 'D': m = 12; break;
  93
+    }
  94
+    d = conv2d(date + 4);
  95
+    hh = conv2d(time);
  96
+    mm = conv2d(time + 3);
  97
+    ss = conv2d(time + 6);
  98
+}
  99
+
  100
+uint8_t DateTime::dayOfWeek() const {    
  101
+    uint16_t day = get() / SECONDS_PER_DAY;
  102
+    return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
  103
+}
  104
+
  105
+long DateTime::get() const {
  106
+    uint16_t days = date2days(yOff, m, d);
  107
+    return time2long(days, hh, mm, ss);
  108
+}
  109
+
  110
+////////////////////////////////////////////////////////////////////////////////
  111
+// RTC_DS1307 implementation
  112
+
  113
+static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
  114
+static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }
  115
+
  116
+uint8_t RTC_DS1307::begin(void) {
  117
+  return 1;
  118
+
  119
+
  120
+}
  121
+
  122
+void RTC_DS1307::adjust(const DateTime& dt) {
  123
+    Wire.beginTransmission(DS1307_ADDRESS);
  124
+    Wire.send(0);
  125
+    Wire.send(bin2bcd(dt.second()));
  126
+    Wire.send(bin2bcd(dt.minute()));
  127
+    Wire.send(bin2bcd(dt.hour()));
  128
+    Wire.send(bin2bcd(0));
  129
+    Wire.send(bin2bcd(dt.day()));
  130
+    Wire.send(bin2bcd(dt.month()));
  131
+    Wire.send(bin2bcd(dt.year() - 2000));
  132
+    Wire.send(0);
  133
+    Wire.endTransmission();
  134
+}
  135
+
  136
+DateTime RTC_DS1307::now() {
  137
+  	Wire.beginTransmission(DS1307_ADDRESS);
  138
+  	Wire.send(0);	
  139
+    Wire.endTransmission();
  140
+
  141
+    Wire.requestFrom(DS1307_ADDRESS, 7);
  142
+    uint8_t ss = bcd2bin(Wire.receive());
  143
+    uint8_t mm = bcd2bin(Wire.receive());
  144
+    uint8_t hh = bcd2bin(Wire.receive());
  145
+    Wire.receive();
  146
+    uint8_t d = bcd2bin(Wire.receive());
  147
+    uint8_t m = bcd2bin(Wire.receive());
  148
+    uint16_t y = bcd2bin(Wire.receive()) + 2000;
  149
+    
  150
+    return DateTime (y, m, d, hh, mm, ss);
  151
+}
  152
+
  153
+////////////////////////////////////////////////////////////////////////////////
  154
+// RTC_Millis implementation
  155
+
  156
+long RTC_Millis::offset = 0;
  157
+
  158
+void RTC_Millis::adjust(const DateTime& dt) {
  159
+    offset = dt.get() - millis() / 1000;
  160
+}
  161
+
  162
+DateTime RTC_Millis::now() {
  163
+    return offset + millis() / 1000;
  164
+}
  165
+
  166
+////////////////////////////////////////////////////////////////////////////////
42  RTClib.h
... ...
@@ -0,0 +1,42 @@
  1
+// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
  2
+class DateTime {
  3
+public:
  4
+    DateTime (long t =0);
  5
+    DateTime (uint16_t year, uint8_t month, uint8_t day,
  6
+                uint8_t hour =0, uint8_t min =0, uint8_t sec =0);
  7
+    DateTime (const char* date, const char* time);
  8
+
  9
+    uint16_t year() const       { return 2000 + yOff; }
  10
+    uint8_t month() const       { return m; }
  11
+    uint8_t day() const         { return d; }
  12
+    uint8_t hour() const        { return hh; }
  13
+    uint8_t minute() const      { return mm; }
  14
+    uint8_t second() const      { return ss; }
  15
+    uint8_t dayOfWeek() const;
  16
+
  17
+    // 32-bit times as seconds since 1/1/2000
  18
+    long get() const;   
  19
+
  20
+protected:
  21
+    uint8_t yOff, m, d, hh, mm, ss;
  22
+};
  23
+
  24
+// RTC based on the DS1307 chip connected via I2C and the Wire library
  25
+class RTC_DS1307 {
  26
+public:
  27
+  static uint8_t begin(void);
  28
+    static void adjust(const DateTime& dt);
  29
+    static DateTime now();
  30
+};
  31
+
  32
+// RTC using the internal millis() clock, has to be initialized before use
  33
+// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?)
  34
+class RTC_Millis {
  35
+public:
  36
+    static void begin(const DateTime& dt) { adjust(dt); }
  37
+    static void adjust(const DateTime& dt);
  38
+    static DateTime now();
  39
+
  40
+protected:
  41
+    static long offset;
  42
+};
65  examples/datecalc/datecalc.pde
... ...
@@ -0,0 +1,65 @@
  1
+// Simple date conversions and calculations
  2
+
  3
+#include <Wire.h>
  4
+#include "RTClib.h"
  5
+
  6
+void showDate(const char* txt, const DateTime& dt) {
  7
+    Serial.print(txt);
  8
+    Serial.print(' ');
  9
+    Serial.print(dt.year(), DEC);
  10
+    Serial.print('/');
  11
+    Serial.print(dt.month(), DEC);
  12
+    Serial.print('/');
  13
+    Serial.print(dt.day(), DEC);
  14
+    Serial.print(' ');
  15
+    Serial.print(dt.hour(), DEC);
  16
+    Serial.print(':');
  17
+    Serial.print(dt.minute(), DEC);
  18
+    Serial.print(':');
  19
+    Serial.print(dt.second(), DEC);
  20
+    
  21
+    Serial.print(" = ");
  22
+    Serial.print(dt.get());
  23
+    Serial.print("s / ");
  24
+    Serial.print(dt.get() / 86400L);
  25
+    Serial.print("d since 2000");
  26
+    
  27
+    Serial.println();
  28
+}
  29
+
  30
+void setup () {
  31
+    Serial.begin(57600);
  32
+    
  33
+    DateTime dt0 (0, 1, 1, 0, 0, 0);
  34
+    showDate("dt0", dt0);
  35
+
  36
+    DateTime dt1 (1, 1, 1, 0, 0, 0);
  37
+    showDate("dt1", dt1);
  38
+
  39
+    DateTime dt2 (2009, 1, 1, 0, 0, 0);
  40
+    showDate("dt2", dt2);
  41
+
  42
+    DateTime dt3 (2009, 1, 2, 0, 0, 0);
  43
+    showDate("dt3", dt3);
  44
+
  45
+    DateTime dt4 (2009, 1, 27, 0, 0, 0);
  46
+    showDate("dt4", dt4);
  47
+
  48
+    DateTime dt5 (2009, 2, 27, 0, 0, 0);
  49
+    showDate("dt5", dt5);
  50
+
  51
+    DateTime dt6 (2009, 12, 27, 0, 0, 0);
  52
+    showDate("dt6", dt6);
  53
+
  54
+    DateTime dt7 (dt6.get() + 3600); // one hour later
  55
+    showDate("dt7", dt7);
  56
+
  57
+    DateTime dt8 (dt6.get() + 86400L); // one day later
  58
+    showDate("dt8", dt8);
  59
+
  60
+    DateTime dt9 (dt6.get() + 7 * 86400L); // one week later
  61
+    showDate("dt9", dt9);
  62
+}
  63
+
  64
+void loop () {
  65
+}
58  examples/ds1307/ds1307.pde
... ...
@@ -0,0 +1,58 @@
  1
+// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
  2
+
  3
+#include <Wire.h>
  4
+#include "RTClib.h"
  5
+
  6
+RTC_DS1307 RTC;
  7
+
  8
+void setup () {
  9
+    Serial.begin(57600);
  10
+    Wire.begin();
  11
+    RTC.begin();
  12
+    
  13
+    // following line sets the RTC to the date & time this sketch was compiled
  14
+    //RTC.adjust(DateTime(__DATE__, __TIME__));
  15
+}
  16
+
  17
+void loop () {
  18
+    DateTime now = RTC.now();
  19
+    
  20
+    Serial.print(now.year(), DEC);
  21
+    Serial.print('/');
  22
+    Serial.print(now.month(), DEC);
  23
+    Serial.print('/');
  24
+    Serial.print(now.day(), DEC);
  25
+    Serial.print(' ');
  26
+    Serial.print(now.hour(), DEC);
  27
+    Serial.print(':');
  28
+    Serial.print(now.minute(), DEC);
  29
+    Serial.print(':');
  30
+    Serial.print(now.second(), DEC);
  31
+    Serial.println();
  32
+    
  33
+    Serial.print(" since 2000 = ");
  34
+    Serial.print(now.get());
  35
+    Serial.print("s = ");
  36
+    Serial.print(now.get() / 86400L);
  37
+    Serial.println("d");
  38
+    
  39
+    // calculate a date which is 7 days and 30 seconds into the future
  40
+    DateTime future (now.get() + 7 * 86400L + 30);
  41
+    
  42
+    Serial.print(" now + 7d + 30s: ");
  43
+    Serial.print(future.year(), DEC);
  44
+    Serial.print('/');
  45
+    Serial.print(future.month(), DEC);
  46
+    Serial.print('/');
  47
+    Serial.print(future.day(), DEC);
  48
+    Serial.print(' ');
  49
+    Serial.print(future.hour(), DEC);
  50
+    Serial.print(':');
  51
+    Serial.print(future.minute(), DEC);
  52
+    Serial.print(':');
  53
+    Serial.print(future.second(), DEC);
  54
+    Serial.println();
  55
+    
  56
+    Serial.println();
  57
+    delay(3000);
  58
+}
52  examples/softrtc/softrtc.pde
... ...
@@ -0,0 +1,52 @@
  1
+// Date and time functions using just software, based on millis() & timer
  2
+
  3
+#include <Wire.h>
  4
+#include "RTClib.h"
  5
+
  6
+RTC_Millis RTC;
  7
+
  8
+void setup () {
  9
+    Serial.begin(57600);
  10
+    // following line sets the RTC to the date & time this sketch was compiled
  11
+    RTC.begin(DateTime(__DATE__, __TIME__));
  12
+}
  13
+
  14
+void loop () {
  15
+    DateTime now = RTC.now();
  16
+    
  17
+    Serial.print(now.year(), DEC);
  18
+    Serial.print('/');
  19
+    Serial.print(now.month(), DEC);
  20
+    Serial.print('/');
  21
+    Serial.print(now.day(), DEC);
  22
+    Serial.print(' ');
  23
+    Serial.print(now.hour(), DEC);
  24
+    Serial.print(':');
  25
+    Serial.print(now.minute(), DEC);
  26
+    Serial.print(':');
  27
+    Serial.print(now.second(), DEC);
  28
+    Serial.println();
  29
+    
  30
+    Serial.print(" seconds since 2000: ");
  31
+    Serial.println(now.get());
  32
+    
  33
+    // calculate a date which is 7 days and 30 seconds into the future
  34
+    DateTime future (now.get() + 7 * 86400L + 30);
  35
+    
  36
+    Serial.print(" now + 7d + 30s: ");
  37
+    Serial.print(future.year(), DEC);
  38
+    Serial.print('/');
  39
+    Serial.print(future.month(), DEC);
  40
+    Serial.print('/');
  41
+    Serial.print(future.day(), DEC);
  42
+    Serial.print(' ');
  43
+    Serial.print(future.hour(), DEC);
  44
+    Serial.print(':');
  45
+    Serial.print(future.minute(), DEC);
  46
+    Serial.print(':');
  47
+    Serial.print(future.second(), DEC);
  48
+    Serial.println();
  49
+    
  50
+    Serial.println();
  51
+    delay(3000);
  52
+}

0 notes on commit f8a1ab0

Please sign in to comment.
Something went wrong with that request. Please try again.