├── .gitignore ├── RTC_DS1307.h ├── RTC_DS3234.h ├── examples ├── softrtc │ └── softrtc.pde ├── ds3234 │ ├── ds3234.pde │ └── Jamfile ├── datecalc │ └── datecalc.pde └── ds1307 │ ├── ds1307.pde │ └── Jamfile ├── RTClib.h ├── RTC_DS1307.cpp ├── RTC_DS3234.cpp └── RTClib.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.orig 3 | .*.swp 4 | ojam/ 5 | 16000000/ 6 | version.h 7 | -------------------------------------------------------------------------------- /RTC_DS1307.h: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | 4 | #ifndef __RTC_DS1307_H__ 5 | #define __RTC_DS1307_H__ 6 | 7 | #include 8 | 9 | // RTC based on the DS1307 chip connected via I2C and the Wire library 10 | class RTC_DS1307 11 | { 12 | public: 13 | static uint8_t begin(void); 14 | static void adjust(const DateTime& dt); 15 | uint8_t isrunning(void); 16 | static DateTime now(); 17 | }; 18 | 19 | #endif // __RTC_DS1307_H__ 20 | 21 | // vim:ci:sw=4 sts=4 ft=cpp 22 | -------------------------------------------------------------------------------- /RTC_DS3234.h: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | 4 | #ifndef __RTC_DS3234_H__ 5 | #define __RTC_DS3234_H__ 6 | 7 | #include 8 | 9 | // RTC based on the DS3234 chip connected via SPI and the SPI library 10 | class RTC_DS3234 11 | { 12 | public: 13 | RTC_DS3234(int _cs_pin): cs_pin(_cs_pin) {} 14 | uint8_t begin(void); 15 | void adjust(const DateTime& dt); 16 | uint8_t isrunning(void); 17 | DateTime now(); 18 | 19 | protected: 20 | void cs(int _value); 21 | 22 | private: 23 | int cs_pin; 24 | }; 25 | 26 | #endif // __RTC_DS3234_H__ 27 | 28 | // vim:ai:cin:sw=4 sts=4 ft=cpp 29 | -------------------------------------------------------------------------------- /examples/softrtc/softrtc.pde: -------------------------------------------------------------------------------- 1 | // Date and time functions using just software, based on millis() & timer 2 | 3 | #include 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 1970: "); 31 | Serial.println(now.unixtime()); 32 | 33 | // calculate a date which is 7 days and 30 seconds into the future 34 | DateTime future (now.unixtime() + 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 | } 53 | -------------------------------------------------------------------------------- /examples/ds3234/ds3234.pde: -------------------------------------------------------------------------------- 1 | // Date and time functions using a DS1307 RTC connected via I2C and Wire lib 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Avoid spurious warnings 9 | #undef PROGMEM 10 | #define PROGMEM __attribute__(( section(".progmem.data") )) 11 | #undef PSTR 12 | #define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];})) 13 | 14 | // Create an RTC instance, using the chip select pin it's connected to 15 | RTC_DS3234 RTC(8); 16 | 17 | void setup () { 18 | Serial.begin(57600); 19 | Serial.println("RTClib/examples/ds3234/"); 20 | SPI.begin(); 21 | RTC.begin(); 22 | 23 | if (! RTC.isrunning()) { 24 | Serial.println("RTC is NOT running!"); 25 | Serial.print("Setting time to... "); 26 | Serial.print(__DATE__); 27 | Serial.print(' '); 28 | Serial.println(__TIME__); 29 | // following line sets the RTC to the date & time this sketch was compiled 30 | RTC.adjust(DateTime(__DATE__, __TIME__)); 31 | } 32 | } 33 | 34 | void loop () { 35 | const int len = 32; 36 | static char buf[len]; 37 | 38 | DateTime now = RTC.now(); 39 | 40 | Serial.println(now.toString(buf,len)); 41 | 42 | Serial.print(" since midnight 1/1/1970 = "); 43 | Serial.print(now.unixtime()); 44 | Serial.print("s = "); 45 | Serial.print(now.unixtime() / 86400L); 46 | Serial.println("d"); 47 | 48 | // calculate a date which is 7 days and 30 seconds into the future 49 | DateTime future (now.unixtime() + 7 * 86400L + 30 ); 50 | 51 | Serial.print(" now + 7d + 30s: "); 52 | Serial.println(future.toString(buf,len)); 53 | 54 | Serial.println(); 55 | delay(3000); 56 | } 57 | // vim:cin:ai:sw=4 sts=4 ft=cpp 58 | -------------------------------------------------------------------------------- /examples/datecalc/datecalc.pde: -------------------------------------------------------------------------------- 1 | // Simple date conversions and calculations 2 | 3 | #include 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.unixtime()); 23 | Serial.print("s / "); 24 | Serial.print(dt.unixtime() / 86400L); 25 | Serial.print("d since 1970"); 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.unixtime() + 3600); // one hour later 55 | showDate("dt7", dt7); 56 | 57 | DateTime dt8 (dt6.unixtime() + 86400L); // one day later 58 | showDate("dt8", dt8); 59 | 60 | DateTime dt9 (dt6.unixtime() + 7 * 86400L); // one week later 61 | showDate("dt9", dt9); 62 | } 63 | 64 | void loop () { 65 | } 66 | -------------------------------------------------------------------------------- /examples/ds1307/ds1307.pde: -------------------------------------------------------------------------------- 1 | // Date and time functions using a DS1307 RTC connected via I2C and Wire lib 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | RTC_DS1307 RTC; 9 | 10 | void setup () { 11 | Serial.begin(57600); 12 | Wire.begin(); 13 | RTC.begin(); 14 | 15 | if (! RTC.isrunning()) { 16 | Serial.println("RTC is NOT running!"); 17 | // following line sets the RTC to the date & time this sketch was compiled 18 | RTC.adjust(DateTime(__DATE__, __TIME__)); 19 | } 20 | } 21 | 22 | void loop () { 23 | DateTime now = RTC.now(); 24 | 25 | Serial.print(now.year(), DEC); 26 | Serial.print('/'); 27 | Serial.print(now.month(), DEC); 28 | Serial.print('/'); 29 | Serial.print(now.day(), DEC); 30 | Serial.print(' '); 31 | Serial.print(now.hour(), DEC); 32 | Serial.print(':'); 33 | Serial.print(now.minute(), DEC); 34 | Serial.print(':'); 35 | Serial.print(now.second(), DEC); 36 | Serial.println(); 37 | 38 | Serial.print(" since midnight 1/1/1970 = "); 39 | Serial.print(now.unixtime()); 40 | Serial.print("s = "); 41 | Serial.print(now.unixtime() / 86400L); 42 | Serial.println("d"); 43 | 44 | // calculate a date which is 7 days and 30 seconds into the future 45 | DateTime future (now.unixtime() + 7 * 86400L + 30); 46 | 47 | Serial.print(" now + 7d + 30s: "); 48 | Serial.print(future.year(), DEC); 49 | Serial.print('/'); 50 | Serial.print(future.month(), DEC); 51 | Serial.print('/'); 52 | Serial.print(future.day(), DEC); 53 | Serial.print(' '); 54 | Serial.print(future.hour(), DEC); 55 | Serial.print(':'); 56 | Serial.print(future.minute(), DEC); 57 | Serial.print(':'); 58 | Serial.print(future.second(), DEC); 59 | Serial.println(); 60 | 61 | Serial.println(); 62 | delay(3000); 63 | } 64 | // vim:ci:sw=4 sts=4 ft=cpp 65 | -------------------------------------------------------------------------------- /RTClib.h: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | 4 | #ifndef __RTCLIB_H__ 5 | #define __RTCLIB_H__ 6 | 7 | // Simple general-purpose date/time class (no TZ / DST / leap second handling!) 8 | class DateTime 9 | { 10 | public: 11 | DateTime (uint32_t t =0); 12 | DateTime (uint16_t year, uint8_t month, uint8_t day, 13 | uint8_t hour =0, uint8_t min =0, uint8_t sec =0); 14 | DateTime (const char* date, const char* time); 15 | uint16_t year() const 16 | { 17 | return 2000 + yOff; 18 | } 19 | uint8_t month() const 20 | { 21 | return m; 22 | } 23 | uint8_t day() const 24 | { 25 | return d; 26 | } 27 | uint8_t hour() const 28 | { 29 | return hh; 30 | } 31 | uint8_t minute() const 32 | { 33 | return mm; 34 | } 35 | uint8_t second() const 36 | { 37 | return ss; 38 | } 39 | uint8_t dayOfWeek() const; 40 | 41 | // 32-bit times as seconds since 1/1/2000 42 | long secondstime() const; 43 | // 32-bit times as seconds since 1/1/1970 44 | uint32_t unixtime(void) const; 45 | // as a string 46 | char* toString(char* buf, int maxlen) const; 47 | // add additional time 48 | void operator+=(uint32_t); 49 | 50 | protected: 51 | uint8_t yOff, m, d, hh, mm, ss; 52 | }; 53 | 54 | 55 | extern uint8_t bcd2bin (uint8_t val); 56 | extern uint8_t bin2bcd (uint8_t val); 57 | 58 | // RTC using the internal millis() clock, has to be initialized before use 59 | // NOTE: this clock won't be correct once the millis() timer rolls over (>49d?) 60 | class RTC_Millis 61 | { 62 | public: 63 | void begin(const DateTime& dt) 64 | { 65 | adjust(dt); 66 | } 67 | void adjust(const DateTime& dt); 68 | DateTime now(); 69 | RTC_Millis(void) 70 | { 71 | adjust(DateTime(2000,1,1,0,0,0)); 72 | } 73 | 74 | protected: 75 | long offset; 76 | }; 77 | 78 | #endif // __RTCLIB_H__ 79 | 80 | // vim:ci:sw=4 sts=4 ft=cpp 81 | -------------------------------------------------------------------------------- /RTC_DS1307.cpp: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | 4 | #if ARDUINO < 100 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | #include 11 | #include 12 | #include "RTClib.h" 13 | #include "RTC_DS1307.h" 14 | 15 | #define DS1307_ADDRESS 0x68 16 | 17 | #if ARDUINO < 100 18 | #define SEND(x) send(x) 19 | #define RECEIVE(x) receive(x) 20 | #else 21 | #define SEND(x) write(static_cast(x)) 22 | #define RECEIVE(x) read(x) 23 | #endif 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // RTC_DS1307 implementation 27 | 28 | uint8_t RTC_DS1307::begin(void) 29 | { 30 | return 1; 31 | } 32 | 33 | uint8_t RTC_DS1307::isrunning(void) 34 | { 35 | Wire.beginTransmission(DS1307_ADDRESS); 36 | Wire.SEND(0); 37 | Wire.endTransmission(); 38 | 39 | Wire.requestFrom(DS1307_ADDRESS, 1); 40 | uint8_t ss = Wire.RECEIVE(); 41 | return !(ss>>7); 42 | } 43 | 44 | void RTC_DS1307::adjust(const DateTime& dt) 45 | { 46 | Wire.beginTransmission(DS1307_ADDRESS); 47 | Wire.SEND(0); 48 | Wire.SEND(bin2bcd(dt.second())); 49 | Wire.SEND(bin2bcd(dt.minute())); 50 | Wire.SEND(bin2bcd(dt.hour())); 51 | Wire.SEND(bin2bcd(0)); 52 | Wire.SEND(bin2bcd(dt.day())); 53 | Wire.SEND(bin2bcd(dt.month())); 54 | Wire.SEND(bin2bcd(dt.year() - 2000)); 55 | Wire.SEND(0); 56 | Wire.endTransmission(); 57 | } 58 | 59 | DateTime RTC_DS1307::now() 60 | { 61 | Wire.beginTransmission(DS1307_ADDRESS); 62 | Wire.SEND(0); 63 | Wire.endTransmission(); 64 | 65 | Wire.requestFrom(DS1307_ADDRESS, 7); 66 | uint8_t ss = bcd2bin(Wire.RECEIVE() & 0x7F); 67 | uint8_t mm = bcd2bin(Wire.RECEIVE()); 68 | uint8_t hh = bcd2bin(Wire.RECEIVE()); 69 | Wire.RECEIVE(); 70 | uint8_t d = bcd2bin(Wire.RECEIVE()); 71 | uint8_t m = bcd2bin(Wire.RECEIVE()); 72 | uint16_t y = bcd2bin(Wire.RECEIVE()) + 2000; 73 | 74 | return DateTime (y, m, d, hh, mm, ss); 75 | } 76 | 77 | // vim:ci:sw=4 sts=4 ft=cpp 78 | -------------------------------------------------------------------------------- /RTC_DS3234.cpp: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | 4 | #if ARDUINO < 100 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | #include 11 | #include 12 | #include "RTClib.h" 13 | #include "RTC_DS3234.h" 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // RTC_DS3234 implementation 17 | 18 | // Registers we use 19 | const int CONTROL_R = 0x0e; 20 | const int CONTROL_W = 0x8e; 21 | const int CONTROL_STATUS_R = 0x0f; 22 | const int CONTROL_STATUS_W = 0x8f; 23 | const int SECONDS_R = 0x00; 24 | const int SECONDS_W = 0x80; 25 | 26 | // Bits we use 27 | const int EOSC = 7; 28 | const int OSF = 7; 29 | 30 | uint8_t RTC_DS3234::begin(void) 31 | { 32 | pinMode(cs_pin,OUTPUT); 33 | cs(HIGH); 34 | SPI.setBitOrder(MSBFIRST); 35 | 36 | //Ugh! In order to get this to interop with other SPI devices, 37 | //This has to be done in cs() 38 | SPI.setDataMode(SPI_MODE1); 39 | 40 | //Enable oscillator, disable square wave, alarms 41 | cs(LOW); 42 | SPI.transfer(CONTROL_W); 43 | SPI.transfer(0x0); 44 | cs(HIGH); 45 | delay(1); 46 | 47 | //Clear oscilator stop flag, 32kHz pin 48 | cs(LOW); 49 | SPI.transfer(CONTROL_STATUS_W); 50 | SPI.transfer(0x0); 51 | cs(HIGH); 52 | delay(1); 53 | 54 | return 1; 55 | } 56 | 57 | void RTC_DS3234::cs(int _value) 58 | { 59 | SPI.setDataMode(SPI_MODE1); 60 | digitalWrite(cs_pin,_value); 61 | } 62 | 63 | uint8_t RTC_DS3234::isrunning(void) 64 | { 65 | cs(LOW); 66 | SPI.transfer(CONTROL_R); 67 | uint8_t ss = SPI.transfer(-1); 68 | cs(HIGH); 69 | return !(ss & _BV(OSF)); 70 | } 71 | 72 | void RTC_DS3234::adjust(const DateTime& dt) 73 | { 74 | cs(LOW); 75 | SPI.transfer(SECONDS_W); 76 | SPI.transfer(bin2bcd(dt.second())); 77 | SPI.transfer(bin2bcd(dt.minute())); 78 | SPI.transfer(bin2bcd(dt.hour())); 79 | SPI.transfer(bin2bcd(dt.dayOfWeek())); 80 | SPI.transfer(bin2bcd(dt.day())); 81 | SPI.transfer(bin2bcd(dt.month())); 82 | SPI.transfer(bin2bcd(dt.year() - 2000)); 83 | cs(HIGH); 84 | 85 | } 86 | 87 | DateTime RTC_DS3234::now() 88 | { 89 | cs(LOW); 90 | SPI.transfer(SECONDS_R); 91 | uint8_t ss = bcd2bin(SPI.transfer(-1) & 0x7F); 92 | uint8_t mm = bcd2bin(SPI.transfer(-1)); 93 | uint8_t hh = bcd2bin(SPI.transfer(-1)); 94 | SPI.transfer(-1); 95 | uint8_t d = bcd2bin(SPI.transfer(-1)); 96 | uint8_t m = bcd2bin(SPI.transfer(-1)); 97 | uint16_t y = bcd2bin(SPI.transfer(-1)) + 2000; 98 | cs(HIGH); 99 | 100 | return DateTime (y, m, d, hh, mm, ss); 101 | } 102 | 103 | // vim:ai:cin:sw=4 sts=4 ft=cpp 104 | -------------------------------------------------------------------------------- /examples/ds1307/Jamfile: -------------------------------------------------------------------------------- 1 | # (1) Project Information 2 | 3 | PROJECT_LIBS = RTClib Wire ; 4 | 5 | # (2) Board Information 6 | 7 | UPLOAD_PROTOCOL ?= stk500v1 ; 8 | UPLOAD_SPEED ?= 57600 ; 9 | MCU ?= atmega328p ; 10 | F_CPU ?= 16000000 ; 11 | CORE ?= arduino ; 12 | VARIANT ?= standard ; 13 | ARDUINO_VERSION ?= 100 ; 14 | 15 | # (3) USB Ports 16 | 17 | PORTS = p4 p6 p9 u0 u1 u2 ; 18 | PORT_p6 = /dev/tty.usbserial-A600eHIs ; 19 | PORT_p4 = /dev/tty.usbserial-A40081RP ; 20 | PORT_p9 = /dev/tty.usbserial-A9007LmI ; 21 | PORT_u0 = /dev/ttyUSB0 ; 22 | PORT_u1 = /dev/ttyUSB1 ; 23 | PORT_u2 = /dev/ttyUSB2 ; 24 | 25 | # (4) Location of AVR tools 26 | # 27 | # This configuration assumes using avr-tools that were obtained separate from the Arduino 28 | # distribution. 29 | 30 | if $(OS) = MACOSX 31 | { 32 | AVR_BIN = /usr/local/avrtools/bin ; 33 | AVR_ETC = /usr/local/avrtools/etc ; 34 | AVR_INCLUDE = /usr/local/avrtools/include ; 35 | } 36 | else 37 | { 38 | AVR_BIN = /usr/bin ; 39 | AVR_INCLUDE = /usr/lib/avr/include ; 40 | AVR_ETC = /etc ; 41 | } 42 | 43 | # (5) Directories where Arduino core and libraries are located 44 | 45 | ARDUINO_DIR ?= /opt/Arduino ; 46 | ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/$(CORE) $(ARDUINO_DIR)/hardware/arduino/variants/$(VARIANT) ; 47 | ARDUINO_LIB = $(ARDUINO_DIR)/libraries ; 48 | SKETCH_LIB = $(HOME)/Source/Arduino/libraries ; 49 | 50 | # 51 | # -------------------------------------------------- 52 | # Below this line usually never needs to be modified 53 | # 54 | 55 | # Tool locations 56 | 57 | CC = $(AVR_BIN)/avr-gcc ; 58 | C++ = $(AVR_BIN)/avr-g++ ; 59 | LINK = $(AVR_BIN)/avr-gcc ; 60 | OBJCOPY = $(AVR_BIN)/avr-objcopy ; 61 | AVRDUDE = $(AVR_BIN)/avrdude ; 62 | 63 | # Flags 64 | 65 | DEFINES += F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ; 66 | OPTIM = -Os ; 67 | CCFLAGS = -Wall -Wextra -mmcu=$(MCU) -ffunction-sections -fdata-sections ; 68 | C++FLAGS = $(CCFLAGS) -fno-exceptions -fno-strict-aliasing ; 69 | LINKFLAGS = $(OPTIM) -lm -Wl,--gc-sections -mmcu=$(MCU) ; 70 | AVRDUDEFLAGS = -V -F -D -C $(AVR_ETC)/avrdude.conf -p $(MCU) -c $(UPLOAD_PROTOCOL) -b $(UPLOAD_SPEED) ; 71 | 72 | # Search everywhere for headers 73 | 74 | HDRS = $(PWD) $(AVR_INCLUDE) $(ARDUINO_CORE) $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) ; 75 | 76 | # Output locations 77 | 78 | LOCATE_TARGET = $(F_CPU) ; 79 | LOCATE_SOURCE = $(F_CPU) ; 80 | 81 | # 82 | # Custom rules 83 | # 84 | 85 | rule GitVersion 86 | { 87 | Always $(<) ; 88 | Depends all : $(<) ; 89 | } 90 | 91 | actions GitVersion 92 | { 93 | echo "const char program_version[] = \"\\" > $(<) 94 | git log -1 --pretty=format:%h >> $(<) 95 | echo "\";" >> $(<) 96 | } 97 | 98 | GitVersion version.h ; 99 | 100 | rule Pde 101 | { 102 | Depends $(<) : $(>) ; 103 | MakeLocate $(<) : $(LOCATE_SOURCE) ; 104 | Clean clean : $(<) ; 105 | } 106 | 107 | if ( $(ARDUINO_VERSION) < 100 ) 108 | { 109 | ARDUINO_H = WProgram.h ; 110 | } 111 | else 112 | { 113 | ARDUINO_H = Arduino.h ; 114 | } 115 | 116 | actions Pde 117 | { 118 | echo "#include <$(ARDUINO_H)>" > $(<) 119 | echo "#line 1 \"$(>)\"" >> $(<) 120 | cat $(>) >> $(<) 121 | } 122 | 123 | rule C++Pde 124 | { 125 | local _CPP = $(>:B).cpp ; 126 | Pde $(_CPP) : $(>) ; 127 | C++ $(<) : $(_CPP) ; 128 | } 129 | 130 | rule UserObject 131 | { 132 | switch $(>:S) 133 | { 134 | case .ino : C++Pde $(<) : $(>) ; 135 | case .pde : C++Pde $(<) : $(>) ; 136 | } 137 | } 138 | 139 | rule Objects 140 | { 141 | local _i ; 142 | 143 | for _i in [ FGristFiles $(<) ] 144 | { 145 | local _b = $(_i:B)$(SUFOBJ) ; 146 | local _o = $(_b:G=$(SOURCE_GRIST:E)) ; 147 | Object $(_o) : $(_i) ; 148 | Depends obj : $(_o) ; 149 | } 150 | } 151 | 152 | rule Main 153 | { 154 | MainFromObjects $(<) : $(>:B)$(SUFOBJ) ; 155 | Objects $(>) ; 156 | } 157 | 158 | rule Hex 159 | { 160 | Depends $(<) : $(>) ; 161 | MakeLocate $(<) : $(LOCATE_TARGET) ; 162 | Depends hex : $(<) ; 163 | Clean clean : $(<) ; 164 | } 165 | 166 | actions Hex 167 | { 168 | $(OBJCOPY) -O ihex -R .eeprom $(>) $(<) 169 | } 170 | 171 | rule Upload 172 | { 173 | Depends $(1) : $(2) ; 174 | Depends $(2) : $(3) ; 175 | NotFile $(1) ; 176 | Always $(1) ; 177 | Always $(2) ; 178 | UploadAction $(2) : $(3) ; 179 | } 180 | 181 | actions UploadAction 182 | { 183 | $(AVRDUDE) $(AVRDUDEFLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i 184 | } 185 | 186 | # 187 | # Targets 188 | # 189 | 190 | # Grab everything from the core directory 191 | CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ; 192 | 193 | # Grab everything from libraries. To avoid this "grab everything" behaviour, you 194 | # can specify specific modules to pick up in PROJECT_MODULES 195 | LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp *.c ] ; 196 | 197 | # Grab everything from the current dir 198 | PROJECT_MODULES += [ GLOB $(PWD) : *.c *.cpp *.pde *.ino ] ; 199 | 200 | # Main output executable 201 | MAIN = $(PWD:B).elf ; 202 | 203 | Main $(MAIN) : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ; 204 | Hex $(MAIN:B).hex : $(MAIN) ; 205 | 206 | # Upload targets 207 | for _p in $(PORTS) 208 | { 209 | Upload $(_p) : $(PORT_$(_p)) : $(MAIN:B).hex ; 210 | } 211 | -------------------------------------------------------------------------------- /examples/ds3234/Jamfile: -------------------------------------------------------------------------------- 1 | # (1) Project Information 2 | 3 | PROJECT_LIBS = RTClib Wire SPI ; 4 | 5 | # (2) Board Information 6 | 7 | UPLOAD_PROTOCOL ?= stk500v1 ; 8 | UPLOAD_SPEED ?= 57600 ; 9 | MCU ?= atmega328p ; 10 | F_CPU ?= 16000000 ; 11 | CORE ?= arduino ; 12 | VARIANT ?= standard ; 13 | ARDUINO_VERSION ?= 100 ; 14 | 15 | # (3) USB Ports 16 | 17 | PORTS = p4 p6 p9 u0 u1 u2 ; 18 | PORT_p6 = /dev/tty.usbserial-A600eHIs ; 19 | PORT_p4 = /dev/tty.usbserial-A40081RP ; 20 | PORT_p9 = /dev/tty.usbserial-A9007LmI ; 21 | PORT_u0 = /dev/ttyUSB0 ; 22 | PORT_u1 = /dev/ttyUSB1 ; 23 | PORT_u2 = /dev/ttyUSB2 ; 24 | 25 | # (4) Location of AVR tools 26 | # 27 | # This configuration assumes using avr-tools that were obtained separate from the Arduino 28 | # distribution. 29 | 30 | if $(OS) = MACOSX 31 | { 32 | AVR_BIN = /usr/local/avrtools/bin ; 33 | AVR_ETC = /usr/local/avrtools/etc ; 34 | AVR_INCLUDE = /usr/local/avrtools/include ; 35 | } 36 | else 37 | { 38 | AVR_BIN = /usr/bin ; 39 | AVR_INCLUDE = /usr/lib/avr/include ; 40 | AVR_ETC = /etc ; 41 | } 42 | 43 | # (5) Directories where Arduino core and libraries are located 44 | 45 | ARDUINO_DIR ?= /opt/Arduino ; 46 | ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/$(CORE) $(ARDUINO_DIR)/hardware/arduino/variants/$(VARIANT) ; 47 | ARDUINO_LIB = $(ARDUINO_DIR)/libraries ; 48 | SKETCH_LIB = $(HOME)/Source/Arduino/libraries ; 49 | 50 | # 51 | # -------------------------------------------------- 52 | # Below this line usually never needs to be modified 53 | # 54 | 55 | # Tool locations 56 | 57 | CC = $(AVR_BIN)/avr-gcc ; 58 | C++ = $(AVR_BIN)/avr-g++ ; 59 | LINK = $(AVR_BIN)/avr-gcc ; 60 | OBJCOPY = $(AVR_BIN)/avr-objcopy ; 61 | AVRDUDE = $(AVR_BIN)/avrdude ; 62 | 63 | # Flags 64 | 65 | DEFINES += F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ; 66 | OPTIM = -Os ; 67 | CCFLAGS = -Wall -Wextra -mmcu=$(MCU) -ffunction-sections -fdata-sections ; 68 | C++FLAGS = $(CCFLAGS) -fno-exceptions -fno-strict-aliasing ; 69 | LINKFLAGS = $(OPTIM) -lm -Wl,--gc-sections -mmcu=$(MCU) ; 70 | AVRDUDEFLAGS = -V -F -D -C $(AVR_ETC)/avrdude.conf -p $(MCU) -c $(UPLOAD_PROTOCOL) -b $(UPLOAD_SPEED) ; 71 | 72 | # Search everywhere for headers 73 | 74 | HDRS = $(PWD) $(AVR_INCLUDE) $(ARDUINO_CORE) $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) ; 75 | 76 | # Output locations 77 | 78 | LOCATE_TARGET = $(F_CPU) ; 79 | LOCATE_SOURCE = $(F_CPU) ; 80 | 81 | # 82 | # Custom rules 83 | # 84 | 85 | rule GitVersion 86 | { 87 | Always $(<) ; 88 | Depends all : $(<) ; 89 | } 90 | 91 | actions GitVersion 92 | { 93 | echo "const char program_version[] = \"\\" > $(<) 94 | git log -1 --pretty=format:%h >> $(<) 95 | echo "\";" >> $(<) 96 | } 97 | 98 | GitVersion version.h ; 99 | 100 | rule Pde 101 | { 102 | Depends $(<) : $(>) ; 103 | MakeLocate $(<) : $(LOCATE_SOURCE) ; 104 | Clean clean : $(<) ; 105 | } 106 | 107 | if ( $(ARDUINO_VERSION) < 100 ) 108 | { 109 | ARDUINO_H = WProgram.h ; 110 | } 111 | else 112 | { 113 | ARDUINO_H = Arduino.h ; 114 | } 115 | 116 | actions Pde 117 | { 118 | echo "#include <$(ARDUINO_H)>" > $(<) 119 | echo "#line 1 \"$(>)\"" >> $(<) 120 | cat $(>) >> $(<) 121 | } 122 | 123 | rule C++Pde 124 | { 125 | local _CPP = $(>:B).cpp ; 126 | Pde $(_CPP) : $(>) ; 127 | C++ $(<) : $(_CPP) ; 128 | } 129 | 130 | rule UserObject 131 | { 132 | switch $(>:S) 133 | { 134 | case .ino : C++Pde $(<) : $(>) ; 135 | case .pde : C++Pde $(<) : $(>) ; 136 | } 137 | } 138 | 139 | rule Objects 140 | { 141 | local _i ; 142 | 143 | for _i in [ FGristFiles $(<) ] 144 | { 145 | local _b = $(_i:B)$(SUFOBJ) ; 146 | local _o = $(_b:G=$(SOURCE_GRIST:E)) ; 147 | Object $(_o) : $(_i) ; 148 | Depends obj : $(_o) ; 149 | } 150 | } 151 | 152 | rule Main 153 | { 154 | MainFromObjects $(<) : $(>:B)$(SUFOBJ) ; 155 | Objects $(>) ; 156 | } 157 | 158 | rule Hex 159 | { 160 | Depends $(<) : $(>) ; 161 | MakeLocate $(<) : $(LOCATE_TARGET) ; 162 | Depends hex : $(<) ; 163 | Clean clean : $(<) ; 164 | } 165 | 166 | actions Hex 167 | { 168 | $(OBJCOPY) -O ihex -R .eeprom $(>) $(<) 169 | } 170 | 171 | rule Upload 172 | { 173 | Depends $(1) : $(2) ; 174 | Depends $(2) : $(3) ; 175 | NotFile $(1) ; 176 | Always $(1) ; 177 | Always $(2) ; 178 | UploadAction $(2) : $(3) ; 179 | } 180 | 181 | actions UploadAction 182 | { 183 | $(AVRDUDE) $(AVRDUDEFLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i 184 | } 185 | 186 | # 187 | # Targets 188 | # 189 | 190 | # Grab everything from the core directory 191 | CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ; 192 | 193 | # Grab everything from libraries. To avoid this "grab everything" behaviour, you 194 | # can specify specific modules to pick up in PROJECT_MODULES 195 | LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp *.c ] ; 196 | 197 | # Grab everything from the current dir 198 | PROJECT_MODULES += [ GLOB $(PWD) : *.c *.cpp *.pde *.ino ] ; 199 | 200 | # Main output executable 201 | MAIN = $(PWD:B).elf ; 202 | 203 | Main $(MAIN) : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ; 204 | Hex $(MAIN:B).hex : $(MAIN) ; 205 | 206 | # Upload targets 207 | for _p in $(PORTS) 208 | { 209 | Upload $(_p) : $(PORT_$(_p)) : $(MAIN:B).hex ; 210 | } 211 | -------------------------------------------------------------------------------- /RTClib.cpp: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | 4 | #include 5 | #include "RTClib.h" 6 | 7 | #define SECONDS_PER_DAY 86400L 8 | #define SECONDS_FROM_1970_TO_2000 946684800 9 | 10 | #if ARDUINO < 100 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | 17 | 18 | int i = 0; //The new wire library needs to take an int when you are sending for the zero register 19 | //////////////////////////////////////////////////////////////////////////////// 20 | // utility code, some of this could be exposed in the DateTime API if needed 21 | 22 | static const uint8_t daysInMonth[] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 23 | 24 | // number of days since 2000/01/01, valid for 2001..2099 25 | static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) 26 | { 27 | if (y >= 2000) 28 | y -= 2000; 29 | uint16_t days = d; 30 | for (uint8_t i = 1; i < m; ++i) 31 | days += pgm_read_byte(daysInMonth + i - 1); 32 | if (m > 2 && y % 4 == 0) 33 | ++days; 34 | return days + 365 * y + (y + 3) / 4 - 1; 35 | } 36 | 37 | static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) 38 | { 39 | return ((days * 24L + h) * 60 + m) * 60 + s; 40 | } 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // DateTime implementation - ignores time zones and DST changes 44 | // NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second 45 | 46 | DateTime::DateTime (uint32_t t) 47 | { 48 | t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 49 | 50 | ss = t % 60; 51 | t /= 60; 52 | mm = t % 60; 53 | t /= 60; 54 | hh = t % 24; 55 | uint16_t days = t / 24; 56 | uint8_t leap; 57 | for (yOff = 0; ; ++yOff) 58 | { 59 | leap = yOff % 4 == 0; 60 | if (days < 365U + leap) 61 | break; 62 | days -= 365 + leap; 63 | } 64 | for (m = 1; ; ++m) 65 | { 66 | uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1); 67 | if (leap && m == 2) 68 | ++daysPerMonth; 69 | if (days < daysPerMonth) 70 | break; 71 | days -= daysPerMonth; 72 | } 73 | d = days + 1; 74 | } 75 | 76 | DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) 77 | { 78 | if (year >= 2000) 79 | year -= 2000; 80 | yOff = year; 81 | m = min(month,12); 82 | d = min(day,31); 83 | hh = min(hour,23); 84 | mm = min(min,60); 85 | ss = min(sec,60); 86 | } 87 | 88 | static uint8_t conv2d(const char* p) 89 | { 90 | uint8_t v = 0; 91 | if ('0' <= *p && *p <= '9') 92 | v = *p - '0'; 93 | return 10 * v + *++p - '0'; 94 | } 95 | 96 | // A convenient constructor for using "the compiler's time": 97 | // DateTime now (__DATE__, __TIME__); 98 | // NOTE: using PSTR would further reduce the RAM footprint 99 | DateTime::DateTime (const char* date, const char* time) 100 | { 101 | // sample input: date = "Dec 26 2009", time = "12:34:56" 102 | yOff = conv2d(date + 9); 103 | // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 104 | switch (date[0]) 105 | { 106 | case 'J': 107 | if ( date[1] == 'a' ) 108 | m = 1; 109 | else if ( date[2] == 'n' ) 110 | m = 6; 111 | else 112 | m = 7; 113 | break; 114 | case 'F': 115 | m = 2; 116 | break; 117 | case 'A': 118 | m = date[2] == 'r' ? 4 : 8; 119 | break; 120 | case 'M': 121 | m = date[2] == 'r' ? 3 : 5; 122 | break; 123 | case 'S': 124 | m = 9; 125 | break; 126 | case 'O': 127 | m = 10; 128 | break; 129 | case 'N': 130 | m = 11; 131 | break; 132 | case 'D': 133 | m = 12; 134 | break; 135 | } 136 | d = conv2d(date + 4); 137 | hh = conv2d(time); 138 | mm = conv2d(time + 3); 139 | ss = conv2d(time + 6); 140 | } 141 | 142 | uint8_t DateTime::dayOfWeek() const 143 | { 144 | uint16_t day = date2days(yOff, m, d); 145 | return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 146 | } 147 | 148 | uint32_t DateTime::unixtime(void) const 149 | { 150 | uint32_t t; 151 | uint16_t days = date2days(yOff, m, d); 152 | t = time2long(days, hh, mm, ss); 153 | t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 154 | 155 | return t; 156 | } 157 | 158 | const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 159 | 160 | // as a string 161 | char* DateTime::toString(char* buf, int maxlen) const 162 | { 163 | snprintf(buf,maxlen,"%s %02u %04u %02u:%02u:%02u", 164 | months[m-1], 165 | d, 166 | 2000 + yOff, 167 | hh, 168 | mm, 169 | ss 170 | ); 171 | return buf; 172 | } 173 | 174 | void DateTime::operator+=(uint32_t additional) 175 | { 176 | DateTime after = DateTime( unixtime() + additional ); 177 | *this = after; 178 | } 179 | 180 | uint8_t bcd2bin (uint8_t val) 181 | { 182 | return val - 6 * (val >> 4); 183 | } 184 | uint8_t bin2bcd (uint8_t val) 185 | { 186 | return val + 6 * (val / 10); 187 | } 188 | 189 | //////////////////////////////////////////////////////////////////////////////// 190 | // RTC_Millis implementation 191 | 192 | void RTC_Millis::adjust(const DateTime& dt) 193 | { 194 | offset = dt.unixtime() - millis() / 1000; 195 | } 196 | 197 | DateTime RTC_Millis::now() 198 | { 199 | return (uint32_t)(offset + millis() / 1000); 200 | } 201 | 202 | //////////////////////////////////////////////////////////////////////////////// 203 | // vim:ci:sw=4 sts=4 ft=cpp 204 | --------------------------------------------------------------------------------