Components and supplies
Arduino Nano R3
perforated board
female header single row
Male Header 40 Position 1 Row (0.1")
Real Time Clock (RTC)
4 digit seven segment led display
Jumper wires (generic)
Tools and machines
Soldering iron (generic)
multimeter
Apps and platforms
Fritzing
Arduino IDE
Project description
Code
RealTimeClockDS1307.cpp
c_cpp
This is one of the library files of the real time clock. Create a folder named "RealTimeClockDS1307" and copy this into this folder. That's all you got to do. No need to compile it.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 v0.92 Updated for Arduino 1.00; not re-tested on earlier versions 6 7 Much thanks to John Waters and Maurice Ribble for their 8 earlier and very helpful work (even if I didn't wind up 9 using any of their code): 10 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 11 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*/ 27 28/****************************************************************************** 29 * Includes 30 ******************************************************************************/ 31 32#include "RealTimeClockDS1307.h" 33#include <Wire.h> 34 35/****************************************************************************** 36 * Definitions 37 ******************************************************************************/ 38 39#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address 40 41/****************************************************************************** 42 * Constructors 43 ******************************************************************************/ 44 45RealTimeClockDS1307::RealTimeClockDS1307() 46{ 47 Wire.begin(); 48 //must NOT attempt to read the clock before 49 //Wire.begin() has not been called; readClock() will hang. 50 //Fortunately, it seems that you can call Wire.begin() 51 //multiple times with no adverse effect). 52} 53 54/****************************************************************************** 55 * User API 56 ******************************************************************************/ 57 58/***** CHIP READ/WRITE ******/ 59 60void RealTimeClockDS1307::readClock() 61{ 62 // Reset the register pointer 63 Wire.beginTransmission(DS1307_I2C_ADDRESS); 64 Wire.write((uint8_t) 0x00); 65 Wire.endTransmission(); 66 67 Wire.requestFrom(DS1307_I2C_ADDRESS, 8); 68 _reg0_sec = Wire.read(); 69 _reg1_min = Wire.read(); 70 _reg2_hour = Wire.read(); 71 _reg3_day = Wire.read(); 72 _reg4_date = Wire.read(); 73 _reg5_month = Wire.read(); 74 _reg6_year = Wire.read(); 75 _reg7_sqw = Wire.read(); 76} 77 78void RealTimeClockDS1307::setClock() 79{ 80 //to be paranoid, we're going to first stop the clock 81 //to ensure we don't have rollovers while we're 82 //writing: 83 writeData(0,0x80); 84 //now, we'll write everything *except* the second 85 Wire.beginTransmission(DS1307_I2C_ADDRESS); 86 Wire.write((uint8_t) 0x01); 87 Wire.write(_reg1_min); 88 Wire.write(_reg2_hour); 89 Wire.write(_reg3_day); 90 Wire.write(_reg4_date); 91 Wire.write(_reg5_month); 92 Wire.write(_reg6_year); 93 Wire.endTransmission(); 94 //now, we'll write the seconds; we didn't have to keep 95 //track of whether the clock was already running, because 96 //_reg0_sec already knows what we want it to be. This 97 //will restart the clock as it writes the new seconds value. 98 writeData(0,_reg0_sec); 99} 100 101void RealTimeClockDS1307::stop() 102{ 103 //"Bit 7 of register 0 is the clock halt (CH) bit. 104 //When this bit is set to a 1, the oscillator is disabled." 105 _reg0_sec = _reg0_sec | 0x80; 106 writeData(0,_reg0_sec); 107} 108void RealTimeClockDS1307::start() 109{ 110 //"Bit 7 of register 0 is the clock halt (CH) bit. 111 //When this bit is set to a 1, the oscillator is disabled." 112 _reg0_sec = _reg0_sec & ~0x80; 113 writeData(0,_reg0_sec); 114} 115 116void RealTimeClockDS1307::writeData(byte regNo, byte value) 117{ 118 if(regNo > 0x3F) { return; } 119 Wire.beginTransmission(DS1307_I2C_ADDRESS); 120 Wire.write(regNo); 121 Wire.write(value); 122 Wire.endTransmission(); 123} 124 125void RealTimeClockDS1307::writeData(byte regNo, void * source, int length) 126{ 127 char * p = (char*) source; 128 if(regNo > 0x3F || length > 0x3F) { return; } 129 Wire.beginTransmission(DS1307_I2C_ADDRESS); 130 Wire.write(regNo); 131 for(int i=0; i<length; i++) { 132 Wire.write(*p); 133 p++; 134 } 135 Wire.endTransmission(); 136} 137 138byte RealTimeClockDS1307::readData(byte regNo) 139{ 140 if(regNo > 0x3F) { return 0xff; } 141 Wire.beginTransmission(DS1307_I2C_ADDRESS); 142 Wire.write(regNo); 143 Wire.endTransmission(); 144 Wire.requestFrom(DS1307_I2C_ADDRESS, 1); 145 return Wire.read(); 146} 147 148void RealTimeClockDS1307::readData(byte regNo, void * dest, int length) 149{ 150 char * p = (char*) dest; 151 if(regNo > 0x3F || length > 0x3F) { return; } 152 Wire.beginTransmission(DS1307_I2C_ADDRESS); 153 Wire.write(regNo); 154 Wire.endTransmission(); 155 Wire.requestFrom(DS1307_I2C_ADDRESS, length); 156 for(int i=0; i<length; i++) { 157 *p=Wire.read(); 158 p++; 159 } 160} 161 162 163void RealTimeClockDS1307::sqwEnable(byte frequency) 164{ 165 if(frequency > 3) { return; } 166 //bit 4 is enable (0x10); 167 //bit 7 is current output state if disabled 168 _reg7_sqw = _reg7_sqw & 0x80 | 0x10 | frequency; 169 writeData(0x07, _reg7_sqw); 170} 171 172void RealTimeClockDS1307::sqwDisable(boolean outputLevel) 173{ 174 //bit 7 0x80 output + bit 4 0x10 enable both to zero, 175 //the OR with the boolean shifted up to bit 7 176 _reg7_sqw = _reg7_sqw & ~0x90 | (outputLevel << 7); 177 writeData(0x07, _reg7_sqw); 178 //note: per the data sheet, "OUT (Output control): This bit controls 179 //the output level of the SQW/OUT pin when the square wave 180 //output is disabled. If SQWE = 0, the logic level on the 181 //SQW/OUT pin is 1 if OUT = 1 and is 0 if OUT = 0." 182 //"The SQW/OUT pin is open drain and requires an external 183 //pull-up resistor." 184 //It is worth mentioning that on the Sparkfun breakout board, 185 //BOB-00099, a LED connected to the SQW pin through a resistor to 186 //Vcc+5V illuminated when OUT=0 and was dark when OUT=1, the 187 //opposite of what I expected until I remembered that it is 188 //an open drain (google it if you need to). Basically, they don't 189 //so much mean a logic level (e.g., +3.3V rel Gnd) as they mean 190 //high or low *impeadance* to ground (drain). So High is basically 191 //an open switch. Low connects to ground. 192} 193 194 195/***** GETTERS ******/ 196 197boolean RealTimeClockDS1307::is12hour() 198{ 199 //12-hour mode has bit 6 of the hour register set high 200 return ((_reg2_hour & 0x40) == 0x40); 201} 202boolean RealTimeClockDS1307::isPM() 203{ 204 //if in 12-hour mode, but 5 of the hour register indicates PM 205 if(is12hour()) { 206 return ((_reg2_hour & 0x20) == 0x20); 207 } 208 //otherwise, let's consider any time with the hour >11 to be PM: 209 return (getHours() > 11); 210} 211boolean RealTimeClockDS1307::isStopped() 212{ 213 //bit 7 of the seconds register stopps the clock when high 214 return ((_reg0_sec & 0x80) == 0x80); 215} 216 217int RealTimeClockDS1307::getHours() 218{ 219 if(is12hour()) { 220 //do not include bit 5, the am/pm indicator 221 return bcdToDec(_reg2_hour & 0x1f); 222 } 223 //bits 4-5 are tens of hours 224 return bcdToDec(_reg2_hour & 0x3f); 225} 226int RealTimeClockDS1307::getMinutes() 227{ 228 //could mask with 0x7f but shouldn't need to 229 return bcdToDec(_reg1_min); 230} 231int RealTimeClockDS1307::getSeconds() 232{ 233 //need to mask oscillator start/stop bit 7 234 return bcdToDec(_reg0_sec & 0x7f); 235} 236int RealTimeClockDS1307::getYear() 237{ 238 return bcdToDec(_reg6_year); 239} 240int RealTimeClockDS1307::getMonth() 241{ 242 //could mask with 0x1f but shouldn't need to 243 return bcdToDec(_reg5_month); 244} 245int RealTimeClockDS1307::getDate() 246{ 247 //could mask with 0x3f but shouldn't need to 248 return bcdToDec(_reg4_date); 249} 250int RealTimeClockDS1307::getDay() 251{ 252 return getDate(); 253} 254int RealTimeClockDS1307::getDayOfWeek() 255{ 256 //could mask with 0x07 but shouldn't need to 257 return bcdToDec(_reg3_day); 258} 259 260void RealTimeClockDS1307::getFormatted(char * buffer) 261{ 262 int i=0; 263 //target string format: YY-MM-DD HH:II:SS 264 buffer[i++]=highNybbleToASCII(_reg6_year); 265 buffer[i++]=lowNybbleToASCII(_reg6_year); 266 buffer[i++]='-'; 267 buffer[i++]=highNybbleToASCII(_reg5_month & 0x1f); 268 buffer[i++]=lowNybbleToASCII(_reg5_month); 269 buffer[i++]='-'; 270 buffer[i++]=highNybbleToASCII(_reg4_date & 0x3f); 271 buffer[i++]=lowNybbleToASCII(_reg4_date); 272 buffer[i++]=' '; 273 if(is12hour()) { 274 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x1f); 275 } else { 276 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x3f); 277 } 278 buffer[i++]=lowNybbleToASCII(_reg2_hour); 279 buffer[i++]=':'; 280 buffer[i++]=highNybbleToASCII(_reg1_min & 0x7f); 281 buffer[i++]=lowNybbleToASCII(_reg1_min); 282 buffer[i++]=':'; 283 buffer[i++]=highNybbleToASCII(_reg0_sec & 0x7f); 284 buffer[i++]=lowNybbleToASCII(_reg0_sec); 285 if(is12hour()) { 286 if(isPM()) { 287 buffer[i++]='P'; 288 } else { 289 buffer[i++]='A'; 290 } 291 } 292 buffer[i++]=0x00; 293} 294 295void RealTimeClockDS1307::getFormatted2k(char * buffer) 296{ 297 buffer[0]='2'; 298 buffer[1]='0'; 299 getFormatted(&buffer[2]); 300} 301 302/**** SETTERS *****/ 303 304void RealTimeClockDS1307::setSeconds(int s) 305{ 306 if (s < 60 && s >=0) 307 { 308 //need to preserve oscillator bit 309 _reg0_sec = decToBcd(s) | (_reg0_sec & 0x80); 310 } 311} 312void RealTimeClockDS1307::setMinutes(int m) 313{ 314 if (m < 60 && m >=0) 315 { 316 _reg1_min = decToBcd(m); 317 } 318} 319void RealTimeClockDS1307::setHours(int h) 320{ 321 if (is12hour()) 322 { 323 if (h >= 1 && h <=12) 324 { 325 //preserve 12/24 and AM/PM bits 326 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x60); 327 } 328 } else { 329 if (h >= 0 && h <=24) 330 { 331 //preserve 12/24 bit 332 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x40); 333 } 334 }//else 335}//setHours 336 337void RealTimeClockDS1307::set24h() 338{ 339 //"Bit 6 of the hours register is defined as the 340 //"12- or 24-hour mode select bit. 341 //"When high, the 12-hour mode is selected" 342 //So, mask the curent value with the complement turn off that bit: 343 _reg2_hour = _reg2_hour & ~0x40; 344} 345void RealTimeClockDS1307::setAM() 346{ 347 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 348 //so we need to OR with 0x40 to set 12-hour mode and also 349 //turn off the PM bit by masking with the complement 350 _reg2_hour = _reg2_hour & ~0x20 | 0x40; 351} 352void RealTimeClockDS1307::setPM() 353{ 354 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 355 //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also 356 //turn on the PM bit: 357 _reg2_hour = _reg2_hour | 0x60; 358} 359 360void RealTimeClockDS1307::switchTo12h() 361{ 362 if(is12hour()) { return; } 363 int h = getHours(); 364 if (h < 12) { 365 setAM(); 366 } else { 367 h = h-12; 368 setPM(); 369 } 370 if (h==0) 371 { 372 h=12; 373 } 374 setHours(h); 375} 376void RealTimeClockDS1307::switchTo24h() 377{ 378 if(!is12hour()) { return ; } 379 int h = getHours(); 380 if(h==12) {//12 PM is just 12; 12 AM is 0 hours. 381 h = 0; 382 } 383 if (isPM()) 384 {//if it was 12 PM, then h=0 above and so we're back to 12: 385 h = h+12; 386 } 387 set24h(); 388 setHours(h); 389} 390 391void RealTimeClockDS1307::setDayOfWeek(int d) 392{ 393 if (d > 0 && d < 8) 394 { 395 _reg3_day = decToBcd(d); 396 } 397} 398 399void RealTimeClockDS1307::setDate(int d) 400{ 401 if (d > 0 && d < 32) 402 { 403 _reg4_date = decToBcd(d); 404 } 405} 406void RealTimeClockDS1307::setDay(int d) 407{ 408 setDate(d); 409} 410 411void RealTimeClockDS1307::setMonth(int m) 412{ 413 if (m > 0 && m < 13) 414 { 415 _reg5_month = decToBcd(m); 416 } 417} 418void RealTimeClockDS1307::setYear(int y) 419{ 420 if (y >= 0 && y <100) 421 { 422 _reg6_year = decToBcd(y); 423 } 424} 425 426 427 428/***************************************** 429 * Private methods 430 *****************************************/ 431byte RealTimeClockDS1307::decToBcd(byte b) 432{ 433 return ( ((b/10) << 4) + (b%10) ); 434} 435 436// Convert binary coded decimal to normal decimal numbers 437byte RealTimeClockDS1307::bcdToDec(byte b) 438{ 439 return ( ((b >> 4)*10) + (b%16) ); 440} 441 442char RealTimeClockDS1307::lowNybbleToASCII(byte b) 443{ 444 b = b & 0x0f; 445 if(b < 10) { 446 //0 is ASCII 48 447 return 48+b; 448 } 449 //A is ASCII 55 450 return 55+b; 451} 452char RealTimeClockDS1307::highNybbleToASCII(byte b) 453{ 454 return lowNybbleToASCII(b >> 4); 455} 456 457/***** INSTANCE *******/ 458 459RealTimeClockDS1307 RTC = RealTimeClockDS1307(); 460
RTClib.h
c_cpp
that's the name. add it to the RTClib library. Now you have all the files for the RTClib library. Do the same steps to add this to the arduino libraries.
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#include <Arduino.h> 8class TimeSpan; 9 10 11#define PCF8523_ADDRESS 0x68 12#define PCF8523_CLKOUTCONTROL 0x0F 13#define PCF8523_CONTROL_3 0x02 14 15#define DS1307_ADDRESS 0x68 16#define DS1307_CONTROL 0x07 17#define DS1307_NVRAM 0x08 18 19#define DS3231_ADDRESS 0x68 20#define DS3231_CONTROL 0x0E 21#define DS3231_STATUSREG 0x0F 22 23#define SECONDS_PER_DAY 86400L 24 25#define SECONDS_FROM_1970_TO_2000 946684800 26 27 28 29// Simple general-purpose date/time class (no TZ / DST / leap second handling!) 30class DateTime { 31public: 32 DateTime (uint32_t t =0); 33 DateTime (uint16_t year, uint8_t month, uint8_t day, 34 uint8_t hour =0, uint8_t min =0, uint8_t sec =0); 35 DateTime (const DateTime& copy); 36 DateTime (const char* date, const char* time); 37 DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time); 38 uint16_t year() const { return 2000 + yOff; } 39 uint8_t month() const { return m; } 40 uint8_t day() const { return d; } 41 uint8_t hour() const { return hh; } 42 uint8_t minute() const { return mm; } 43 uint8_t second() const { return ss; } 44 uint8_t dayOfTheWeek() const; 45 46 // 32-bit times as seconds since 1/1/2000 47 long secondstime() const; 48 // 32-bit times as seconds since 1/1/1970 49 uint32_t unixtime(void) const; 50 51 DateTime operator+(const TimeSpan& span); 52 DateTime operator-(const TimeSpan& span); 53 TimeSpan operator-(const DateTime& right); 54 55protected: 56 uint8_t yOff, m, d, hh, mm, ss; 57}; 58 59// Timespan which can represent changes in time with seconds accuracy. 60class TimeSpan { 61public: 62 TimeSpan (int32_t seconds = 0); 63 TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds); 64 TimeSpan (const TimeSpan& copy); 65 int16_t days() const { return _seconds / 86400L; } 66 int8_t hours() const { return _seconds / 3600 % 24; } 67 int8_t minutes() const { return _seconds / 60 % 60; } 68 int8_t seconds() const { return _seconds % 60; } 69 int32_t totalseconds() const { return _seconds; } 70 71 TimeSpan operator+(const TimeSpan& right); 72 TimeSpan operator-(const TimeSpan& right); 73 74protected: 75 int32_t _seconds; 76}; 77 78// RTC based on the DS1307 chip connected via I2C and the Wire library 79enum Ds1307SqwPinMode { OFF = 0x00, ON = 0x80, SquareWave1HZ = 0x10, SquareWave4kHz = 0x11, SquareWave8kHz = 0x12, SquareWave32kHz = 0x13 }; 80 81class RTC_DS1307 { 82public: 83 boolean begin(void); 84 static void adjust(const DateTime& dt); 85 uint8_t isrunning(void); 86 static DateTime now(); 87 static Ds1307SqwPinMode readSqwPinMode(); 88 static void writeSqwPinMode(Ds1307SqwPinMode mode); 89 uint8_t readnvram(uint8_t address); 90 void readnvram(uint8_t* buf, uint8_t size, uint8_t address); 91 void writenvram(uint8_t address, uint8_t data); 92 void writenvram(uint8_t address, uint8_t* buf, uint8_t size); 93}; 94 95// RTC based on the DS3231 chip connected via I2C and the Wire library 96enum Ds3231SqwPinMode { DS3231_OFF = 0x01, DS3231_SquareWave1Hz = 0x00, DS3231_SquareWave1kHz = 0x08, DS3231_SquareWave4kHz = 0x10, DS3231_SquareWave8kHz = 0x18 }; 97 98class RTC_DS3231 { 99public: 100 boolean begin(void); 101 static void adjust(const DateTime& dt); 102 bool lostPower(void); 103 static DateTime now(); 104 static Ds3231SqwPinMode readSqwPinMode(); 105 static void writeSqwPinMode(Ds3231SqwPinMode mode); 106}; 107 108 109// RTC based on the PCF8523 chip connected via I2C and the Wire library 110enum Pcf8523SqwPinMode { PCF8523_OFF = 7, PCF8523_SquareWave1HZ = 6, PCF8523_SquareWave32HZ = 5, PCF8523_SquareWave1kHz = 4, PCF8523_SquareWave4kHz = 3, PCF8523_SquareWave8kHz = 2, PCF8523_SquareWave16kHz = 1, PCF8523_SquareWave32kHz = 0 }; 111 112class RTC_PCF8523 { 113public: 114 boolean begin(void); 115 void adjust(const DateTime& dt); 116 boolean initialized(void); 117 static DateTime now(); 118 119 Pcf8523SqwPinMode readSqwPinMode(); 120 void writeSqwPinMode(Pcf8523SqwPinMode mode); 121}; 122 123// RTC using the internal millis() clock, has to be initialized before use 124// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?) 125class RTC_Millis { 126public: 127 static void begin(const DateTime& dt) { adjust(dt); } 128 static void adjust(const DateTime& dt); 129 static DateTime now(); 130 131protected: 132 static long offset; 133}; 134 135#endif // _RTCLIB_H_ 136
RealTimeClockDS1307.h
c_cpp
This is the main header file of the real time clock. Copy this also into the folder you previously created named "RealTimeClockDS1307". Now you have all the files for the Real Time Clock. Enter the arduino ide and under the 'Sketch' menu click on the 'include library' option and then search your folder under the 'Add .ZIP Library". This will do the trick and you will now be able to set the time in the RTC module.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 v0.92 Updated for Arduino 1.00; not re-tested on earlier versions 6 7 Much thanks to John Waters and Maurice Ribble for their 8 earlier and very helpful work (even if I didn't wind up 9 using any of their code): 10 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 11 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*/ 27 28#ifndef RealTimeClockDS1307_h 29#define RealTimeClockDS1307_h 30 31 #if defined(ARDUINO) && ARDUINO >= 100 32 #include "Arduino.h" 33 #else 34 #include "WProgram.h" 35 #endif 36 37//#include <HardwareSerial.h> 38//#include <WConstants.h> //need/want 'boolean' and 'byte' types used by Arduino 39//#undef round is required to avoid a compile-time 40//"expected unqualified-id before 'double'" error in math.h 41//see: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247924528/3 42#undef round 43#include <Wire.h> 44 45#define ARDUINO_PIN_T uint8_t 46 47class RealTimeClockDS1307 48{ 49 private: 50 byte _reg0_sec; 51 byte _reg1_min; 52 byte _reg2_hour; 53 byte _reg3_day; 54 byte _reg4_date; 55 byte _reg5_month; 56 byte _reg6_year; 57 byte _reg7_sqw; 58 byte decToBcd(byte); 59 byte bcdToDec(byte); 60 char lowNybbleToASCII(byte); 61 char highNybbleToASCII(byte); 62 public: 63 RealTimeClockDS1307(); 64 void readClock();//read registers (incl sqw) to local store 65 void setClock();//update clock registers from local store 66 void stop();//immediate; does not require setClock(); 67 void start();//immediate; does not require setClock(); 68 void sqwEnable(byte);//enable the square wave with the specified frequency 69 void sqwDisable(boolean);//disable the square wave, setting output either high or low 70 void writeData(byte, byte);//write a single value to a register 71 void writeData(byte, void *, int);//write several values consecutively 72 byte readData(byte);//read a single value from a register 73 void readData(byte, void *, int);//read several values into a buffer 74 75 int getHours(); 76 int getMinutes(); 77 int getSeconds(); 78 int getYear(); 79 int getMonth(); 80 int getDate(); 81 int getDay(); 82 int getDayOfWeek(); 83 boolean is12hour(); 84 boolean isPM(); 85 boolean isStopped(); 86 //getFormatted writes into a char array provided by you. Format is: 87 // YY-MM-DD HH:II:SS ... plus "A" or "P" if in 12-hour mode 88 //and of course a NULL terminator. So, [18] for 24h or [19] for 12h 89 void getFormatted(char *);//see comment above 90 void getFormatted2k(char *);//as getFormatted, but with "20" prepended 91 92 //must also call setClock() after any of these 93 //before next readClock(). Note that invalid dates are not 94 //corrected by the clock. All the clock knows is when it should 95 //roll over to the next month rather than the next date in the same month. 96 void setSeconds(int); 97 void setMinutes(int); 98 //setHours rejects values out of range for the current 12/24 mode 99 void setHours(int); 100 void setAM();//does not consider hours; see switchTo24() 101 void setPM();//does not consider hours; see switchTo24() 102 void set24h();//does not consider hours; see switchTo24() 103 void switchTo24h();//returns immediately if already 24h 104 void switchTo12h();//returns immediately if already 12h 105 void setDayOfWeek(int);//incremented at midnight; not set by date (no fixed meaning) 106 void setDate(int);//allows 1-31 for *all* months. 107 void setDay(int); 108 void setMonth(int); 109 void setYear(int); 110 111 //squarewave frequencies: 112 static const byte SQW_1Hz=0x00; 113 static const byte SQW_4kHz=0x01;//actually 4.096kHz 114 static const byte SQW_8kHz=0x02;//actually 8.192kHz 115 static const byte SQW_32kHz=0x03;//actually 32.768kHz 116}; 117 118extern RealTimeClockDS1307 RTC; 119 120#endif 121
RTClib.cpp
c_cpp
name it as above and add it to the RTClib library
1// Code by JeeLabs http://news.jeelabs.org/code/ 2// Released to the public domain! Enjoy! 3 4#include <Wire.h> 5#include "RTClib.h" 6#ifdef __AVR__ 7 #include <avr/pgmspace.h> 8#elif defined(ESP8266) 9 #include <pgmspace.h> 10#elif defined(ARDUINO_ARCH_SAMD) 11// nothing special needed 12#elif defined(ARDUINO_SAM_DUE) 13 #define PROGMEM 14 #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 15 #define Wire Wire1 16#endif 17 18 19 20#if (ARDUINO >= 100) 21 #include <Arduino.h> // capital A so it is error prone on case-sensitive filesystems 22 // Macro to deal with the difference in I2C write functions from old and new Arduino versions. 23 #define _I2C_WRITE write 24 #define _I2C_READ read 25#else 26 #include <WProgram.h> 27 #define _I2C_WRITE send 28 #define _I2C_READ receive 29#endif 30 31 32static uint8_t read_i2c_register(uint8_t addr, uint8_t reg) { 33 Wire.beginTransmission(addr); 34 Wire._I2C_WRITE((byte)reg); 35 Wire.endTransmission(); 36 37 Wire.requestFrom(addr, (byte)1); 38 return Wire._I2C_READ(); 39} 40 41static void write_i2c_register(uint8_t addr, uint8_t reg, uint8_t val) { 42 Wire.beginTransmission(addr); 43 Wire._I2C_WRITE((byte)reg); 44 Wire._I2C_WRITE((byte)val); 45 Wire.endTransmission(); 46} 47 48 49//////////////////////////////////////////////////////////////////////////////// 50// utility code, some of this could be exposed in the DateTime API if needed 51 52const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 53 54// number of days since 2000/01/01, valid for 2001..2099 55static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) { 56 if (y >= 2000) 57 y -= 2000; 58 uint16_t days = d; 59 for (uint8_t i = 1; i < m; ++i) 60 days += pgm_read_byte(daysInMonth + i - 1); 61 if (m > 2 && y % 4 == 0) 62 ++days; 63 return days + 365 * y + (y + 3) / 4 - 1; 64} 65 66static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) { 67 return ((days * 24L + h) * 60 + m) * 60 + s; 68} 69 70//////////////////////////////////////////////////////////////////////////////// 71// DateTime implementation - ignores time zones and DST changes 72// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second 73 74DateTime::DateTime (uint32_t t) { 75 t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 76 77 ss = t % 60; 78 t /= 60; 79 mm = t % 60; 80 t /= 60; 81 hh = t % 24; 82 uint16_t days = t / 24; 83 uint8_t leap; 84 for (yOff = 0; ; ++yOff) { 85 leap = yOff % 4 == 0; 86 if (days < 365 + leap) 87 break; 88 days -= 365 + leap; 89 } 90 for (m = 1; ; ++m) { 91 uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1); 92 if (leap && m == 2) 93 ++daysPerMonth; 94 if (days < daysPerMonth) 95 break; 96 days -= daysPerMonth; 97 } 98 d = days + 1; 99} 100 101DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) { 102 if (year >= 2000) 103 year -= 2000; 104 yOff = year; 105 m = month; 106 d = day; 107 hh = hour; 108 mm = min; 109 ss = sec; 110} 111 112DateTime::DateTime (const DateTime& copy): 113 yOff(copy.yOff), 114 m(copy.m), 115 d(copy.d), 116 hh(copy.hh), 117 mm(copy.mm), 118 ss(copy.ss) 119{} 120 121static uint8_t conv2d(const char* p) { 122 uint8_t v = 0; 123 if ('0' <= *p && *p <= '9') 124 v = *p - '0'; 125 return 10 * v + *++p - '0'; 126} 127 128// A convenient constructor for using "the compiler's time": 129// DateTime now (__DATE__, __TIME__); 130// NOTE: using F() would further reduce the RAM footprint, see below. 131DateTime::DateTime (const char* date, const char* time) { 132 // sample input: date = "Dec 26 2009", time = "12:34:56" 133 yOff = conv2d(date + 9); 134 // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 135 switch (date[0]) { 136 case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; 137 case 'F': m = 2; break; 138 case 'A': m = date[2] == 'r' ? 4 : 8; break; 139 case 'M': m = date[2] == 'r' ? 3 : 5; break; 140 case 'S': m = 9; break; 141 case 'O': m = 10; break; 142 case 'N': m = 11; break; 143 case 'D': m = 12; break; 144 } 145 d = conv2d(date + 4); 146 hh = conv2d(time); 147 mm = conv2d(time + 3); 148 ss = conv2d(time + 6); 149} 150 151// A convenient constructor for using "the compiler's time": 152// This version will save RAM by using PROGMEM to store it by using the F macro. 153// DateTime now (F(__DATE__), F(__TIME__)); 154DateTime::DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time) { 155 // sample input: date = "Dec 26 2009", time = "12:34:56" 156 char buff[11]; 157 memcpy_P(buff, date, 11); 158 yOff = conv2d(buff + 9); 159 // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 160 switch (buff[0]) { 161 case 'J': m = buff[1] == 'a' ? 1 : m = buff[2] == 'n' ? 6 : 7; break; 162 case 'F': m = 2; break; 163 case 'A': m = buff[2] == 'r' ? 4 : 8; break; 164 case 'M': m = buff[2] == 'r' ? 3 : 5; break; 165 case 'S': m = 9; break; 166 case 'O': m = 10; break; 167 case 'N': m = 11; break; 168 case 'D': m = 12; break; 169 } 170 d = conv2d(buff + 4); 171 memcpy_P(buff, time, 8); 172 hh = conv2d(buff); 173 mm = conv2d(buff + 3); 174 ss = conv2d(buff + 6); 175} 176 177uint8_t DateTime::dayOfTheWeek() const { 178 uint16_t day = date2days(yOff, m, d); 179 return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 180} 181 182uint32_t DateTime::unixtime(void) const { 183 uint32_t t; 184 uint16_t days = date2days(yOff, m, d); 185 t = time2long(days, hh, mm, ss); 186 t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 187 188 return t; 189} 190 191long DateTime::secondstime(void) const { 192 long t; 193 uint16_t days = date2days(yOff, m, d); 194 t = time2long(days, hh, mm, ss); 195 return t; 196} 197 198DateTime DateTime::operator+(const TimeSpan& span) { 199 return DateTime(unixtime()+span.totalseconds()); 200} 201 202DateTime DateTime::operator-(const TimeSpan& span) { 203 return DateTime(unixtime()-span.totalseconds()); 204} 205 206TimeSpan DateTime::operator-(const DateTime& right) { 207 return TimeSpan(unixtime()-right.unixtime()); 208} 209 210//////////////////////////////////////////////////////////////////////////////// 211// TimeSpan implementation 212 213TimeSpan::TimeSpan (int32_t seconds): 214 _seconds(seconds) 215{} 216 217TimeSpan::TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds): 218 _seconds((int32_t)days*86400L + (int32_t)hours*3600 + (int32_t)minutes*60 + seconds) 219{} 220 221TimeSpan::TimeSpan (const TimeSpan& copy): 222 _seconds(copy._seconds) 223{} 224 225TimeSpan TimeSpan::operator+(const TimeSpan& right) { 226 return TimeSpan(_seconds+right._seconds); 227} 228 229TimeSpan TimeSpan::operator-(const TimeSpan& right) { 230 return TimeSpan(_seconds-right._seconds); 231} 232 233//////////////////////////////////////////////////////////////////////////////// 234// RTC_DS1307 implementation 235 236static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } 237static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } 238 239boolean RTC_DS1307::begin(void) { 240 Wire.begin(); 241 return true; 242} 243 244uint8_t RTC_DS1307::isrunning(void) { 245 Wire.beginTransmission(DS1307_ADDRESS); 246 Wire._I2C_WRITE((byte)0); 247 Wire.endTransmission(); 248 249 Wire.requestFrom(DS1307_ADDRESS, 1); 250 uint8_t ss = Wire._I2C_READ(); 251 return !(ss>>7); 252} 253 254void RTC_DS1307::adjust(const DateTime& dt) { 255 Wire.beginTransmission(DS1307_ADDRESS); 256 Wire._I2C_WRITE((byte)0); // start at location 0 257 Wire._I2C_WRITE(bin2bcd(dt.second())); 258 Wire._I2C_WRITE(bin2bcd(dt.minute())); 259 Wire._I2C_WRITE(bin2bcd(dt.hour())); 260 Wire._I2C_WRITE(bin2bcd(0)); 261 Wire._I2C_WRITE(bin2bcd(dt.day())); 262 Wire._I2C_WRITE(bin2bcd(dt.month())); 263 Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); 264 Wire.endTransmission(); 265} 266 267DateTime RTC_DS1307::now() { 268 Wire.beginTransmission(DS1307_ADDRESS); 269 Wire._I2C_WRITE((byte)0); 270 Wire.endTransmission(); 271 272 Wire.requestFrom(DS1307_ADDRESS, 7); 273 uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F); 274 uint8_t mm = bcd2bin(Wire._I2C_READ()); 275 uint8_t hh = bcd2bin(Wire._I2C_READ()); 276 Wire._I2C_READ(); 277 uint8_t d = bcd2bin(Wire._I2C_READ()); 278 uint8_t m = bcd2bin(Wire._I2C_READ()); 279 uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000; 280 281 return DateTime (y, m, d, hh, mm, ss); 282} 283 284Ds1307SqwPinMode RTC_DS1307::readSqwPinMode() { 285 int mode; 286 287 Wire.beginTransmission(DS1307_ADDRESS); 288 Wire._I2C_WRITE(DS1307_CONTROL); 289 Wire.endTransmission(); 290 291 Wire.requestFrom((uint8_t)DS1307_ADDRESS, (uint8_t)1); 292 mode = Wire._I2C_READ(); 293 294 mode &= 0x93; 295 return static_cast<Ds1307SqwPinMode>(mode); 296} 297 298void RTC_DS1307::writeSqwPinMode(Ds1307SqwPinMode mode) { 299 Wire.beginTransmission(DS1307_ADDRESS); 300 Wire._I2C_WRITE(DS1307_CONTROL); 301 Wire._I2C_WRITE(mode); 302 Wire.endTransmission(); 303} 304 305void RTC_DS1307::readnvram(uint8_t* buf, uint8_t size, uint8_t address) { 306 int addrByte = DS1307_NVRAM + address; 307 Wire.beginTransmission(DS1307_ADDRESS); 308 Wire._I2C_WRITE(addrByte); 309 Wire.endTransmission(); 310 311 Wire.requestFrom((uint8_t) DS1307_ADDRESS, size); 312 for (uint8_t pos = 0; pos < size; ++pos) { 313 buf[pos] = Wire._I2C_READ(); 314 } 315} 316 317void RTC_DS1307::writenvram(uint8_t address, uint8_t* buf, uint8_t size) { 318 int addrByte = DS1307_NVRAM + address; 319 Wire.beginTransmission(DS1307_ADDRESS); 320 Wire._I2C_WRITE(addrByte); 321 for (uint8_t pos = 0; pos < size; ++pos) { 322 Wire._I2C_WRITE(buf[pos]); 323 } 324 Wire.endTransmission(); 325} 326 327uint8_t RTC_DS1307::readnvram(uint8_t address) { 328 uint8_t data; 329 readnvram(&data, 1, address); 330 return data; 331} 332 333void RTC_DS1307::writenvram(uint8_t address, uint8_t data) { 334 writenvram(address, &data, 1); 335} 336 337//////////////////////////////////////////////////////////////////////////////// 338// RTC_Millis implementation 339 340long RTC_Millis::offset = 0; 341 342void RTC_Millis::adjust(const DateTime& dt) { 343 offset = dt.unixtime() - millis() / 1000; 344} 345 346DateTime RTC_Millis::now() { 347 return (uint32_t)(offset + millis() / 1000); 348} 349 350//////////////////////////////////////////////////////////////////////////////// 351 352//////////////////////////////////////////////////////////////////////////////// 353// RTC_PCF8563 implementation 354 355boolean RTC_PCF8523::begin(void) { 356 Wire.begin(); 357 return true; 358} 359 360boolean RTC_PCF8523::initialized(void) { 361 Wire.beginTransmission(PCF8523_ADDRESS); 362 Wire._I2C_WRITE((byte)PCF8523_CONTROL_3); 363 Wire.endTransmission(); 364 365 Wire.requestFrom(PCF8523_ADDRESS, 1); 366 uint8_t ss = Wire._I2C_READ(); 367 return ((ss & 0xE0) != 0xE0); 368} 369 370void RTC_PCF8523::adjust(const DateTime& dt) { 371 Wire.beginTransmission(PCF8523_ADDRESS); 372 Wire._I2C_WRITE((byte)3); // start at location 3 373 Wire._I2C_WRITE(bin2bcd(dt.second())); 374 Wire._I2C_WRITE(bin2bcd(dt.minute())); 375 Wire._I2C_WRITE(bin2bcd(dt.hour())); 376 Wire._I2C_WRITE(bin2bcd(dt.day())); 377 Wire._I2C_WRITE(bin2bcd(0)); // skip weekdays 378 Wire._I2C_WRITE(bin2bcd(dt.month())); 379 Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); 380 Wire.endTransmission(); 381 382 // set to battery switchover mode 383 Wire.beginTransmission(PCF8523_ADDRESS); 384 Wire._I2C_WRITE((byte)PCF8523_CONTROL_3); 385 Wire._I2C_WRITE((byte)0x00); 386 Wire.endTransmission(); 387} 388 389DateTime RTC_PCF8523::now() { 390 Wire.beginTransmission(PCF8523_ADDRESS); 391 Wire._I2C_WRITE((byte)3); 392 Wire.endTransmission(); 393 394 Wire.requestFrom(PCF8523_ADDRESS, 7); 395 uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F); 396 uint8_t mm = bcd2bin(Wire._I2C_READ()); 397 uint8_t hh = bcd2bin(Wire._I2C_READ()); 398 uint8_t d = bcd2bin(Wire._I2C_READ()); 399 Wire._I2C_READ(); // skip 'weekdays' 400 uint8_t m = bcd2bin(Wire._I2C_READ()); 401 uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000; 402 403 return DateTime (y, m, d, hh, mm, ss); 404} 405 406Pcf8523SqwPinMode RTC_PCF8523::readSqwPinMode() { 407 int mode; 408 409 Wire.beginTransmission(PCF8523_ADDRESS); 410 Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL); 411 Wire.endTransmission(); 412 413 Wire.requestFrom((uint8_t)PCF8523_ADDRESS, (uint8_t)1); 414 mode = Wire._I2C_READ(); 415 416 mode >>= 3; 417 mode &= 0x7; 418 return static_cast<Pcf8523SqwPinMode>(mode); 419} 420 421void RTC_PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) { 422 Wire.beginTransmission(PCF8523_ADDRESS); 423 Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL); 424 Wire._I2C_WRITE(mode << 3); 425 Wire.endTransmission(); 426} 427 428 429 430 431//////////////////////////////////////////////////////////////////////////////// 432// RTC_DS3231 implementation 433 434boolean RTC_DS3231::begin(void) { 435 Wire.begin(); 436 return true; 437} 438 439bool RTC_DS3231::lostPower(void) { 440 return (read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG) >> 7); 441} 442 443void RTC_DS3231::adjust(const DateTime& dt) { 444 Wire.beginTransmission(DS3231_ADDRESS); 445 Wire._I2C_WRITE((byte)0); // start at location 0 446 Wire._I2C_WRITE(bin2bcd(dt.second())); 447 Wire._I2C_WRITE(bin2bcd(dt.minute())); 448 Wire._I2C_WRITE(bin2bcd(dt.hour())); 449 Wire._I2C_WRITE(bin2bcd(0)); 450 Wire._I2C_WRITE(bin2bcd(dt.day())); 451 Wire._I2C_WRITE(bin2bcd(dt.month())); 452 Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); 453 Wire.endTransmission(); 454 455 uint8_t statreg = read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG); 456 statreg &= ~0x80; // flip OSF bit 457 write_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG, statreg); 458} 459 460DateTime RTC_DS3231::now() { 461 Wire.beginTransmission(DS3231_ADDRESS); 462 Wire._I2C_WRITE((byte)0); 463 Wire.endTransmission(); 464 465 Wire.requestFrom(DS3231_ADDRESS, 7); 466 uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F); 467 uint8_t mm = bcd2bin(Wire._I2C_READ()); 468 uint8_t hh = bcd2bin(Wire._I2C_READ()); 469 Wire._I2C_READ(); 470 uint8_t d = bcd2bin(Wire._I2C_READ()); 471 uint8_t m = bcd2bin(Wire._I2C_READ()); 472 uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000; 473 474 return DateTime (y, m, d, hh, mm, ss); 475} 476 477Ds3231SqwPinMode RTC_DS3231::readSqwPinMode() { 478 int mode; 479 480 Wire.beginTransmission(DS3231_ADDRESS); 481 Wire._I2C_WRITE(DS3231_CONTROL); 482 Wire.endTransmission(); 483 484 Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1); 485 mode = Wire._I2C_READ(); 486 487 mode &= 0x93; 488 return static_cast<Ds3231SqwPinMode>(mode); 489} 490 491void RTC_DS3231::writeSqwPinMode(Ds3231SqwPinMode mode) { 492 uint8_t ctrl; 493 ctrl = read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL); 494 495 ctrl &= ~0x04; // turn off INTCON 496 ctrl &= ~0x18; // set freq bits to 0 497 498 if (mode == DS3231_OFF) { 499 ctrl |= 0x04; // turn on INTCN 500 } else { 501 ctrl |= mode; 502 } 503 write_i2c_register(DS3231_ADDRESS, DS3231_CONTROL, ctrl); 504 505 //Serial.println( read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL), HEX); 506} 507
Set the time
arduino
since the ds1307 is susceptible to drift away from the correct time. This program allows you to set the time through the Serial Monitor. When you see that the time is not correct simply plugin the rtc module into the arduino and upload this program. Then enter the Serial Monitor and then set the correct date, month, year, time. Then simply upload the other program and the correct time will be displayed on the 7 segment display.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 Much thanks to John Waters and Maurice Ribble for their 6 earlier and very helpful work (even if I didn't wind up 7 using any of their code): 8 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 9 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 10 11 This library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Lesser General Public 13 License as published by the Free Software Foundation; either 14 version 2.1 of the License, or (at your option) any later version. 15 16 This library is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Lesser General Public License for more details. 20 21 You should have received a copy of the GNU Lesser General Public 22 License along with this library; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24*/ 25 26 27#include <Wire.h> 28#include <RealTimeClockDS1307.h> 29 30//RealTimeClock RTC;//=new RealTimeClock(); 31 32#define Display_Clock_Every_N_Seconds 1 33#define Display_ShortHelp_Every_N_Seconds 25 34//#define TEST_Squarewave 35//#define TEST_StopStart 36//#define TEST_1224Switch 37 38int count=0; 39char formatted[] = "00-00-00 00:00:00x"; 40 41void setup() { 42// Wire.begin(); 43 Serial.begin(9600); 44} 45 46void loop() { 47 if(Serial.available()) 48 { 49 processCommand(); 50 } 51 delay(1000); 52 RTC.readClock(); 53 count++; 54 if(count % Display_Clock_Every_N_Seconds == 0){ 55 Serial.print(count); 56 Serial.print(": "); 57 RTC.getFormatted(formatted); 58 Serial.print(formatted); 59 Serial.println(); 60 } 61 62 if(count % Display_ShortHelp_Every_N_Seconds == 0) { 63 Serial.println("Send ? for a list of commands."); 64 } 65#ifdef TEST_Squarewave 66if(count%10 == 0) 67{ 68 switch(count/10 % 6) 69 { 70 case 0: 71 Serial.print("Squarewave disabled (low impedance): "); 72 RTC.sqwDisable(0); 73 Serial.println((int) RTC.readData(7)); 74 break; 75 case 1: 76 Serial.print("Squarewave disabled (high impedance): "); 77 RTC.sqwDisable(1); 78 Serial.println((int) RTC.readData(7)); 79 break; 80 case 2: 81 Serial.println("Squarewave enabled at 1 Hz"); 82 RTC.sqwEnable(RTC.SQW_1Hz); 83 break; 84 case 3: 85 Serial.println("Squarewave enabled at 4.096 kHz"); 86 RTC.sqwEnable(RTC.SQW_4kHz); 87 break; 88 case 4: 89 Serial.println("Squarewave enabled at 8.192 kHz"); 90 RTC.sqwEnable(RTC.SQW_8kHz); 91 break; 92 case 5: 93 Serial.println("Squarewave enabled at 32.768 kHz"); 94 RTC.sqwEnable(RTC.SQW_32kHz); 95 break; 96 default: 97 Serial.println("Squarewave test not defined"); 98 }//switch 99} 100#endif 101 102#ifdef TEST_StopStart 103if(count%10 == 0) 104{ 105 if(!RTC.isStopped()) 106 { 107 if(RTC.getSeconds() < 45) 108 { 109 Serial.println("Stopping clock for 10 seconds"); 110 RTC.stop(); 111 }//if we have enough time 112 } else { 113 RTC.setSeconds(RTC.getSeconds()+11); 114 RTC.start(); 115 Serial.println("Adding 11 seconds and restarting clock"); 116 } 117}//if on a multiple of 10 counts 118#endif 119 120#ifdef TEST_1224Switch 121 if(count%10 == 0) 122 { 123 if(count %20 == 0) 124 { 125 Serial.println("switching to 12-hour time"); 126 RTC.switchTo12h(); 127 RTC.setClock(); 128 } 129 else 130 { 131 Serial.println("switching to 24-hour time"); 132 RTC.switchTo24h(); 133 RTC.setClock(); 134 } 135 } 136#endif 137} 138 139void processCommand() { 140 if(!Serial.available()) { return; } 141 char command = Serial.read(); 142 int in,in2; 143 switch(command) 144 { 145 case 'H': 146 case 'h': 147 in=SerialReadPosInt(); 148 RTC.setHours(in); 149 RTC.setClock(); 150 Serial.print("Setting hours to "); 151 Serial.println(in); 152 break; 153 case 'I': 154 case 'i': 155 in=SerialReadPosInt(); 156 RTC.setMinutes(in); 157 RTC.setClock(); 158 Serial.print("Setting minutes to "); 159 Serial.println(in); 160 break; 161 case 'S': 162 case 's': 163 in=SerialReadPosInt(); 164 RTC.setSeconds(in); 165 RTC.setClock(); 166 Serial.print("Setting seconds to "); 167 Serial.println(in); 168 break; 169 case 'Y': 170 case 'y': 171 in=SerialReadPosInt(); 172 RTC.setYear(in); 173 RTC.setClock(); 174 Serial.print("Setting year to "); 175 Serial.println(in); 176 break; 177 case 'M': 178 case 'm': 179 in=SerialReadPosInt(); 180 RTC.setMonth(in); 181 RTC.setClock(); 182 Serial.print("Setting month to "); 183 Serial.println(in); 184 break; 185 case 'D': 186 case 'd': 187 in=SerialReadPosInt(); 188 RTC.setDate(in); 189 RTC.setClock(); 190 Serial.print("Setting date to "); 191 Serial.println(in); 192 break; 193 case 'W': 194 Serial.print("Day of week is "); 195 Serial.println((int) RTC.getDayOfWeek()); 196 break; 197 case 'w': 198 in=SerialReadPosInt(); 199 RTC.setDayOfWeek(in); 200 RTC.setClock(); 201 Serial.print("Setting day of week to "); 202 Serial.println(in); 203 break; 204 205 case 't': 206 case 'T': 207 if(RTC.is12hour()) { 208 RTC.switchTo24h(); 209 Serial.println("Switching to 24-hour clock."); 210 } else { 211 RTC.switchTo12h(); 212 Serial.println("Switching to 12-hour clock."); 213 } 214 RTC.setClock(); 215 break; 216 217 case 'A': 218 case 'a': 219 if(RTC.is12hour()) { 220 RTC.setAM(); 221 RTC.setClock(); 222 Serial.println("Set AM."); 223 } else { 224 Serial.println("(Set hours only in 24-hour mode.)"); 225 } 226 break; 227 228 case 'P': 229 case 'p': 230 if(RTC.is12hour()) { 231 RTC.setPM(); 232 RTC.setClock(); 233 Serial.println("Set PM."); 234 } else { 235 Serial.println("(Set hours only in 24-hour mode.)"); 236 } 237 break; 238 239 case 'q': 240 RTC.sqwEnable(RTC.SQW_1Hz); 241 Serial.println("Square wave output set to 1Hz"); 242 break; 243 case 'Q': 244 RTC.sqwDisable(0); 245 Serial.println("Square wave output disabled (low)"); 246 break; 247 248 case 'z': 249 RTC.start(); 250 Serial.println("Clock oscillator started."); 251 break; 252 case 'Z': 253 RTC.stop(); 254 Serial.println("Clock oscillator stopped."); 255 break; 256 257 case '>': 258 in=SerialReadPosInt(); 259 in2=SerialReadPosInt(); 260 RTC.writeData(in, in2); 261 Serial.print("Write to register "); 262 Serial.print(in); 263 Serial.print(" the value "); 264 Serial.println(in2); 265 break; 266 case '<': 267 in=SerialReadPosInt(); 268 in2=RTC.readData(in); 269 Serial.print("Read from register "); 270 Serial.print(in); 271 Serial.print(" the value "); 272 Serial.println(in2); 273 break; 274 275 default: 276 Serial.println("Unknown command. Try these:"); 277 Serial.println(" h## - set Hours d## - set Date"); 278 Serial.println(" i## - set mInutes m## - set Month"); 279 Serial.println(" s## - set Seconds y## - set Year"); 280 Serial.println(" w## - set arbitrary day of Week"); 281 Serial.println(" t - toggle 24-hour mode"); 282 Serial.println(" a - set AM p - set PM"); 283 Serial.println(); 284 Serial.println(" z - start clock Z - stop clock"); 285 Serial.println(" q - SQW/OUT = 1Hz Q - stop SQW/OUT"); 286 Serial.println(); 287 Serial.println(" >##,### - write to register ## the value ###"); 288 Serial.println(" <## - read the value in register ##"); 289 290 }//switch on command 291 292} 293 294//read in numeric characters until something else 295//or no more data is available on serial. 296int SerialReadPosInt() { 297 int i = 0; 298 boolean done=false; 299 while(Serial.available() && !done) 300 { 301 char c = Serial.read(); 302 if (c >= '0' && c <='9') 303 { 304 i = i * 10 + (c-'0'); 305 } 306 else 307 { 308 done = true; 309 } 310 } 311 return i; 312}
README.md
c_cpp
add this to the RTClib library
1This is a fork of JeeLab's fantastic real time clock library for Arduino. 2 3For details on using this library with an RTC module like the DS1307, see the guide at: https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview 4 5To download. click the DOWNLOADS button to the right, and rename the uncompressed folder RTClib. 6 7Place the RTClib folder in your *arduinosketchfolder*/libraries/ folder. 8You may need to create the libraries subfolder if its your first library. Restart the IDE. 9 10<!-- START COMPATIBILITY TABLE --> 11 12## Compatibility 13 14MCU | Tested Works | Doesn't Work | Not Tested | Notes 15------------------ | :----------: | :----------: | :---------: | ----- 16Atmega328 @ 16MHz | X | | | 17Atmega328 @ 12MHz | X | | | 18Atmega32u4 @ 16MHz | X | | | Use SDA/SCL on pins D3 & D2 19Atmega32u4 @ 8MHz | X | | | Use SDA/SCL on pins D3 & D2 20ESP8266 | X | | | SDA/SCL default to pins 4 & 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL) 21Atmega2560 @ 16MHz | X | | | Use SDA/SCL on Pins 20 & 21 22ATSAM3X8E | X | | | Use SDA1 and SCL1 23ATSAM21D | X | | | 24ATtiny85 @ 16MHz | X | | | 25ATtiny85 @ 8MHz | X | | | 26Intel Curie @ 32MHz | | | X | 27STM32F2 | | | X | 28 29 * ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini 30 * ATmega328 @ 12MHz : Adafruit Pro Trinket 3V 31 * ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0 32 * ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro 33 * ESP8266 : Adafruit Huzzah 34 * ATmega2560 @ 16MHz : Arduino Mega 35 * ATSAM3X8E : Arduino Due 36 * ATSAM21D : Arduino Zero, M0 Pro 37 * ATtiny85 @ 16MHz : Adafruit Trinket 5V 38 * ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V 39 40<!-- END COMPATIBILITY TABLE --> 41
Clock Code
arduino
The code uses the RTC library and the I2C library. You need these libraries for the program to execute. This program is for Common Anode type display.
1#include <Wire.h> 2#include<EEPROM.h> 3#include <RTClib.h> 4RTC_DS1307 RTC; 5int temp, inc, hours1, minut, add = 11; 6int HOUR, MINUT, SECOND; 7int latchPin = 3; //pin 12 on the 595 o3 3 8int dataPin = 4; //pin 14 on the 595 or 4 9int clockPin = 2; //pin 11 on the 595 or 2 10int shift = 256; 11int units, tens, hundreds, thousands; 12int x; 13int y; 14const int alarmHour = 17; 15const int alarmMinute = 26; 16 17void setup() { 18 Serial.begin(9600); 19 pinMode(latchPin, OUTPUT); 20 pinMode(dataPin, OUTPUT); 21 pinMode(clockPin, OUTPUT); 22 pinMode(13, OUTPUT); 23 Wire.begin(); 24 RTC.begin(); 25 if (!RTC.isrunning()) 26 { 27 RTC.adjust(DateTime(__DATE__, __TIME__)); 28 } 29} 30 31void loop() { 32 int temp = 0, val = 1, temp4; 33 DateTime now = RTC.now(); 34 HOUR = now.hour(); 35 MINUT = now.minute(); 36 //Serial.println(MINUT); 37 if (HOUR < 10) 38 { 39 hundreds = HOUR; 40 thousands = HOUR/10; 41 } 42 else if (HOUR >= 10 && HOUR < 24) 43 { 44 hundreds = HOUR % 10; 45 thousands = HOUR / 10; 46 } 47 if (MINUT <= 9) 48 { 49 units = MINUT; 50 tens = MINUT/10; 51 } 52 53 else if (MINUT > 9 && MINUT <= 60) 54 { 55 units = MINUT % 10; 56 tens = MINUT / 10; 57 } 58 59 switch (units) 60 { 61 case 0: 62 //0 63 digitalWrite(latchPin, LOW); 64 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 65 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 192 ); 66 digitalWrite(latchPin, HIGH); 67 break; 68 case 1: 69 //1 70 digitalWrite(latchPin, LOW); 71 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 72 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 249); 73 digitalWrite(latchPin, HIGH); 74 break; 75 case 2: 76 //2 77 digitalWrite(latchPin, LOW); 78 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 79 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 164); 80 digitalWrite(latchPin, HIGH); 81 break; 82 case 3: 83 //3 84 digitalWrite(latchPin, LOW); 85 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 86 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 176); 87 digitalWrite(latchPin, HIGH); 88 break; 89 case 4: 90 //4 91 digitalWrite(latchPin, LOW); 92 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 93 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 153); 94 digitalWrite(latchPin, HIGH); 95 break; 96 case 5: 97 //5 98 digitalWrite(latchPin, LOW); 99 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 100 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 146); 101 digitalWrite(latchPin, HIGH); 102 break; 103 case 6: 104 //6 105 digitalWrite(latchPin, LOW); 106 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 107 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 130); 108 digitalWrite(latchPin, HIGH); 109 break; 110 case 7: 111 //7 112 digitalWrite(latchPin, LOW); 113 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 114 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 248); 115 digitalWrite(latchPin, HIGH); 116 break; 117 case 8: 118 //8 119 digitalWrite(latchPin, LOW); 120 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 121 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 128); 122 digitalWrite(latchPin, HIGH); 123 break; 124 case 9: 125 //9 126 digitalWrite(latchPin, LOW); 127 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 128 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 144); 129 digitalWrite(latchPin, HIGH); 130 break; 131 } 132 delay(1); 133 134 135 switch (tens) 136 { 137 case 0: 138 //0 139 digitalWrite(latchPin, LOW); 140 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 141 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 192 ); 142 digitalWrite(latchPin, HIGH); 143 break; 144 case 1: 145 //1 146 digitalWrite(latchPin, LOW); 147 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 148 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 249); 149 digitalWrite(latchPin, HIGH); 150 break; 151 case 2: 152 //2 153 digitalWrite(latchPin, LOW); 154 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 155 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 164); 156 digitalWrite(latchPin, HIGH); 157 break; 158 case 3: 159 //3 160 digitalWrite(latchPin, LOW); 161 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 162 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 176); 163 digitalWrite(latchPin, HIGH); 164 break; 165 case 4: 166 //4 167 digitalWrite(latchPin, LOW); 168 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 169 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 153); 170 digitalWrite(latchPin, HIGH); 171 break; 172 case 5: 173 //5 174 digitalWrite(latchPin, LOW); 175 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 176 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 146); 177 digitalWrite(latchPin, HIGH); 178 break; 179 180 } 181 delay(1); 182 183 switch (hundreds) 184 { 185 case 0: 186 //0 187 digitalWrite(latchPin, LOW); 188 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 189 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 64 ); 190 digitalWrite(latchPin, HIGH); 191 break; 192 case 1: 193 //1 194 digitalWrite(latchPin, LOW); 195 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 196 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 121); 197 digitalWrite(latchPin, HIGH); 198 199 break; 200 case 2: 201 //2 202 digitalWrite(latchPin, LOW); 203 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 204 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 36); 205 digitalWrite(latchPin, HIGH); 206 break; 207 case 3: 208 //3 209 digitalWrite(latchPin, LOW); 210 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 211 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 48); 212 digitalWrite(latchPin, HIGH); 213 break; 214 case 4: 215 //4 216 digitalWrite(latchPin, LOW); 217 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 218 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 25); 219 digitalWrite(latchPin, HIGH); 220 break; 221 case 5: 222 //5 223 digitalWrite(latchPin, LOW); 224 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 225 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 18); 226 digitalWrite(latchPin, HIGH); 227 break; 228 case 6: 229 //6 230 digitalWrite(latchPin, LOW); 231 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 232 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 2); 233 digitalWrite(latchPin, HIGH); 234 break; 235 case 7: 236 //7 237 digitalWrite(latchPin, LOW); 238 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 239 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 120); 240 digitalWrite(latchPin, HIGH); 241 break; 242 case 8: 243 //8 244 digitalWrite(latchPin, LOW); 245 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 246 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 0); 247 digitalWrite(latchPin, HIGH); 248 break; 249 case 9: 250 //9 251 digitalWrite(latchPin, LOW); 252 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 253 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 16); 254 digitalWrite(latchPin, HIGH); 255 break; 256 257 } 258 delay(1); 259 260 switch (thousands) 261 { 262 case 0: 263 //0 264 digitalWrite(latchPin, LOW); 265 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 266 shiftOut(dataPin, clockPin, MSBFIRST, shift + 192 ); 267 digitalWrite(latchPin, HIGH); 268 //delay(500); 269 break; 270 case 1: 271 //1 272 digitalWrite(latchPin, LOW); 273 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 274 shiftOut(dataPin, clockPin, MSBFIRST, shift + 249); 275 digitalWrite(latchPin, HIGH); 276 //delay(500); 277 break; 278 case 2: 279 //2 280 digitalWrite(latchPin, LOW); 281 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 282 shiftOut(dataPin, clockPin, MSBFIRST, shift + 164); 283 digitalWrite(latchPin, HIGH); 284 //delay(500); 285 break; 286 case 3: 287 //3 288 digitalWrite(latchPin, LOW); 289 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 290 shiftOut(dataPin, clockPin, MSBFIRST, shift + 176); 291 digitalWrite(latchPin, HIGH); 292 //delay(500); 293 break; 294 case 4: 295 //4 296 digitalWrite(latchPin, LOW); 297 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 298 shiftOut(dataPin, clockPin, MSBFIRST, shift + 153); 299 digitalWrite(latchPin, HIGH); 300 //delay(500); 301 break; 302 case 5: 303 //5 304 digitalWrite(latchPin, LOW); 305 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 306 shiftOut(dataPin, clockPin, MSBFIRST, shift + 146); 307 digitalWrite(latchPin, HIGH); 308 //delay(500); 309 break; 310 case 6: 311 //6 312 digitalWrite(latchPin, LOW); 313 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 314 shiftOut(dataPin, clockPin, MSBFIRST, shift + 130); 315 digitalWrite(latchPin, HIGH); 316 //delay(500); 317 break; 318 case 7: 319 //7 320 digitalWrite(latchPin, LOW); 321 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 322 shiftOut(dataPin, clockPin, MSBFIRST, shift + 248); 323 digitalWrite(latchPin, HIGH); 324 //delay(500); 325 break; 326 case 8: 327 //8 328 digitalWrite(latchPin, LOW); 329 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 330 shiftOut(dataPin, clockPin, MSBFIRST, shift + 128); 331 digitalWrite(latchPin, HIGH); 332 333 break; 334 case 9: 335 //9 336 digitalWrite(latchPin, LOW); 337 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 338 shiftOut(dataPin, clockPin, MSBFIRST, shift + 152); 339 digitalWrite(latchPin, HIGH); 340 break; 341 } 342 delay(1); 343 //alarm section 344 if (HOUR == alarmHour && MINUT == alarmMinute) 345 { 346 digitalWrite(13, HIGH); 347 } 348 else 349 { 350 digitalWrite(13, LOW); 351 } 352 353}
another file
c_cpp
add this to the 'RealTimeClockDS1307' folder.
1######################################### 2# Syntax Coloring Map RealTimeClockDS1307 3######################################### 4 5 6####################################### 7# Instances (KEYWORD2) 8####################################### 9RTC KEYWORD2 10 11######################################### 12# Methods and Functions (KEYWORD2) 13######################################### 14readClock KEYWORD2 15setClock KEYWORD2 16stop KEYWORD2 17start KEYWORD2 18sqwEnable KEYWORD2 19sqwDisable KEYWORD2 20writeData KEYWORD2 21readData KEYWORD2 22 23getHours KEYWORD2 24getMinutes KEYWORD2 25getSeconds KEYWORD2 26getYear KEYWORD2 27getMonth KEYWORD2 28getDate KEYWORD2 29getDay KEYWORD2 30getDayOfWeek KEYWORD2 31is12hour KEYWORD2 32isPM KEYWORD2 33isStopped KEYWORD2 34getFormatted KEYWORD2 35getFormatted2k KEYWORD2 36 37setSeconds KEYWORD2 38setMinutes KEYWORD2 39setHours KEYWORD2 40setAM KEYWORD2 41setPM KEYWORD2 42set24h KEYWORD2 43switchTo24h KEYWORD2 44switchTo12h KEYWORD2 45setDayOfWeek KEYWORD2 46setDate KEYWORD2 47setDay KEYWORD2 48setMonth KEYWORD2 49setYear KEYWORD2 50 51######################################### 52# Constants (LITERAL1) 53######################################### 54SQW_1Hz LITERAL1 55SQW_4kHz LITERAL1 56SQW_8kHz LITERAL1 57SQW_32kHz LITERAL1 58
RealTimeClockDS1307.cpp
c_cpp
This is one of the library files of the real time clock. Create a folder named "RealTimeClockDS1307" and copy this into this folder. That's all you got to do. No need to compile it.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 v0.92 Updated for Arduino 1.00; not re-tested on earlier versions 6 7 Much thanks to John Waters and Maurice Ribble for their 8 earlier and very helpful work (even if I didn't wind up 9 using any of their code): 10 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 11 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*/ 27 28/****************************************************************************** 29 * Includes 30 ******************************************************************************/ 31 32#include "RealTimeClockDS1307.h" 33#include <Wire.h> 34 35/****************************************************************************** 36 * Definitions 37 ******************************************************************************/ 38 39#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address 40 41/****************************************************************************** 42 * Constructors 43 ******************************************************************************/ 44 45RealTimeClockDS1307::RealTimeClockDS1307() 46{ 47 Wire.begin(); 48 //must NOT attempt to read the clock before 49 //Wire.begin() has not been called; readClock() will hang. 50 //Fortunately, it seems that you can call Wire.begin() 51 //multiple times with no adverse effect). 52} 53 54/****************************************************************************** 55 * User API 56 ******************************************************************************/ 57 58/***** CHIP READ/WRITE ******/ 59 60void RealTimeClockDS1307::readClock() 61{ 62 // Reset the register pointer 63 Wire.beginTransmission(DS1307_I2C_ADDRESS); 64 Wire.write((uint8_t) 0x00); 65 Wire.endTransmission(); 66 67 Wire.requestFrom(DS1307_I2C_ADDRESS, 8); 68 _reg0_sec = Wire.read(); 69 _reg1_min = Wire.read(); 70 _reg2_hour = Wire.read(); 71 _reg3_day = Wire.read(); 72 _reg4_date = Wire.read(); 73 _reg5_month = Wire.read(); 74 _reg6_year = Wire.read(); 75 _reg7_sqw = Wire.read(); 76} 77 78void RealTimeClockDS1307::setClock() 79{ 80 //to be paranoid, we're going to first stop the clock 81 //to ensure we don't have rollovers while we're 82 //writing: 83 writeData(0,0x80); 84 //now, we'll write everything *except* the second 85 Wire.beginTransmission(DS1307_I2C_ADDRESS); 86 Wire.write((uint8_t) 0x01); 87 Wire.write(_reg1_min); 88 Wire.write(_reg2_hour); 89 Wire.write(_reg3_day); 90 Wire.write(_reg4_date); 91 Wire.write(_reg5_month); 92 Wire.write(_reg6_year); 93 Wire.endTransmission(); 94 //now, we'll write the seconds; we didn't have to keep 95 //track of whether the clock was already running, because 96 //_reg0_sec already knows what we want it to be. This 97 //will restart the clock as it writes the new seconds value. 98 writeData(0,_reg0_sec); 99} 100 101void RealTimeClockDS1307::stop() 102{ 103 //"Bit 7 of register 0 is the clock halt (CH) bit. 104 //When this bit is set to a 1, the oscillator is disabled." 105 _reg0_sec = _reg0_sec | 0x80; 106 writeData(0,_reg0_sec); 107} 108void RealTimeClockDS1307::start() 109{ 110 //"Bit 7 of register 0 is the clock halt (CH) bit. 111 //When this bit is set to a 1, the oscillator is disabled." 112 _reg0_sec = _reg0_sec & ~0x80; 113 writeData(0,_reg0_sec); 114} 115 116void RealTimeClockDS1307::writeData(byte regNo, byte value) 117{ 118 if(regNo > 0x3F) { return; } 119 Wire.beginTransmission(DS1307_I2C_ADDRESS); 120 Wire.write(regNo); 121 Wire.write(value); 122 Wire.endTransmission(); 123} 124 125void RealTimeClockDS1307::writeData(byte regNo, void * source, int length) 126{ 127 char * p = (char*) source; 128 if(regNo > 0x3F || length > 0x3F) { return; } 129 Wire.beginTransmission(DS1307_I2C_ADDRESS); 130 Wire.write(regNo); 131 for(int i=0; i<length; i++) { 132 Wire.write(*p); 133 p++; 134 } 135 Wire.endTransmission(); 136} 137 138byte RealTimeClockDS1307::readData(byte regNo) 139{ 140 if(regNo > 0x3F) { return 0xff; } 141 Wire.beginTransmission(DS1307_I2C_ADDRESS); 142 Wire.write(regNo); 143 Wire.endTransmission(); 144 Wire.requestFrom(DS1307_I2C_ADDRESS, 1); 145 return Wire.read(); 146} 147 148void RealTimeClockDS1307::readData(byte regNo, void * dest, int length) 149{ 150 char * p = (char*) dest; 151 if(regNo > 0x3F || length > 0x3F) { return; } 152 Wire.beginTransmission(DS1307_I2C_ADDRESS); 153 Wire.write(regNo); 154 Wire.endTransmission(); 155 Wire.requestFrom(DS1307_I2C_ADDRESS, length); 156 for(int i=0; i<length; i++) { 157 *p=Wire.read(); 158 p++; 159 } 160} 161 162 163void RealTimeClockDS1307::sqwEnable(byte frequency) 164{ 165 if(frequency > 3) { return; } 166 //bit 4 is enable (0x10); 167 //bit 7 is current output state if disabled 168 _reg7_sqw = _reg7_sqw & 0x80 | 0x10 | frequency; 169 writeData(0x07, _reg7_sqw); 170} 171 172void RealTimeClockDS1307::sqwDisable(boolean outputLevel) 173{ 174 //bit 7 0x80 output + bit 4 0x10 enable both to zero, 175 //the OR with the boolean shifted up to bit 7 176 _reg7_sqw = _reg7_sqw & ~0x90 | (outputLevel << 7); 177 writeData(0x07, _reg7_sqw); 178 //note: per the data sheet, "OUT (Output control): This bit controls 179 //the output level of the SQW/OUT pin when the square wave 180 //output is disabled. If SQWE = 0, the logic level on the 181 //SQW/OUT pin is 1 if OUT = 1 and is 0 if OUT = 0." 182 //"The SQW/OUT pin is open drain and requires an external 183 //pull-up resistor." 184 //It is worth mentioning that on the Sparkfun breakout board, 185 //BOB-00099, a LED connected to the SQW pin through a resistor to 186 //Vcc+5V illuminated when OUT=0 and was dark when OUT=1, the 187 //opposite of what I expected until I remembered that it is 188 //an open drain (google it if you need to). Basically, they don't 189 //so much mean a logic level (e.g., +3.3V rel Gnd) as they mean 190 //high or low *impeadance* to ground (drain). So High is basically 191 //an open switch. Low connects to ground. 192} 193 194 195/***** GETTERS ******/ 196 197boolean RealTimeClockDS1307::is12hour() 198{ 199 //12-hour mode has bit 6 of the hour register set high 200 return ((_reg2_hour & 0x40) == 0x40); 201} 202boolean RealTimeClockDS1307::isPM() 203{ 204 //if in 12-hour mode, but 5 of the hour register indicates PM 205 if(is12hour()) { 206 return ((_reg2_hour & 0x20) == 0x20); 207 } 208 //otherwise, let's consider any time with the hour >11 to be PM: 209 return (getHours() > 11); 210} 211boolean RealTimeClockDS1307::isStopped() 212{ 213 //bit 7 of the seconds register stopps the clock when high 214 return ((_reg0_sec & 0x80) == 0x80); 215} 216 217int RealTimeClockDS1307::getHours() 218{ 219 if(is12hour()) { 220 //do not include bit 5, the am/pm indicator 221 return bcdToDec(_reg2_hour & 0x1f); 222 } 223 //bits 4-5 are tens of hours 224 return bcdToDec(_reg2_hour & 0x3f); 225} 226int RealTimeClockDS1307::getMinutes() 227{ 228 //could mask with 0x7f but shouldn't need to 229 return bcdToDec(_reg1_min); 230} 231int RealTimeClockDS1307::getSeconds() 232{ 233 //need to mask oscillator start/stop bit 7 234 return bcdToDec(_reg0_sec & 0x7f); 235} 236int RealTimeClockDS1307::getYear() 237{ 238 return bcdToDec(_reg6_year); 239} 240int RealTimeClockDS1307::getMonth() 241{ 242 //could mask with 0x1f but shouldn't need to 243 return bcdToDec(_reg5_month); 244} 245int RealTimeClockDS1307::getDate() 246{ 247 //could mask with 0x3f but shouldn't need to 248 return bcdToDec(_reg4_date); 249} 250int RealTimeClockDS1307::getDay() 251{ 252 return getDate(); 253} 254int RealTimeClockDS1307::getDayOfWeek() 255{ 256 //could mask with 0x07 but shouldn't need to 257 return bcdToDec(_reg3_day); 258} 259 260void RealTimeClockDS1307::getFormatted(char * buffer) 261{ 262 int i=0; 263 //target string format: YY-MM-DD HH:II:SS 264 buffer[i++]=highNybbleToASCII(_reg6_year); 265 buffer[i++]=lowNybbleToASCII(_reg6_year); 266 buffer[i++]='-'; 267 buffer[i++]=highNybbleToASCII(_reg5_month & 0x1f); 268 buffer[i++]=lowNybbleToASCII(_reg5_month); 269 buffer[i++]='-'; 270 buffer[i++]=highNybbleToASCII(_reg4_date & 0x3f); 271 buffer[i++]=lowNybbleToASCII(_reg4_date); 272 buffer[i++]=' '; 273 if(is12hour()) { 274 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x1f); 275 } else { 276 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x3f); 277 } 278 buffer[i++]=lowNybbleToASCII(_reg2_hour); 279 buffer[i++]=':'; 280 buffer[i++]=highNybbleToASCII(_reg1_min & 0x7f); 281 buffer[i++]=lowNybbleToASCII(_reg1_min); 282 buffer[i++]=':'; 283 buffer[i++]=highNybbleToASCII(_reg0_sec & 0x7f); 284 buffer[i++]=lowNybbleToASCII(_reg0_sec); 285 if(is12hour()) { 286 if(isPM()) { 287 buffer[i++]='P'; 288 } else { 289 buffer[i++]='A'; 290 } 291 } 292 buffer[i++]=0x00; 293} 294 295void RealTimeClockDS1307::getFormatted2k(char * buffer) 296{ 297 buffer[0]='2'; 298 buffer[1]='0'; 299 getFormatted(&buffer[2]); 300} 301 302/**** SETTERS *****/ 303 304void RealTimeClockDS1307::setSeconds(int s) 305{ 306 if (s < 60 && s >=0) 307 { 308 //need to preserve oscillator bit 309 _reg0_sec = decToBcd(s) | (_reg0_sec & 0x80); 310 } 311} 312void RealTimeClockDS1307::setMinutes(int m) 313{ 314 if (m < 60 && m >=0) 315 { 316 _reg1_min = decToBcd(m); 317 } 318} 319void RealTimeClockDS1307::setHours(int h) 320{ 321 if (is12hour()) 322 { 323 if (h >= 1 && h <=12) 324 { 325 //preserve 12/24 and AM/PM bits 326 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x60); 327 } 328 } else { 329 if (h >= 0 && h <=24) 330 { 331 //preserve 12/24 bit 332 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x40); 333 } 334 }//else 335}//setHours 336 337void RealTimeClockDS1307::set24h() 338{ 339 //"Bit 6 of the hours register is defined as the 340 //"12- or 24-hour mode select bit. 341 //"When high, the 12-hour mode is selected" 342 //So, mask the curent value with the complement turn off that bit: 343 _reg2_hour = _reg2_hour & ~0x40; 344} 345void RealTimeClockDS1307::setAM() 346{ 347 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 348 //so we need to OR with 0x40 to set 12-hour mode and also 349 //turn off the PM bit by masking with the complement 350 _reg2_hour = _reg2_hour & ~0x20 | 0x40; 351} 352void RealTimeClockDS1307::setPM() 353{ 354 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 355 //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also 356 //turn on the PM bit: 357 _reg2_hour = _reg2_hour | 0x60; 358} 359 360void RealTimeClockDS1307::switchTo12h() 361{ 362 if(is12hour()) { return; } 363 int h = getHours(); 364 if (h < 12) { 365 setAM(); 366 } else { 367 h = h-12; 368 setPM(); 369 } 370 if (h==0) 371 { 372 h=12; 373 } 374 setHours(h); 375} 376void RealTimeClockDS1307::switchTo24h() 377{ 378 if(!is12hour()) { return ; } 379 int h = getHours(); 380 if(h==12) {//12 PM is just 12; 12 AM is 0 hours. 381 h = 0; 382 } 383 if (isPM()) 384 {//if it was 12 PM, then h=0 above and so we're back to 12: 385 h = h+12; 386 } 387 set24h(); 388 setHours(h); 389} 390 391void RealTimeClockDS1307::setDayOfWeek(int d) 392{ 393 if (d > 0 && d < 8) 394 { 395 _reg3_day = decToBcd(d); 396 } 397} 398 399void RealTimeClockDS1307::setDate(int d) 400{ 401 if (d > 0 && d < 32) 402 { 403 _reg4_date = decToBcd(d); 404 } 405} 406void RealTimeClockDS1307::setDay(int d) 407{ 408 setDate(d); 409} 410 411void RealTimeClockDS1307::setMonth(int m) 412{ 413 if (m > 0 && m < 13) 414 { 415 _reg5_month = decToBcd(m); 416 } 417} 418void RealTimeClockDS1307::setYear(int y) 419{ 420 if (y >= 0 && y <100) 421 { 422 _reg6_year = decToBcd(y); 423 } 424} 425 426 427 428/***************************************** 429 * Private methods 430 *****************************************/ 431byte RealTimeClockDS1307::decToBcd(byte b) 432{ 433 return ( ((b/10) << 4) + (b%10) ); 434} 435 436// Convert binary coded decimal to normal decimal numbers 437byte RealTimeClockDS1307::bcdToDec(byte b) 438{ 439 return ( ((b >> 4)*10) + (b%16) ); 440} 441 442char RealTimeClockDS1307::lowNybbleToASCII(byte b) 443{ 444 b = b & 0x0f; 445 if(b < 10) { 446 //0 is ASCII 48 447 return 48+b; 448 } 449 //A is ASCII 55 450 return 55+b; 451} 452char RealTimeClockDS1307::highNybbleToASCII(byte b) 453{ 454 return lowNybbleToASCII(b >> 4); 455} 456 457/***** INSTANCE *******/ 458 459RealTimeClockDS1307 RTC = RealTimeClockDS1307(); 460
RTClib
c_cpp
add this to the RTClib folder
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 v0.92 Updated for Arduino 1.00; not re-tested on earlier versions 6 7 Much thanks to John Waters and Maurice Ribble for their 8 earlier and very helpful work (even if I didn't wind up 9 using any of their code): 10 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 11 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*/ 27 28/****************************************************************************** 29 * Includes 30 ******************************************************************************/ 31 32#include "RealTimeClockDS1307.h" 33#include <Wire.h> 34 35/****************************************************************************** 36 * Definitions 37 ******************************************************************************/ 38 39#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address 40 41/****************************************************************************** 42 * Constructors 43 ******************************************************************************/ 44 45RealTimeClockDS1307::RealTimeClockDS1307() 46{ 47 Wire.begin(); 48 //must NOT attempt to read the clock before 49 //Wire.begin() has not been called; readClock() will hang. 50 //Fortunately, it seems that you can call Wire.begin() 51 //multiple times with no adverse effect). 52} 53 54/****************************************************************************** 55 * User API 56 ******************************************************************************/ 57 58/***** CHIP READ/WRITE ******/ 59 60void RealTimeClockDS1307::readClock() 61{ 62 // Reset the register pointer 63 Wire.beginTransmission(DS1307_I2C_ADDRESS); 64 Wire.write((uint8_t) 0x00); 65 Wire.endTransmission(); 66 67 Wire.requestFrom(DS1307_I2C_ADDRESS, 8); 68 _reg0_sec = Wire.read(); 69 _reg1_min = Wire.read(); 70 _reg2_hour = Wire.read(); 71 _reg3_day = Wire.read(); 72 _reg4_date = Wire.read(); 73 _reg5_month = Wire.read(); 74 _reg6_year = Wire.read(); 75 _reg7_sqw = Wire.read(); 76} 77 78void RealTimeClockDS1307::setClock() 79{ 80 //to be paranoid, we're going to first stop the clock 81 //to ensure we don't have rollovers while we're 82 //writing: 83 writeData(0,0x80); 84 //now, we'll write everything *except* the second 85 Wire.beginTransmission(DS1307_I2C_ADDRESS); 86 Wire.write((uint8_t) 0x01); 87 Wire.write(_reg1_min); 88 Wire.write(_reg2_hour); 89 Wire.write(_reg3_day); 90 Wire.write(_reg4_date); 91 Wire.write(_reg5_month); 92 Wire.write(_reg6_year); 93 Wire.endTransmission(); 94 //now, we'll write the seconds; we didn't have to keep 95 //track of whether the clock was already running, because 96 //_reg0_sec already knows what we want it to be. This 97 //will restart the clock as it writes the new seconds value. 98 writeData(0,_reg0_sec); 99} 100 101void RealTimeClockDS1307::stop() 102{ 103 //"Bit 7 of register 0 is the clock halt (CH) bit. 104 //When this bit is set to a 1, the oscillator is disabled." 105 _reg0_sec = _reg0_sec | 0x80; 106 writeData(0,_reg0_sec); 107} 108void RealTimeClockDS1307::start() 109{ 110 //"Bit 7 of register 0 is the clock halt (CH) bit. 111 //When this bit is set to a 1, the oscillator is disabled." 112 _reg0_sec = _reg0_sec & ~0x80; 113 writeData(0,_reg0_sec); 114} 115 116void RealTimeClockDS1307::writeData(byte regNo, byte value) 117{ 118 if(regNo > 0x3F) { return; } 119 Wire.beginTransmission(DS1307_I2C_ADDRESS); 120 Wire.write(regNo); 121 Wire.write(value); 122 Wire.endTransmission(); 123} 124 125void RealTimeClockDS1307::writeData(byte regNo, void * source, int length) 126{ 127 char * p = (char*) source; 128 if(regNo > 0x3F || length > 0x3F) { return; } 129 Wire.beginTransmission(DS1307_I2C_ADDRESS); 130 Wire.write(regNo); 131 for(int i=0; i<length; i++) { 132 Wire.write(*p); 133 p++; 134 } 135 Wire.endTransmission(); 136} 137 138byte RealTimeClockDS1307::readData(byte regNo) 139{ 140 if(regNo > 0x3F) { return 0xff; } 141 Wire.beginTransmission(DS1307_I2C_ADDRESS); 142 Wire.write(regNo); 143 Wire.endTransmission(); 144 Wire.requestFrom(DS1307_I2C_ADDRESS, 1); 145 return Wire.read(); 146} 147 148void RealTimeClockDS1307::readData(byte regNo, void * dest, int length) 149{ 150 char * p = (char*) dest; 151 if(regNo > 0x3F || length > 0x3F) { return; } 152 Wire.beginTransmission(DS1307_I2C_ADDRESS); 153 Wire.write(regNo); 154 Wire.endTransmission(); 155 Wire.requestFrom(DS1307_I2C_ADDRESS, length); 156 for(int i=0; i<length; i++) { 157 *p=Wire.read(); 158 p++; 159 } 160} 161 162 163void RealTimeClockDS1307::sqwEnable(byte frequency) 164{ 165 if(frequency > 3) { return; } 166 //bit 4 is enable (0x10); 167 //bit 7 is current output state if disabled 168 _reg7_sqw = _reg7_sqw & 0x80 | 0x10 | frequency; 169 writeData(0x07, _reg7_sqw); 170} 171 172void RealTimeClockDS1307::sqwDisable(boolean outputLevel) 173{ 174 //bit 7 0x80 output + bit 4 0x10 enable both to zero, 175 //the OR with the boolean shifted up to bit 7 176 _reg7_sqw = _reg7_sqw & ~0x90 | (outputLevel << 7); 177 writeData(0x07, _reg7_sqw); 178 //note: per the data sheet, "OUT (Output control): This bit controls 179 //the output level of the SQW/OUT pin when the square wave 180 //output is disabled. If SQWE = 0, the logic level on the 181 //SQW/OUT pin is 1 if OUT = 1 and is 0 if OUT = 0." 182 //"The SQW/OUT pin is open drain and requires an external 183 //pull-up resistor." 184 //It is worth mentioning that on the Sparkfun breakout board, 185 //BOB-00099, a LED connected to the SQW pin through a resistor to 186 //Vcc+5V illuminated when OUT=0 and was dark when OUT=1, the 187 //opposite of what I expected until I remembered that it is 188 //an open drain (google it if you need to). Basically, they don't 189 //so much mean a logic level (e.g., +3.3V rel Gnd) as they mean 190 //high or low *impeadance* to ground (drain). So High is basically 191 //an open switch. Low connects to ground. 192} 193 194 195/***** GETTERS ******/ 196 197boolean RealTimeClockDS1307::is12hour() 198{ 199 //12-hour mode has bit 6 of the hour register set high 200 return ((_reg2_hour & 0x40) == 0x40); 201} 202boolean RealTimeClockDS1307::isPM() 203{ 204 //if in 12-hour mode, but 5 of the hour register indicates PM 205 if(is12hour()) { 206 return ((_reg2_hour & 0x20) == 0x20); 207 } 208 //otherwise, let's consider any time with the hour >11 to be PM: 209 return (getHours() > 11); 210} 211boolean RealTimeClockDS1307::isStopped() 212{ 213 //bit 7 of the seconds register stopps the clock when high 214 return ((_reg0_sec & 0x80) == 0x80); 215} 216 217int RealTimeClockDS1307::getHours() 218{ 219 if(is12hour()) { 220 //do not include bit 5, the am/pm indicator 221 return bcdToDec(_reg2_hour & 0x1f); 222 } 223 //bits 4-5 are tens of hours 224 return bcdToDec(_reg2_hour & 0x3f); 225} 226int RealTimeClockDS1307::getMinutes() 227{ 228 //could mask with 0x7f but shouldn't need to 229 return bcdToDec(_reg1_min); 230} 231int RealTimeClockDS1307::getSeconds() 232{ 233 //need to mask oscillator start/stop bit 7 234 return bcdToDec(_reg0_sec & 0x7f); 235} 236int RealTimeClockDS1307::getYear() 237{ 238 return bcdToDec(_reg6_year); 239} 240int RealTimeClockDS1307::getMonth() 241{ 242 //could mask with 0x1f but shouldn't need to 243 return bcdToDec(_reg5_month); 244} 245int RealTimeClockDS1307::getDate() 246{ 247 //could mask with 0x3f but shouldn't need to 248 return bcdToDec(_reg4_date); 249} 250int RealTimeClockDS1307::getDay() 251{ 252 return getDate(); 253} 254int RealTimeClockDS1307::getDayOfWeek() 255{ 256 //could mask with 0x07 but shouldn't need to 257 return bcdToDec(_reg3_day); 258} 259 260void RealTimeClockDS1307::getFormatted(char * buffer) 261{ 262 int i=0; 263 //target string format: YY-MM-DD HH:II:SS 264 buffer[i++]=highNybbleToASCII(_reg6_year); 265 buffer[i++]=lowNybbleToASCII(_reg6_year); 266 buffer[i++]='-'; 267 buffer[i++]=highNybbleToASCII(_reg5_month & 0x1f); 268 buffer[i++]=lowNybbleToASCII(_reg5_month); 269 buffer[i++]='-'; 270 buffer[i++]=highNybbleToASCII(_reg4_date & 0x3f); 271 buffer[i++]=lowNybbleToASCII(_reg4_date); 272 buffer[i++]=' '; 273 if(is12hour()) { 274 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x1f); 275 } else { 276 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x3f); 277 } 278 buffer[i++]=lowNybbleToASCII(_reg2_hour); 279 buffer[i++]=':'; 280 buffer[i++]=highNybbleToASCII(_reg1_min & 0x7f); 281 buffer[i++]=lowNybbleToASCII(_reg1_min); 282 buffer[i++]=':'; 283 buffer[i++]=highNybbleToASCII(_reg0_sec & 0x7f); 284 buffer[i++]=lowNybbleToASCII(_reg0_sec); 285 if(is12hour()) { 286 if(isPM()) { 287 buffer[i++]='P'; 288 } else { 289 buffer[i++]='A'; 290 } 291 } 292 buffer[i++]=0x00; 293} 294 295void RealTimeClockDS1307::getFormatted2k(char * buffer) 296{ 297 buffer[0]='2'; 298 buffer[1]='0'; 299 getFormatted(&buffer[2]); 300} 301 302/**** SETTERS *****/ 303 304void RealTimeClockDS1307::setSeconds(int s) 305{ 306 if (s < 60 && s >=0) 307 { 308 //need to preserve oscillator bit 309 _reg0_sec = decToBcd(s) | (_reg0_sec & 0x80); 310 } 311} 312void RealTimeClockDS1307::setMinutes(int m) 313{ 314 if (m < 60 && m >=0) 315 { 316 _reg1_min = decToBcd(m); 317 } 318} 319void RealTimeClockDS1307::setHours(int h) 320{ 321 if (is12hour()) 322 { 323 if (h >= 1 && h <=12) 324 { 325 //preserve 12/24 and AM/PM bits 326 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x60); 327 } 328 } else { 329 if (h >= 0 && h <=24) 330 { 331 //preserve 12/24 bit 332 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x40); 333 } 334 }//else 335}//setHours 336 337void RealTimeClockDS1307::set24h() 338{ 339 //"Bit 6 of the hours register is defined as the 340 //"12- or 24-hour mode select bit. 341 //"When high, the 12-hour mode is selected" 342 //So, mask the curent value with the complement turn off that bit: 343 _reg2_hour = _reg2_hour & ~0x40; 344} 345void RealTimeClockDS1307::setAM() 346{ 347 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 348 //so we need to OR with 0x40 to set 12-hour mode and also 349 //turn off the PM bit by masking with the complement 350 _reg2_hour = _reg2_hour & ~0x20 | 0x40; 351} 352void RealTimeClockDS1307::setPM() 353{ 354 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 355 //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also 356 //turn on the PM bit: 357 _reg2_hour = _reg2_hour | 0x60; 358} 359 360void RealTimeClockDS1307::switchTo12h() 361{ 362 if(is12hour()) { return; } 363 int h = getHours(); 364 if (h < 12) { 365 setAM(); 366 } else { 367 h = h-12; 368 setPM(); 369 } 370 if (h==0) 371 { 372 h=12; 373 } 374 setHours(h); 375} 376void RealTimeClockDS1307::switchTo24h() 377{ 378 if(!is12hour()) { return ; } 379 int h = getHours(); 380 if(h==12) {//12 PM is just 12; 12 AM is 0 hours. 381 h = 0; 382 } 383 if (isPM()) 384 {//if it was 12 PM, then h=0 above and so we're back to 12: 385 h = h+12; 386 } 387 set24h(); 388 setHours(h); 389} 390 391void RealTimeClockDS1307::setDayOfWeek(int d) 392{ 393 if (d > 0 && d < 8) 394 { 395 _reg3_day = decToBcd(d); 396 } 397} 398 399void RealTimeClockDS1307::setDate(int d) 400{ 401 if (d > 0 && d < 32) 402 { 403 _reg4_date = decToBcd(d); 404 } 405} 406void RealTimeClockDS1307::setDay(int d) 407{ 408 setDate(d); 409} 410 411void RealTimeClockDS1307::setMonth(int m) 412{ 413 if (m > 0 && m < 13) 414 { 415 _reg5_month = decToBcd(m); 416 } 417} 418void RealTimeClockDS1307::setYear(int y) 419{ 420 if (y >= 0 && y <100) 421 { 422 _reg6_year = decToBcd(y); 423 } 424} 425 426 427 428/***************************************** 429 * Private methods 430 *****************************************/ 431byte RealTimeClockDS1307::decToBcd(byte b) 432{ 433 return ( ((b/10) << 4) + (b%10) ); 434} 435 436// Convert binary coded decimal to normal decimal numbers 437byte RealTimeClockDS1307::bcdToDec(byte b) 438{ 439 return ( ((b >> 4)*10) + (b%16) ); 440} 441 442char RealTimeClockDS1307::lowNybbleToASCII(byte b) 443{ 444 b = b & 0x0f; 445 if(b < 10) { 446 //0 is ASCII 48 447 return 48+b; 448 } 449 //A is ASCII 55 450 return 55+b; 451} 452char RealTimeClockDS1307::highNybbleToASCII(byte b) 453{ 454 return lowNybbleToASCII(b >> 4); 455} 456 457/***** INSTANCE *******/ 458 459RealTimeClockDS1307 RTC = RealTimeClockDS1307(); 460
RTClib.cpp
c_cpp
name it as above and add it to the RTClib library
1// Code by JeeLabs http://news.jeelabs.org/code/ 2// Released to the public domain! Enjoy! 3 4#include <Wire.h> 5#include "RTClib.h" 6#ifdef __AVR__ 7 #include <avr/pgmspace.h> 8#elif defined(ESP8266) 9 #include <pgmspace.h> 10#elif defined(ARDUINO_ARCH_SAMD) 11// nothing special needed 12#elif defined(ARDUINO_SAM_DUE) 13 #define PROGMEM 14 #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 15 #define Wire Wire1 16#endif 17 18 19 20#if (ARDUINO >= 100) 21 #include <Arduino.h> // capital A so it is error prone on case-sensitive filesystems 22 // Macro to deal with the difference in I2C write functions from old and new Arduino versions. 23 #define _I2C_WRITE write 24 #define _I2C_READ read 25#else 26 #include <WProgram.h> 27 #define _I2C_WRITE send 28 #define _I2C_READ receive 29#endif 30 31 32static uint8_t read_i2c_register(uint8_t addr, uint8_t reg) { 33 Wire.beginTransmission(addr); 34 Wire._I2C_WRITE((byte)reg); 35 Wire.endTransmission(); 36 37 Wire.requestFrom(addr, (byte)1); 38 return Wire._I2C_READ(); 39} 40 41static void write_i2c_register(uint8_t addr, uint8_t reg, uint8_t val) { 42 Wire.beginTransmission(addr); 43 Wire._I2C_WRITE((byte)reg); 44 Wire._I2C_WRITE((byte)val); 45 Wire.endTransmission(); 46} 47 48 49//////////////////////////////////////////////////////////////////////////////// 50// utility code, some of this could be exposed in the DateTime API if needed 51 52const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 53 54// number of days since 2000/01/01, valid for 2001..2099 55static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) { 56 if (y >= 2000) 57 y -= 2000; 58 uint16_t days = d; 59 for (uint8_t i = 1; i < m; ++i) 60 days += pgm_read_byte(daysInMonth + i - 1); 61 if (m > 2 && y % 4 == 0) 62 ++days; 63 return days + 365 * y + (y + 3) / 4 - 1; 64} 65 66static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) { 67 return ((days * 24L + h) * 60 + m) * 60 + s; 68} 69 70//////////////////////////////////////////////////////////////////////////////// 71// DateTime implementation - ignores time zones and DST changes 72// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second 73 74DateTime::DateTime (uint32_t t) { 75 t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 76 77 ss = t % 60; 78 t /= 60; 79 mm = t % 60; 80 t /= 60; 81 hh = t % 24; 82 uint16_t days = t / 24; 83 uint8_t leap; 84 for (yOff = 0; ; ++yOff) { 85 leap = yOff % 4 == 0; 86 if (days < 365 + leap) 87 break; 88 days -= 365 + leap; 89 } 90 for (m = 1; ; ++m) { 91 uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1); 92 if (leap && m == 2) 93 ++daysPerMonth; 94 if (days < daysPerMonth) 95 break; 96 days -= daysPerMonth; 97 } 98 d = days + 1; 99} 100 101DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) { 102 if (year >= 2000) 103 year -= 2000; 104 yOff = year; 105 m = month; 106 d = day; 107 hh = hour; 108 mm = min; 109 ss = sec; 110} 111 112DateTime::DateTime (const DateTime& copy): 113 yOff(copy.yOff), 114 m(copy.m), 115 d(copy.d), 116 hh(copy.hh), 117 mm(copy.mm), 118 ss(copy.ss) 119{} 120 121static uint8_t conv2d(const char* p) { 122 uint8_t v = 0; 123 if ('0' <= *p && *p <= '9') 124 v = *p - '0'; 125 return 10 * v + *++p - '0'; 126} 127 128// A convenient constructor for using "the compiler's time": 129// DateTime now (__DATE__, __TIME__); 130// NOTE: using F() would further reduce the RAM footprint, see below. 131DateTime::DateTime (const char* date, const char* time) { 132 // sample input: date = "Dec 26 2009", time = "12:34:56" 133 yOff = conv2d(date + 9); 134 // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 135 switch (date[0]) { 136 case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; 137 case 'F': m = 2; break; 138 case 'A': m = date[2] == 'r' ? 4 : 8; break; 139 case 'M': m = date[2] == 'r' ? 3 : 5; break; 140 case 'S': m = 9; break; 141 case 'O': m = 10; break; 142 case 'N': m = 11; break; 143 case 'D': m = 12; break; 144 } 145 d = conv2d(date + 4); 146 hh = conv2d(time); 147 mm = conv2d(time + 3); 148 ss = conv2d(time + 6); 149} 150 151// A convenient constructor for using "the compiler's time": 152// This version will save RAM by using PROGMEM to store it by using the F macro. 153// DateTime now (F(__DATE__), F(__TIME__)); 154DateTime::DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time) { 155 // sample input: date = "Dec 26 2009", time = "12:34:56" 156 char buff[11]; 157 memcpy_P(buff, date, 11); 158 yOff = conv2d(buff + 9); 159 // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 160 switch (buff[0]) { 161 case 'J': m = buff[1] == 'a' ? 1 : m = buff[2] == 'n' ? 6 : 7; break; 162 case 'F': m = 2; break; 163 case 'A': m = buff[2] == 'r' ? 4 : 8; break; 164 case 'M': m = buff[2] == 'r' ? 3 : 5; break; 165 case 'S': m = 9; break; 166 case 'O': m = 10; break; 167 case 'N': m = 11; break; 168 case 'D': m = 12; break; 169 } 170 d = conv2d(buff + 4); 171 memcpy_P(buff, time, 8); 172 hh = conv2d(buff); 173 mm = conv2d(buff + 3); 174 ss = conv2d(buff + 6); 175} 176 177uint8_t DateTime::dayOfTheWeek() const { 178 uint16_t day = date2days(yOff, m, d); 179 return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 180} 181 182uint32_t DateTime::unixtime(void) const { 183 uint32_t t; 184 uint16_t days = date2days(yOff, m, d); 185 t = time2long(days, hh, mm, ss); 186 t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 187 188 return t; 189} 190 191long DateTime::secondstime(void) const { 192 long t; 193 uint16_t days = date2days(yOff, m, d); 194 t = time2long(days, hh, mm, ss); 195 return t; 196} 197 198DateTime DateTime::operator+(const TimeSpan& span) { 199 return DateTime(unixtime()+span.totalseconds()); 200} 201 202DateTime DateTime::operator-(const TimeSpan& span) { 203 return DateTime(unixtime()-span.totalseconds()); 204} 205 206TimeSpan DateTime::operator-(const DateTime& right) { 207 return TimeSpan(unixtime()-right.unixtime()); 208} 209 210//////////////////////////////////////////////////////////////////////////////// 211// TimeSpan implementation 212 213TimeSpan::TimeSpan (int32_t seconds): 214 _seconds(seconds) 215{} 216 217TimeSpan::TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds): 218 _seconds((int32_t)days*86400L + (int32_t)hours*3600 + (int32_t)minutes*60 + seconds) 219{} 220 221TimeSpan::TimeSpan (const TimeSpan& copy): 222 _seconds(copy._seconds) 223{} 224 225TimeSpan TimeSpan::operator+(const TimeSpan& right) { 226 return TimeSpan(_seconds+right._seconds); 227} 228 229TimeSpan TimeSpan::operator-(const TimeSpan& right) { 230 return TimeSpan(_seconds-right._seconds); 231} 232 233//////////////////////////////////////////////////////////////////////////////// 234// RTC_DS1307 implementation 235 236static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } 237static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } 238 239boolean RTC_DS1307::begin(void) { 240 Wire.begin(); 241 return true; 242} 243 244uint8_t RTC_DS1307::isrunning(void) { 245 Wire.beginTransmission(DS1307_ADDRESS); 246 Wire._I2C_WRITE((byte)0); 247 Wire.endTransmission(); 248 249 Wire.requestFrom(DS1307_ADDRESS, 1); 250 uint8_t ss = Wire._I2C_READ(); 251 return !(ss>>7); 252} 253 254void RTC_DS1307::adjust(const DateTime& dt) { 255 Wire.beginTransmission(DS1307_ADDRESS); 256 Wire._I2C_WRITE((byte)0); // start at location 0 257 Wire._I2C_WRITE(bin2bcd(dt.second())); 258 Wire._I2C_WRITE(bin2bcd(dt.minute())); 259 Wire._I2C_WRITE(bin2bcd(dt.hour())); 260 Wire._I2C_WRITE(bin2bcd(0)); 261 Wire._I2C_WRITE(bin2bcd(dt.day())); 262 Wire._I2C_WRITE(bin2bcd(dt.month())); 263 Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); 264 Wire.endTransmission(); 265} 266 267DateTime RTC_DS1307::now() { 268 Wire.beginTransmission(DS1307_ADDRESS); 269 Wire._I2C_WRITE((byte)0); 270 Wire.endTransmission(); 271 272 Wire.requestFrom(DS1307_ADDRESS, 7); 273 uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F); 274 uint8_t mm = bcd2bin(Wire._I2C_READ()); 275 uint8_t hh = bcd2bin(Wire._I2C_READ()); 276 Wire._I2C_READ(); 277 uint8_t d = bcd2bin(Wire._I2C_READ()); 278 uint8_t m = bcd2bin(Wire._I2C_READ()); 279 uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000; 280 281 return DateTime (y, m, d, hh, mm, ss); 282} 283 284Ds1307SqwPinMode RTC_DS1307::readSqwPinMode() { 285 int mode; 286 287 Wire.beginTransmission(DS1307_ADDRESS); 288 Wire._I2C_WRITE(DS1307_CONTROL); 289 Wire.endTransmission(); 290 291 Wire.requestFrom((uint8_t)DS1307_ADDRESS, (uint8_t)1); 292 mode = Wire._I2C_READ(); 293 294 mode &= 0x93; 295 return static_cast<Ds1307SqwPinMode>(mode); 296} 297 298void RTC_DS1307::writeSqwPinMode(Ds1307SqwPinMode mode) { 299 Wire.beginTransmission(DS1307_ADDRESS); 300 Wire._I2C_WRITE(DS1307_CONTROL); 301 Wire._I2C_WRITE(mode); 302 Wire.endTransmission(); 303} 304 305void RTC_DS1307::readnvram(uint8_t* buf, uint8_t size, uint8_t address) { 306 int addrByte = DS1307_NVRAM + address; 307 Wire.beginTransmission(DS1307_ADDRESS); 308 Wire._I2C_WRITE(addrByte); 309 Wire.endTransmission(); 310 311 Wire.requestFrom((uint8_t) DS1307_ADDRESS, size); 312 for (uint8_t pos = 0; pos < size; ++pos) { 313 buf[pos] = Wire._I2C_READ(); 314 } 315} 316 317void RTC_DS1307::writenvram(uint8_t address, uint8_t* buf, uint8_t size) { 318 int addrByte = DS1307_NVRAM + address; 319 Wire.beginTransmission(DS1307_ADDRESS); 320 Wire._I2C_WRITE(addrByte); 321 for (uint8_t pos = 0; pos < size; ++pos) { 322 Wire._I2C_WRITE(buf[pos]); 323 } 324 Wire.endTransmission(); 325} 326 327uint8_t RTC_DS1307::readnvram(uint8_t address) { 328 uint8_t data; 329 readnvram(&data, 1, address); 330 return data; 331} 332 333void RTC_DS1307::writenvram(uint8_t address, uint8_t data) { 334 writenvram(address, &data, 1); 335} 336 337//////////////////////////////////////////////////////////////////////////////// 338// RTC_Millis implementation 339 340long RTC_Millis::offset = 0; 341 342void RTC_Millis::adjust(const DateTime& dt) { 343 offset = dt.unixtime() - millis() / 1000; 344} 345 346DateTime RTC_Millis::now() { 347 return (uint32_t)(offset + millis() / 1000); 348} 349 350//////////////////////////////////////////////////////////////////////////////// 351 352//////////////////////////////////////////////////////////////////////////////// 353// RTC_PCF8563 implementation 354 355boolean RTC_PCF8523::begin(void) { 356 Wire.begin(); 357 return true; 358} 359 360boolean RTC_PCF8523::initialized(void) { 361 Wire.beginTransmission(PCF8523_ADDRESS); 362 Wire._I2C_WRITE((byte)PCF8523_CONTROL_3); 363 Wire.endTransmission(); 364 365 Wire.requestFrom(PCF8523_ADDRESS, 1); 366 uint8_t ss = Wire._I2C_READ(); 367 return ((ss & 0xE0) != 0xE0); 368} 369 370void RTC_PCF8523::adjust(const DateTime& dt) { 371 Wire.beginTransmission(PCF8523_ADDRESS); 372 Wire._I2C_WRITE((byte)3); // start at location 3 373 Wire._I2C_WRITE(bin2bcd(dt.second())); 374 Wire._I2C_WRITE(bin2bcd(dt.minute())); 375 Wire._I2C_WRITE(bin2bcd(dt.hour())); 376 Wire._I2C_WRITE(bin2bcd(dt.day())); 377 Wire._I2C_WRITE(bin2bcd(0)); // skip weekdays 378 Wire._I2C_WRITE(bin2bcd(dt.month())); 379 Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); 380 Wire.endTransmission(); 381 382 // set to battery switchover mode 383 Wire.beginTransmission(PCF8523_ADDRESS); 384 Wire._I2C_WRITE((byte)PCF8523_CONTROL_3); 385 Wire._I2C_WRITE((byte)0x00); 386 Wire.endTransmission(); 387} 388 389DateTime RTC_PCF8523::now() { 390 Wire.beginTransmission(PCF8523_ADDRESS); 391 Wire._I2C_WRITE((byte)3); 392 Wire.endTransmission(); 393 394 Wire.requestFrom(PCF8523_ADDRESS, 7); 395 uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F); 396 uint8_t mm = bcd2bin(Wire._I2C_READ()); 397 uint8_t hh = bcd2bin(Wire._I2C_READ()); 398 uint8_t d = bcd2bin(Wire._I2C_READ()); 399 Wire._I2C_READ(); // skip 'weekdays' 400 uint8_t m = bcd2bin(Wire._I2C_READ()); 401 uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000; 402 403 return DateTime (y, m, d, hh, mm, ss); 404} 405 406Pcf8523SqwPinMode RTC_PCF8523::readSqwPinMode() { 407 int mode; 408 409 Wire.beginTransmission(PCF8523_ADDRESS); 410 Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL); 411 Wire.endTransmission(); 412 413 Wire.requestFrom((uint8_t)PCF8523_ADDRESS, (uint8_t)1); 414 mode = Wire._I2C_READ(); 415 416 mode >>= 3; 417 mode &= 0x7; 418 return static_cast<Pcf8523SqwPinMode>(mode); 419} 420 421void RTC_PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) { 422 Wire.beginTransmission(PCF8523_ADDRESS); 423 Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL); 424 Wire._I2C_WRITE(mode << 3); 425 Wire.endTransmission(); 426} 427 428 429 430 431//////////////////////////////////////////////////////////////////////////////// 432// RTC_DS3231 implementation 433 434boolean RTC_DS3231::begin(void) { 435 Wire.begin(); 436 return true; 437} 438 439bool RTC_DS3231::lostPower(void) { 440 return (read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG) >> 7); 441} 442 443void RTC_DS3231::adjust(const DateTime& dt) { 444 Wire.beginTransmission(DS3231_ADDRESS); 445 Wire._I2C_WRITE((byte)0); // start at location 0 446 Wire._I2C_WRITE(bin2bcd(dt.second())); 447 Wire._I2C_WRITE(bin2bcd(dt.minute())); 448 Wire._I2C_WRITE(bin2bcd(dt.hour())); 449 Wire._I2C_WRITE(bin2bcd(0)); 450 Wire._I2C_WRITE(bin2bcd(dt.day())); 451 Wire._I2C_WRITE(bin2bcd(dt.month())); 452 Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); 453 Wire.endTransmission(); 454 455 uint8_t statreg = read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG); 456 statreg &= ~0x80; // flip OSF bit 457 write_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG, statreg); 458} 459 460DateTime RTC_DS3231::now() { 461 Wire.beginTransmission(DS3231_ADDRESS); 462 Wire._I2C_WRITE((byte)0); 463 Wire.endTransmission(); 464 465 Wire.requestFrom(DS3231_ADDRESS, 7); 466 uint8_t ss = bcd2bin(Wire._I2C_READ() & 0x7F); 467 uint8_t mm = bcd2bin(Wire._I2C_READ()); 468 uint8_t hh = bcd2bin(Wire._I2C_READ()); 469 Wire._I2C_READ(); 470 uint8_t d = bcd2bin(Wire._I2C_READ()); 471 uint8_t m = bcd2bin(Wire._I2C_READ()); 472 uint16_t y = bcd2bin(Wire._I2C_READ()) + 2000; 473 474 return DateTime (y, m, d, hh, mm, ss); 475} 476 477Ds3231SqwPinMode RTC_DS3231::readSqwPinMode() { 478 int mode; 479 480 Wire.beginTransmission(DS3231_ADDRESS); 481 Wire._I2C_WRITE(DS3231_CONTROL); 482 Wire.endTransmission(); 483 484 Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1); 485 mode = Wire._I2C_READ(); 486 487 mode &= 0x93; 488 return static_cast<Ds3231SqwPinMode>(mode); 489} 490 491void RTC_DS3231::writeSqwPinMode(Ds3231SqwPinMode mode) { 492 uint8_t ctrl; 493 ctrl = read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL); 494 495 ctrl &= ~0x04; // turn off INTCON 496 ctrl &= ~0x18; // set freq bits to 0 497 498 if (mode == DS3231_OFF) { 499 ctrl |= 0x04; // turn on INTCN 500 } else { 501 ctrl |= mode; 502 } 503 write_i2c_register(DS3231_ADDRESS, DS3231_CONTROL, ctrl); 504 505 //Serial.println( read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL), HEX); 506} 507
Set the time
arduino
since the ds1307 is susceptible to drift away from the correct time. This program allows you to set the time through the Serial Monitor. When you see that the time is not correct simply plugin the rtc module into the arduino and upload this program. Then enter the Serial Monitor and then set the correct date, month, year, time. Then simply upload the other program and the correct time will be displayed on the 7 segment display.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 Much thanks to John Waters and Maurice Ribble for their 6 earlier and very helpful work (even if I didn't wind up 7 using any of their code): 8 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 9 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 10 11 This library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Lesser General Public 13 License as published by the Free Software Foundation; either 14 version 2.1 of the License, or (at your option) any later version. 15 16 This library is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Lesser General Public License for more details. 20 21 You should have received a copy of the GNU Lesser General Public 22 License along with this library; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24*/ 25 26 27#include <Wire.h> 28#include <RealTimeClockDS1307.h> 29 30//RealTimeClock RTC;//=new RealTimeClock(); 31 32#define Display_Clock_Every_N_Seconds 1 33#define Display_ShortHelp_Every_N_Seconds 25 34//#define TEST_Squarewave 35//#define TEST_StopStart 36//#define TEST_1224Switch 37 38int count=0; 39char formatted[] = "00-00-00 00:00:00x"; 40 41void setup() { 42// Wire.begin(); 43 Serial.begin(9600); 44} 45 46void loop() { 47 if(Serial.available()) 48 { 49 processCommand(); 50 } 51 delay(1000); 52 RTC.readClock(); 53 count++; 54 if(count % Display_Clock_Every_N_Seconds == 0){ 55 Serial.print(count); 56 Serial.print(": "); 57 RTC.getFormatted(formatted); 58 Serial.print(formatted); 59 Serial.println(); 60 } 61 62 if(count % Display_ShortHelp_Every_N_Seconds == 0) { 63 Serial.println("Send ? for a list of commands."); 64 } 65#ifdef TEST_Squarewave 66if(count%10 == 0) 67{ 68 switch(count/10 % 6) 69 { 70 case 0: 71 Serial.print("Squarewave disabled (low impedance): "); 72 RTC.sqwDisable(0); 73 Serial.println((int) RTC.readData(7)); 74 break; 75 case 1: 76 Serial.print("Squarewave disabled (high impedance): "); 77 RTC.sqwDisable(1); 78 Serial.println((int) RTC.readData(7)); 79 break; 80 case 2: 81 Serial.println("Squarewave enabled at 1 Hz"); 82 RTC.sqwEnable(RTC.SQW_1Hz); 83 break; 84 case 3: 85 Serial.println("Squarewave enabled at 4.096 kHz"); 86 RTC.sqwEnable(RTC.SQW_4kHz); 87 break; 88 case 4: 89 Serial.println("Squarewave enabled at 8.192 kHz"); 90 RTC.sqwEnable(RTC.SQW_8kHz); 91 break; 92 case 5: 93 Serial.println("Squarewave enabled at 32.768 kHz"); 94 RTC.sqwEnable(RTC.SQW_32kHz); 95 break; 96 default: 97 Serial.println("Squarewave test not defined"); 98 }//switch 99} 100#endif 101 102#ifdef TEST_StopStart 103if(count%10 == 0) 104{ 105 if(!RTC.isStopped()) 106 { 107 if(RTC.getSeconds() < 45) 108 { 109 Serial.println("Stopping clock for 10 seconds"); 110 RTC.stop(); 111 }//if we have enough time 112 } else { 113 RTC.setSeconds(RTC.getSeconds()+11); 114 RTC.start(); 115 Serial.println("Adding 11 seconds and restarting clock"); 116 } 117}//if on a multiple of 10 counts 118#endif 119 120#ifdef TEST_1224Switch 121 if(count%10 == 0) 122 { 123 if(count %20 == 0) 124 { 125 Serial.println("switching to 12-hour time"); 126 RTC.switchTo12h(); 127 RTC.setClock(); 128 } 129 else 130 { 131 Serial.println("switching to 24-hour time"); 132 RTC.switchTo24h(); 133 RTC.setClock(); 134 } 135 } 136#endif 137} 138 139void processCommand() { 140 if(!Serial.available()) { return; } 141 char command = Serial.read(); 142 int in,in2; 143 switch(command) 144 { 145 case 'H': 146 case 'h': 147 in=SerialReadPosInt(); 148 RTC.setHours(in); 149 RTC.setClock(); 150 Serial.print("Setting hours to "); 151 Serial.println(in); 152 break; 153 case 'I': 154 case 'i': 155 in=SerialReadPosInt(); 156 RTC.setMinutes(in); 157 RTC.setClock(); 158 Serial.print("Setting minutes to "); 159 Serial.println(in); 160 break; 161 case 'S': 162 case 's': 163 in=SerialReadPosInt(); 164 RTC.setSeconds(in); 165 RTC.setClock(); 166 Serial.print("Setting seconds to "); 167 Serial.println(in); 168 break; 169 case 'Y': 170 case 'y': 171 in=SerialReadPosInt(); 172 RTC.setYear(in); 173 RTC.setClock(); 174 Serial.print("Setting year to "); 175 Serial.println(in); 176 break; 177 case 'M': 178 case 'm': 179 in=SerialReadPosInt(); 180 RTC.setMonth(in); 181 RTC.setClock(); 182 Serial.print("Setting month to "); 183 Serial.println(in); 184 break; 185 case 'D': 186 case 'd': 187 in=SerialReadPosInt(); 188 RTC.setDate(in); 189 RTC.setClock(); 190 Serial.print("Setting date to "); 191 Serial.println(in); 192 break; 193 case 'W': 194 Serial.print("Day of week is "); 195 Serial.println((int) RTC.getDayOfWeek()); 196 break; 197 case 'w': 198 in=SerialReadPosInt(); 199 RTC.setDayOfWeek(in); 200 RTC.setClock(); 201 Serial.print("Setting day of week to "); 202 Serial.println(in); 203 break; 204 205 case 't': 206 case 'T': 207 if(RTC.is12hour()) { 208 RTC.switchTo24h(); 209 Serial.println("Switching to 24-hour clock."); 210 } else { 211 RTC.switchTo12h(); 212 Serial.println("Switching to 12-hour clock."); 213 } 214 RTC.setClock(); 215 break; 216 217 case 'A': 218 case 'a': 219 if(RTC.is12hour()) { 220 RTC.setAM(); 221 RTC.setClock(); 222 Serial.println("Set AM."); 223 } else { 224 Serial.println("(Set hours only in 24-hour mode.)"); 225 } 226 break; 227 228 case 'P': 229 case 'p': 230 if(RTC.is12hour()) { 231 RTC.setPM(); 232 RTC.setClock(); 233 Serial.println("Set PM."); 234 } else { 235 Serial.println("(Set hours only in 24-hour mode.)"); 236 } 237 break; 238 239 case 'q': 240 RTC.sqwEnable(RTC.SQW_1Hz); 241 Serial.println("Square wave output set to 1Hz"); 242 break; 243 case 'Q': 244 RTC.sqwDisable(0); 245 Serial.println("Square wave output disabled (low)"); 246 break; 247 248 case 'z': 249 RTC.start(); 250 Serial.println("Clock oscillator started."); 251 break; 252 case 'Z': 253 RTC.stop(); 254 Serial.println("Clock oscillator stopped."); 255 break; 256 257 case '>': 258 in=SerialReadPosInt(); 259 in2=SerialReadPosInt(); 260 RTC.writeData(in, in2); 261 Serial.print("Write to register "); 262 Serial.print(in); 263 Serial.print(" the value "); 264 Serial.println(in2); 265 break; 266 case '<': 267 in=SerialReadPosInt(); 268 in2=RTC.readData(in); 269 Serial.print("Read from register "); 270 Serial.print(in); 271 Serial.print(" the value "); 272 Serial.println(in2); 273 break; 274 275 default: 276 Serial.println("Unknown command. Try these:"); 277 Serial.println(" h## - set Hours d## - set Date"); 278 Serial.println(" i## - set mInutes m## - set Month"); 279 Serial.println(" s## - set Seconds y## - set Year"); 280 Serial.println(" w## - set arbitrary day of Week"); 281 Serial.println(" t - toggle 24-hour mode"); 282 Serial.println(" a - set AM p - set PM"); 283 Serial.println(); 284 Serial.println(" z - start clock Z - stop clock"); 285 Serial.println(" q - SQW/OUT = 1Hz Q - stop SQW/OUT"); 286 Serial.println(); 287 Serial.println(" >##,### - write to register ## the value ###"); 288 Serial.println(" <## - read the value in register ##"); 289 290 }//switch on command 291 292} 293 294//read in numeric characters until something else 295//or no more data is available on serial. 296int SerialReadPosInt() { 297 int i = 0; 298 boolean done=false; 299 while(Serial.available() && !done) 300 { 301 char c = Serial.read(); 302 if (c >= '0' && c <='9') 303 { 304 i = i * 10 + (c-'0'); 305 } 306 else 307 { 308 done = true; 309 } 310 } 311 return i; 312}
RealTimeClockDS1307.h
c_cpp
This is the main header file of the real time clock. Copy this also into the folder you previously created named "RealTimeClockDS1307". Now you have all the files for the Real Time Clock. Enter the arduino ide and under the 'Sketch' menu click on the 'include library' option and then search your folder under the 'Add .ZIP Library". This will do the trick and you will now be able to set the time in the RTC module.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 v0.92 Updated for Arduino 1.00; not re-tested on earlier versions 6 7 Much thanks to John Waters and Maurice Ribble for their 8 earlier and very helpful work (even if I didn't wind up 9 using any of their code): 10 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 11 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*/ 27 28#ifndef RealTimeClockDS1307_h 29#define RealTimeClockDS1307_h 30 31 #if defined(ARDUINO) && ARDUINO >= 100 32 #include "Arduino.h" 33 #else 34 #include "WProgram.h" 35 #endif 36 37//#include <HardwareSerial.h> 38//#include <WConstants.h> //need/want 'boolean' and 'byte' types used by Arduino 39//#undef round is required to avoid a compile-time 40//"expected unqualified-id before 'double'" error in math.h 41//see: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247924528/3 42#undef round 43#include <Wire.h> 44 45#define ARDUINO_PIN_T uint8_t 46 47class RealTimeClockDS1307 48{ 49 private: 50 byte _reg0_sec; 51 byte _reg1_min; 52 byte _reg2_hour; 53 byte _reg3_day; 54 byte _reg4_date; 55 byte _reg5_month; 56 byte _reg6_year; 57 byte _reg7_sqw; 58 byte decToBcd(byte); 59 byte bcdToDec(byte); 60 char lowNybbleToASCII(byte); 61 char highNybbleToASCII(byte); 62 public: 63 RealTimeClockDS1307(); 64 void readClock();//read registers (incl sqw) to local store 65 void setClock();//update clock registers from local store 66 void stop();//immediate; does not require setClock(); 67 void start();//immediate; does not require setClock(); 68 void sqwEnable(byte);//enable the square wave with the specified frequency 69 void sqwDisable(boolean);//disable the square wave, setting output either high or low 70 void writeData(byte, byte);//write a single value to a register 71 void writeData(byte, void *, int);//write several values consecutively 72 byte readData(byte);//read a single value from a register 73 void readData(byte, void *, int);//read several values into a buffer 74 75 int getHours(); 76 int getMinutes(); 77 int getSeconds(); 78 int getYear(); 79 int getMonth(); 80 int getDate(); 81 int getDay(); 82 int getDayOfWeek(); 83 boolean is12hour(); 84 boolean isPM(); 85 boolean isStopped(); 86 //getFormatted writes into a char array provided by you. Format is: 87 // YY-MM-DD HH:II:SS ... plus "A" or "P" if in 12-hour mode 88 //and of course a NULL terminator. So, [18] for 24h or [19] for 12h 89 void getFormatted(char *);//see comment above 90 void getFormatted2k(char *);//as getFormatted, but with "20" prepended 91 92 //must also call setClock() after any of these 93 //before next readClock(). Note that invalid dates are not 94 //corrected by the clock. All the clock knows is when it should 95 //roll over to the next month rather than the next date in the same month. 96 void setSeconds(int); 97 void setMinutes(int); 98 //setHours rejects values out of range for the current 12/24 mode 99 void setHours(int); 100 void setAM();//does not consider hours; see switchTo24() 101 void setPM();//does not consider hours; see switchTo24() 102 void set24h();//does not consider hours; see switchTo24() 103 void switchTo24h();//returns immediately if already 24h 104 void switchTo12h();//returns immediately if already 12h 105 void setDayOfWeek(int);//incremented at midnight; not set by date (no fixed meaning) 106 void setDate(int);//allows 1-31 for *all* months. 107 void setDay(int); 108 void setMonth(int); 109 void setYear(int); 110 111 //squarewave frequencies: 112 static const byte SQW_1Hz=0x00; 113 static const byte SQW_4kHz=0x01;//actually 4.096kHz 114 static const byte SQW_8kHz=0x02;//actually 8.192kHz 115 static const byte SQW_32kHz=0x03;//actually 32.768kHz 116}; 117 118extern RealTimeClockDS1307 RTC; 119 120#endif 121
RTClib files
csharp
create a folder named 'RTClib' and add the following files into it
1######################################### 2# Syntax Coloring Map RealTimeClockDS1307 3######################################### 4 5 6####################################### 7# Instances (KEYWORD2) 8####################################### 9RTC KEYWORD2 10 11######################################### 12# Methods and Functions (KEYWORD2) 13######################################### 14readClock KEYWORD2 15setClock KEYWORD2 16stop KEYWORD2 17start KEYWORD2 18sqwEnable KEYWORD2 19sqwDisable KEYWORD2 20writeData KEYWORD2 21readData KEYWORD2 22 23getHours KEYWORD2 24getMinutes KEYWORD2 25getSeconds KEYWORD2 26getYear KEYWORD2 27getMonth KEYWORD2 28getDate KEYWORD2 29getDay KEYWORD2 30getDayOfWeek KEYWORD2 31is12hour KEYWORD2 32isPM KEYWORD2 33isStopped KEYWORD2 34getFormatted KEYWORD2 35getFormatted2k KEYWORD2 36 37setSeconds KEYWORD2 38setMinutes KEYWORD2 39setHours KEYWORD2 40setAM KEYWORD2 41setPM KEYWORD2 42set24h KEYWORD2 43switchTo24h KEYWORD2 44switchTo12h KEYWORD2 45setDayOfWeek KEYWORD2 46setDate KEYWORD2 47setDay KEYWORD2 48setMonth KEYWORD2 49setYear KEYWORD2 50 51######################################### 52# Constants (LITERAL1) 53######################################### 54SQW_1Hz LITERAL1 55SQW_4kHz LITERAL1 56SQW_8kHz LITERAL1 57SQW_32kHz LITERAL1 58
RTClib
c_cpp
add this to the RTClib folder
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 Copyright (c) 2011 David H. Brown. All rights reserved 4 5 v0.92 Updated for Arduino 1.00; not re-tested on earlier versions 6 7 Much thanks to John Waters and Maurice Ribble for their 8 earlier and very helpful work (even if I didn't wind up 9 using any of their code): 10 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 11 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*/ 27 28/****************************************************************************** 29 * Includes 30 ******************************************************************************/ 31 32#include "RealTimeClockDS1307.h" 33#include <Wire.h> 34 35/****************************************************************************** 36 * Definitions 37 ******************************************************************************/ 38 39#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address 40 41/****************************************************************************** 42 * Constructors 43 ******************************************************************************/ 44 45RealTimeClockDS1307::RealTimeClockDS1307() 46{ 47 Wire.begin(); 48 //must NOT attempt to read the clock before 49 //Wire.begin() has not been called; readClock() will hang. 50 //Fortunately, it seems that you can call Wire.begin() 51 //multiple times with no adverse effect). 52} 53 54/****************************************************************************** 55 * User API 56 ******************************************************************************/ 57 58/***** CHIP READ/WRITE ******/ 59 60void RealTimeClockDS1307::readClock() 61{ 62 // Reset the register pointer 63 Wire.beginTransmission(DS1307_I2C_ADDRESS); 64 Wire.write((uint8_t) 0x00); 65 Wire.endTransmission(); 66 67 Wire.requestFrom(DS1307_I2C_ADDRESS, 8); 68 _reg0_sec = Wire.read(); 69 _reg1_min = Wire.read(); 70 _reg2_hour = Wire.read(); 71 _reg3_day = Wire.read(); 72 _reg4_date = Wire.read(); 73 _reg5_month = Wire.read(); 74 _reg6_year = Wire.read(); 75 _reg7_sqw = Wire.read(); 76} 77 78void RealTimeClockDS1307::setClock() 79{ 80 //to be paranoid, we're going to first stop the clock 81 //to ensure we don't have rollovers while we're 82 //writing: 83 writeData(0,0x80); 84 //now, we'll write everything *except* the second 85 Wire.beginTransmission(DS1307_I2C_ADDRESS); 86 Wire.write((uint8_t) 0x01); 87 Wire.write(_reg1_min); 88 Wire.write(_reg2_hour); 89 Wire.write(_reg3_day); 90 Wire.write(_reg4_date); 91 Wire.write(_reg5_month); 92 Wire.write(_reg6_year); 93 Wire.endTransmission(); 94 //now, we'll write the seconds; we didn't have to keep 95 //track of whether the clock was already running, because 96 //_reg0_sec already knows what we want it to be. This 97 //will restart the clock as it writes the new seconds value. 98 writeData(0,_reg0_sec); 99} 100 101void RealTimeClockDS1307::stop() 102{ 103 //"Bit 7 of register 0 is the clock halt (CH) bit. 104 //When this bit is set to a 1, the oscillator is disabled." 105 _reg0_sec = _reg0_sec | 0x80; 106 writeData(0,_reg0_sec); 107} 108void RealTimeClockDS1307::start() 109{ 110 //"Bit 7 of register 0 is the clock halt (CH) bit. 111 //When this bit is set to a 1, the oscillator is disabled." 112 _reg0_sec = _reg0_sec & ~0x80; 113 writeData(0,_reg0_sec); 114} 115 116void RealTimeClockDS1307::writeData(byte regNo, byte value) 117{ 118 if(regNo > 0x3F) { return; } 119 Wire.beginTransmission(DS1307_I2C_ADDRESS); 120 Wire.write(regNo); 121 Wire.write(value); 122 Wire.endTransmission(); 123} 124 125void RealTimeClockDS1307::writeData(byte regNo, void * source, int length) 126{ 127 char * p = (char*) source; 128 if(regNo > 0x3F || length > 0x3F) { return; } 129 Wire.beginTransmission(DS1307_I2C_ADDRESS); 130 Wire.write(regNo); 131 for(int i=0; i<length; i++) { 132 Wire.write(*p); 133 p++; 134 } 135 Wire.endTransmission(); 136} 137 138byte RealTimeClockDS1307::readData(byte regNo) 139{ 140 if(regNo > 0x3F) { return 0xff; } 141 Wire.beginTransmission(DS1307_I2C_ADDRESS); 142 Wire.write(regNo); 143 Wire.endTransmission(); 144 Wire.requestFrom(DS1307_I2C_ADDRESS, 1); 145 return Wire.read(); 146} 147 148void RealTimeClockDS1307::readData(byte regNo, void * dest, int length) 149{ 150 char * p = (char*) dest; 151 if(regNo > 0x3F || length > 0x3F) { return; } 152 Wire.beginTransmission(DS1307_I2C_ADDRESS); 153 Wire.write(regNo); 154 Wire.endTransmission(); 155 Wire.requestFrom(DS1307_I2C_ADDRESS, length); 156 for(int i=0; i<length; i++) { 157 *p=Wire.read(); 158 p++; 159 } 160} 161 162 163void RealTimeClockDS1307::sqwEnable(byte frequency) 164{ 165 if(frequency > 3) { return; } 166 //bit 4 is enable (0x10); 167 //bit 7 is current output state if disabled 168 _reg7_sqw = _reg7_sqw & 0x80 | 0x10 | frequency; 169 writeData(0x07, _reg7_sqw); 170} 171 172void RealTimeClockDS1307::sqwDisable(boolean outputLevel) 173{ 174 //bit 7 0x80 output + bit 4 0x10 enable both to zero, 175 //the OR with the boolean shifted up to bit 7 176 _reg7_sqw = _reg7_sqw & ~0x90 | (outputLevel << 7); 177 writeData(0x07, _reg7_sqw); 178 //note: per the data sheet, "OUT (Output control): This bit controls 179 //the output level of the SQW/OUT pin when the square wave 180 //output is disabled. If SQWE = 0, the logic level on the 181 //SQW/OUT pin is 1 if OUT = 1 and is 0 if OUT = 0." 182 //"The SQW/OUT pin is open drain and requires an external 183 //pull-up resistor." 184 //It is worth mentioning that on the Sparkfun breakout board, 185 //BOB-00099, a LED connected to the SQW pin through a resistor to 186 //Vcc+5V illuminated when OUT=0 and was dark when OUT=1, the 187 //opposite of what I expected until I remembered that it is 188 //an open drain (google it if you need to). Basically, they don't 189 //so much mean a logic level (e.g., +3.3V rel Gnd) as they mean 190 //high or low *impeadance* to ground (drain). So High is basically 191 //an open switch. Low connects to ground. 192} 193 194 195/***** GETTERS ******/ 196 197boolean RealTimeClockDS1307::is12hour() 198{ 199 //12-hour mode has bit 6 of the hour register set high 200 return ((_reg2_hour & 0x40) == 0x40); 201} 202boolean RealTimeClockDS1307::isPM() 203{ 204 //if in 12-hour mode, but 5 of the hour register indicates PM 205 if(is12hour()) { 206 return ((_reg2_hour & 0x20) == 0x20); 207 } 208 //otherwise, let's consider any time with the hour >11 to be PM: 209 return (getHours() > 11); 210} 211boolean RealTimeClockDS1307::isStopped() 212{ 213 //bit 7 of the seconds register stopps the clock when high 214 return ((_reg0_sec & 0x80) == 0x80); 215} 216 217int RealTimeClockDS1307::getHours() 218{ 219 if(is12hour()) { 220 //do not include bit 5, the am/pm indicator 221 return bcdToDec(_reg2_hour & 0x1f); 222 } 223 //bits 4-5 are tens of hours 224 return bcdToDec(_reg2_hour & 0x3f); 225} 226int RealTimeClockDS1307::getMinutes() 227{ 228 //could mask with 0x7f but shouldn't need to 229 return bcdToDec(_reg1_min); 230} 231int RealTimeClockDS1307::getSeconds() 232{ 233 //need to mask oscillator start/stop bit 7 234 return bcdToDec(_reg0_sec & 0x7f); 235} 236int RealTimeClockDS1307::getYear() 237{ 238 return bcdToDec(_reg6_year); 239} 240int RealTimeClockDS1307::getMonth() 241{ 242 //could mask with 0x1f but shouldn't need to 243 return bcdToDec(_reg5_month); 244} 245int RealTimeClockDS1307::getDate() 246{ 247 //could mask with 0x3f but shouldn't need to 248 return bcdToDec(_reg4_date); 249} 250int RealTimeClockDS1307::getDay() 251{ 252 return getDate(); 253} 254int RealTimeClockDS1307::getDayOfWeek() 255{ 256 //could mask with 0x07 but shouldn't need to 257 return bcdToDec(_reg3_day); 258} 259 260void RealTimeClockDS1307::getFormatted(char * buffer) 261{ 262 int i=0; 263 //target string format: YY-MM-DD HH:II:SS 264 buffer[i++]=highNybbleToASCII(_reg6_year); 265 buffer[i++]=lowNybbleToASCII(_reg6_year); 266 buffer[i++]='-'; 267 buffer[i++]=highNybbleToASCII(_reg5_month & 0x1f); 268 buffer[i++]=lowNybbleToASCII(_reg5_month); 269 buffer[i++]='-'; 270 buffer[i++]=highNybbleToASCII(_reg4_date & 0x3f); 271 buffer[i++]=lowNybbleToASCII(_reg4_date); 272 buffer[i++]=' '; 273 if(is12hour()) { 274 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x1f); 275 } else { 276 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x3f); 277 } 278 buffer[i++]=lowNybbleToASCII(_reg2_hour); 279 buffer[i++]=':'; 280 buffer[i++]=highNybbleToASCII(_reg1_min & 0x7f); 281 buffer[i++]=lowNybbleToASCII(_reg1_min); 282 buffer[i++]=':'; 283 buffer[i++]=highNybbleToASCII(_reg0_sec & 0x7f); 284 buffer[i++]=lowNybbleToASCII(_reg0_sec); 285 if(is12hour()) { 286 if(isPM()) { 287 buffer[i++]='P'; 288 } else { 289 buffer[i++]='A'; 290 } 291 } 292 buffer[i++]=0x00; 293} 294 295void RealTimeClockDS1307::getFormatted2k(char * buffer) 296{ 297 buffer[0]='2'; 298 buffer[1]='0'; 299 getFormatted(&buffer[2]); 300} 301 302/**** SETTERS *****/ 303 304void RealTimeClockDS1307::setSeconds(int s) 305{ 306 if (s < 60 && s >=0) 307 { 308 //need to preserve oscillator bit 309 _reg0_sec = decToBcd(s) | (_reg0_sec & 0x80); 310 } 311} 312void RealTimeClockDS1307::setMinutes(int m) 313{ 314 if (m < 60 && m >=0) 315 { 316 _reg1_min = decToBcd(m); 317 } 318} 319void RealTimeClockDS1307::setHours(int h) 320{ 321 if (is12hour()) 322 { 323 if (h >= 1 && h <=12) 324 { 325 //preserve 12/24 and AM/PM bits 326 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x60); 327 } 328 } else { 329 if (h >= 0 && h <=24) 330 { 331 //preserve 12/24 bit 332 _reg2_hour = decToBcd(h) | (_reg2_hour & 0x40); 333 } 334 }//else 335}//setHours 336 337void RealTimeClockDS1307::set24h() 338{ 339 //"Bit 6 of the hours register is defined as the 340 //"12- or 24-hour mode select bit. 341 //"When high, the 12-hour mode is selected" 342 //So, mask the curent value with the complement turn off that bit: 343 _reg2_hour = _reg2_hour & ~0x40; 344} 345void RealTimeClockDS1307::setAM() 346{ 347 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 348 //so we need to OR with 0x40 to set 12-hour mode and also 349 //turn off the PM bit by masking with the complement 350 _reg2_hour = _reg2_hour & ~0x20 | 0x40; 351} 352void RealTimeClockDS1307::setPM() 353{ 354 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 355 //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also 356 //turn on the PM bit: 357 _reg2_hour = _reg2_hour | 0x60; 358} 359 360void RealTimeClockDS1307::switchTo12h() 361{ 362 if(is12hour()) { return; } 363 int h = getHours(); 364 if (h < 12) { 365 setAM(); 366 } else { 367 h = h-12; 368 setPM(); 369 } 370 if (h==0) 371 { 372 h=12; 373 } 374 setHours(h); 375} 376void RealTimeClockDS1307::switchTo24h() 377{ 378 if(!is12hour()) { return ; } 379 int h = getHours(); 380 if(h==12) {//12 PM is just 12; 12 AM is 0 hours. 381 h = 0; 382 } 383 if (isPM()) 384 {//if it was 12 PM, then h=0 above and so we're back to 12: 385 h = h+12; 386 } 387 set24h(); 388 setHours(h); 389} 390 391void RealTimeClockDS1307::setDayOfWeek(int d) 392{ 393 if (d > 0 && d < 8) 394 { 395 _reg3_day = decToBcd(d); 396 } 397} 398 399void RealTimeClockDS1307::setDate(int d) 400{ 401 if (d > 0 && d < 32) 402 { 403 _reg4_date = decToBcd(d); 404 } 405} 406void RealTimeClockDS1307::setDay(int d) 407{ 408 setDate(d); 409} 410 411void RealTimeClockDS1307::setMonth(int m) 412{ 413 if (m > 0 && m < 13) 414 { 415 _reg5_month = decToBcd(m); 416 } 417} 418void RealTimeClockDS1307::setYear(int y) 419{ 420 if (y >= 0 && y <100) 421 { 422 _reg6_year = decToBcd(y); 423 } 424} 425 426 427 428/***************************************** 429 * Private methods 430 *****************************************/ 431byte RealTimeClockDS1307::decToBcd(byte b) 432{ 433 return ( ((b/10) << 4) + (b%10) ); 434} 435 436// Convert binary coded decimal to normal decimal numbers 437byte RealTimeClockDS1307::bcdToDec(byte b) 438{ 439 return ( ((b >> 4)*10) + (b%16) ); 440} 441 442char RealTimeClockDS1307::lowNybbleToASCII(byte b) 443{ 444 b = b & 0x0f; 445 if(b < 10) { 446 //0 is ASCII 48 447 return 48+b; 448 } 449 //A is ASCII 55 450 return 55+b; 451} 452char RealTimeClockDS1307::highNybbleToASCII(byte b) 453{ 454 return lowNybbleToASCII(b >> 4); 455} 456 457/***** INSTANCE *******/ 458 459RealTimeClockDS1307 RTC = RealTimeClockDS1307(); 460
library.properties(name)
c_cpp
add this to the RTClib folder
1My goal in creating yet another DS1307 library was to provide 2easy access to some of the other functions I needed from the chip, 3specifically its square wave output and its battery-backed RAM. 4 5## Documentation 6@todo Mostly comments in `RealTimeClockDS1307.h` 7 8## Examples (in /examples folder) 9 10- `RealTimeClockDS1307_Test.pde` allow you to turn the clock on/off, 11set date/time, set 12/24h, [de]activate the square wave, and 12read/write memory from the Serial Monitor. 13 14- `RealTimeClockDS1307.fz` is a Fritzing breadboard layout showing 15the basic hookup of the Sparkfun RTC module to an Arduino. Included 16is an optional resistor+LED to show the square wave (note that it's 17an open drain, so you hook up to it rather differently than, say, 18pin 13). 19 20## Changelog 21 22##### Version 0.95 23* Reverse renaming of getDate() and setDate(), now getDay() is calling getDate() and setDay() is calling setDate() 24* Readme improvements 25 26##### Version 0.94 27* changed getDate() to getDay() and setDate() to setDay() 28* updated keywords.txt 29* updated example 30 31##### Version 0.93 32* added keywords.txt for syntax highlighting 33 34##### Version 0.92 RC 35* Updated for Arduino 1.00; testing with Andreas Giemza (hurik) 36 37##### Version 0.91 38* added multi-byte read/write 39 40##### Version 0.9 RC 41* initial release 42 43## Future 44 - web page documentation 45 46## Credits 47 48Much thanks to John Waters and Maurice Ribble for their 49earlier and very helpful work (even if I didn't wind up 50using any of their code): 51 52- [http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock](http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock) 53- [http://www.glacialwanderer.com/hobbyrobotics/?p=12](http://www.glacialwanderer.com/hobbyrobotics/?p=12) 54 55## Copyright 56 57RealTimeClockDS1307 - library to control a DS1307 RTC module 58Copyright (c) 2011 David H. Brown. All rights reserved 59 60## License 61 62 This library is free software; you can redistribute it and/or 63 modify it under the terms of the GNU Lesser General Public 64 License as published by the Free Software Foundation; either 65 version 2.1 of the License, or (at your option) any later version. 66 67 This library is distributed in the hope that it will be useful, 68 but WITHOUT ANY WARRANTY; without even the implied warranty of 69 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 70 Lesser General Public License for more details. 71 72 You should have received a copy of the GNU Lesser General Public 73 License along with this library; if not, write to the Free Software 74 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 75
README.md
c_cpp
add this to the RTClib library
1This is a fork of JeeLab's fantastic real time clock library for Arduino. 2 3For details on using this library with an RTC module like the DS1307, see the guide at: https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview 4 5To download. click the DOWNLOADS button to the right, and rename the uncompressed folder RTClib. 6 7Place the RTClib folder in your *arduinosketchfolder*/libraries/ folder. 8You may need to create the libraries subfolder if its your first library. Restart the IDE. 9 10<!-- START COMPATIBILITY TABLE --> 11 12## Compatibility 13 14MCU | Tested Works | Doesn't Work | Not Tested | Notes 15------------------ | :----------: | :----------: | :---------: | ----- 16Atmega328 @ 16MHz | X | | | 17Atmega328 @ 12MHz | X | | | 18Atmega32u4 @ 16MHz | X | | | Use SDA/SCL on pins D3 & D2 19Atmega32u4 @ 8MHz | X | | | Use SDA/SCL on pins D3 & D2 20ESP8266 | X | | | SDA/SCL default to pins 4 & 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL) 21Atmega2560 @ 16MHz | X | | | Use SDA/SCL on Pins 20 & 21 22ATSAM3X8E | X | | | Use SDA1 and SCL1 23ATSAM21D | X | | | 24ATtiny85 @ 16MHz | X | | | 25ATtiny85 @ 8MHz | X | | | 26Intel Curie @ 32MHz | | | X | 27STM32F2 | | | X | 28 29 * ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini 30 * ATmega328 @ 12MHz : Adafruit Pro Trinket 3V 31 * ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0 32 * ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro 33 * ESP8266 : Adafruit Huzzah 34 * ATmega2560 @ 16MHz : Arduino Mega 35 * ATSAM3X8E : Arduino Due 36 * ATSAM21D : Arduino Zero, M0 Pro 37 * ATtiny85 @ 16MHz : Adafruit Trinket 5V 38 * ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V 39 40<!-- END COMPATIBILITY TABLE --> 41
Clock Code
arduino
The code uses the RTC library and the I2C library. You need these libraries for the program to execute. This program is for Common Anode type display.
1#include <Wire.h> 2#include<EEPROM.h> 3#include <RTClib.h> 4RTC_DS1307 RTC; 5int temp, inc, hours1, minut, add = 11; 6int HOUR, MINUT, SECOND; 7int latchPin = 3; //pin 12 on the 595 o3 3 8int dataPin = 4; //pin 14 on the 595 or 4 9int clockPin = 2; //pin 11 on the 595 or 2 10int shift = 256; 11int units, tens, hundreds, thousands; 12int x; 13int y; 14const int alarmHour = 17; 15const int alarmMinute = 26; 16 17void setup() { 18 Serial.begin(9600); 19 pinMode(latchPin, OUTPUT); 20 pinMode(dataPin, OUTPUT); 21 pinMode(clockPin, OUTPUT); 22 pinMode(13, OUTPUT); 23 Wire.begin(); 24 RTC.begin(); 25 if (!RTC.isrunning()) 26 { 27 RTC.adjust(DateTime(__DATE__, __TIME__)); 28 } 29} 30 31void loop() { 32 int temp = 0, val = 1, temp4; 33 DateTime now = RTC.now(); 34 HOUR = now.hour(); 35 MINUT = now.minute(); 36 //Serial.println(MINUT); 37 if (HOUR < 10) 38 { 39 hundreds = HOUR; 40 thousands = HOUR/10; 41 } 42 else if (HOUR >= 10 && HOUR < 24) 43 { 44 hundreds = HOUR % 10; 45 thousands = HOUR / 10; 46 } 47 if (MINUT <= 9) 48 { 49 units = MINUT; 50 tens = MINUT/10; 51 } 52 53 else if (MINUT > 9 && MINUT <= 60) 54 { 55 units = MINUT % 10; 56 tens = MINUT / 10; 57 } 58 59 switch (units) 60 { 61 case 0: 62 //0 63 digitalWrite(latchPin, LOW); 64 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 65 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 192 ); 66 digitalWrite(latchPin, HIGH); 67 break; 68 case 1: 69 //1 70 digitalWrite(latchPin, LOW); 71 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 72 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 249); 73 digitalWrite(latchPin, HIGH); 74 break; 75 case 2: 76 //2 77 digitalWrite(latchPin, LOW); 78 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 79 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 164); 80 digitalWrite(latchPin, HIGH); 81 break; 82 case 3: 83 //3 84 digitalWrite(latchPin, LOW); 85 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 86 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 176); 87 digitalWrite(latchPin, HIGH); 88 break; 89 case 4: 90 //4 91 digitalWrite(latchPin, LOW); 92 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 93 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 153); 94 digitalWrite(latchPin, HIGH); 95 break; 96 case 5: 97 //5 98 digitalWrite(latchPin, LOW); 99 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 100 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 146); 101 digitalWrite(latchPin, HIGH); 102 break; 103 case 6: 104 //6 105 digitalWrite(latchPin, LOW); 106 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 107 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 130); 108 digitalWrite(latchPin, HIGH); 109 break; 110 case 7: 111 //7 112 digitalWrite(latchPin, LOW); 113 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 114 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 248); 115 digitalWrite(latchPin, HIGH); 116 break; 117 case 8: 118 //8 119 digitalWrite(latchPin, LOW); 120 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 121 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 128); 122 digitalWrite(latchPin, HIGH); 123 break; 124 case 9: 125 //9 126 digitalWrite(latchPin, LOW); 127 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 ); 128 shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 144); 129 digitalWrite(latchPin, HIGH); 130 break; 131 } 132 delay(1); 133 134 135 switch (tens) 136 { 137 case 0: 138 //0 139 digitalWrite(latchPin, LOW); 140 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 141 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 192 ); 142 digitalWrite(latchPin, HIGH); 143 break; 144 case 1: 145 //1 146 digitalWrite(latchPin, LOW); 147 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 148 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 249); 149 digitalWrite(latchPin, HIGH); 150 break; 151 case 2: 152 //2 153 digitalWrite(latchPin, LOW); 154 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 155 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 164); 156 digitalWrite(latchPin, HIGH); 157 break; 158 case 3: 159 //3 160 digitalWrite(latchPin, LOW); 161 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 162 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 176); 163 digitalWrite(latchPin, HIGH); 164 break; 165 case 4: 166 //4 167 digitalWrite(latchPin, LOW); 168 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 169 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 153); 170 digitalWrite(latchPin, HIGH); 171 break; 172 case 5: 173 //5 174 digitalWrite(latchPin, LOW); 175 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 ); 176 shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 146); 177 digitalWrite(latchPin, HIGH); 178 break; 179 180 } 181 delay(1); 182 183 switch (hundreds) 184 { 185 case 0: 186 //0 187 digitalWrite(latchPin, LOW); 188 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 189 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 64 ); 190 digitalWrite(latchPin, HIGH); 191 break; 192 case 1: 193 //1 194 digitalWrite(latchPin, LOW); 195 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 196 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 121); 197 digitalWrite(latchPin, HIGH); 198 199 break; 200 case 2: 201 //2 202 digitalWrite(latchPin, LOW); 203 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 204 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 36); 205 digitalWrite(latchPin, HIGH); 206 break; 207 case 3: 208 //3 209 digitalWrite(latchPin, LOW); 210 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 211 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 48); 212 digitalWrite(latchPin, HIGH); 213 break; 214 case 4: 215 //4 216 digitalWrite(latchPin, LOW); 217 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 218 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 25); 219 digitalWrite(latchPin, HIGH); 220 break; 221 case 5: 222 //5 223 digitalWrite(latchPin, LOW); 224 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 225 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 18); 226 digitalWrite(latchPin, HIGH); 227 break; 228 case 6: 229 //6 230 digitalWrite(latchPin, LOW); 231 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 232 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 2); 233 digitalWrite(latchPin, HIGH); 234 break; 235 case 7: 236 //7 237 digitalWrite(latchPin, LOW); 238 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 239 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 120); 240 digitalWrite(latchPin, HIGH); 241 break; 242 case 8: 243 //8 244 digitalWrite(latchPin, LOW); 245 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 246 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 0); 247 digitalWrite(latchPin, HIGH); 248 break; 249 case 9: 250 //9 251 digitalWrite(latchPin, LOW); 252 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 >> 8 ); 253 shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 16); 254 digitalWrite(latchPin, HIGH); 255 break; 256 257 } 258 delay(1); 259 260 switch (thousands) 261 { 262 case 0: 263 //0 264 digitalWrite(latchPin, LOW); 265 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 266 shiftOut(dataPin, clockPin, MSBFIRST, shift + 192 ); 267 digitalWrite(latchPin, HIGH); 268 //delay(500); 269 break; 270 case 1: 271 //1 272 digitalWrite(latchPin, LOW); 273 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 274 shiftOut(dataPin, clockPin, MSBFIRST, shift + 249); 275 digitalWrite(latchPin, HIGH); 276 //delay(500); 277 break; 278 case 2: 279 //2 280 digitalWrite(latchPin, LOW); 281 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 282 shiftOut(dataPin, clockPin, MSBFIRST, shift + 164); 283 digitalWrite(latchPin, HIGH); 284 //delay(500); 285 break; 286 case 3: 287 //3 288 digitalWrite(latchPin, LOW); 289 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 290 shiftOut(dataPin, clockPin, MSBFIRST, shift + 176); 291 digitalWrite(latchPin, HIGH); 292 //delay(500); 293 break; 294 case 4: 295 //4 296 digitalWrite(latchPin, LOW); 297 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 298 shiftOut(dataPin, clockPin, MSBFIRST, shift + 153); 299 digitalWrite(latchPin, HIGH); 300 //delay(500); 301 break; 302 case 5: 303 //5 304 digitalWrite(latchPin, LOW); 305 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 306 shiftOut(dataPin, clockPin, MSBFIRST, shift + 146); 307 digitalWrite(latchPin, HIGH); 308 //delay(500); 309 break; 310 case 6: 311 //6 312 digitalWrite(latchPin, LOW); 313 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 314 shiftOut(dataPin, clockPin, MSBFIRST, shift + 130); 315 digitalWrite(latchPin, HIGH); 316 //delay(500); 317 break; 318 case 7: 319 //7 320 digitalWrite(latchPin, LOW); 321 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 322 shiftOut(dataPin, clockPin, MSBFIRST, shift + 248); 323 digitalWrite(latchPin, HIGH); 324 //delay(500); 325 break; 326 case 8: 327 //8 328 digitalWrite(latchPin, LOW); 329 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 330 shiftOut(dataPin, clockPin, MSBFIRST, shift + 128); 331 digitalWrite(latchPin, HIGH); 332 333 break; 334 case 9: 335 //9 336 digitalWrite(latchPin, LOW); 337 shiftOut(dataPin, clockPin, MSBFIRST, shift >> 8 ); 338 shiftOut(dataPin, clockPin, MSBFIRST, shift + 152); 339 digitalWrite(latchPin, HIGH); 340 break; 341 } 342 delay(1); 343 //alarm section 344 if (HOUR == alarmHour && MINUT == alarmMinute) 345 { 346 digitalWrite(13, HIGH); 347 } 348 else 349 { 350 digitalWrite(13, LOW); 351 } 352 353}
Readme
clojure
Copy this also into the same folder you created named "RealTimeClockDS1307".
1My goal in creating yet another DS1307 library was to provide 2easy access to some of the other functions I needed from the chip, 3specifically its square wave output and its battery-backed RAM. 4 5## Documentation 6@todo Mostly comments in `RealTimeClockDS1307.h` 7 8## Examples (in /examples folder) 9 10- `RealTimeClockDS1307_Test.pde` allow you to turn the clock on/off, 11set date/time, set 12/24h, [de]activate the square wave, and 12read/write memory from the Serial Monitor. 13 14- `RealTimeClockDS1307.fz` is a Fritzing breadboard layout showing 15the basic hookup of the Sparkfun RTC module to an Arduino. Included 16is an optional resistor+LED to show the square wave (note that it's 17an open drain, so you hook up to it rather differently than, say, 18pin 13). 19 20## Changelog 21 22##### Version 0.95 23* Reverse renaming of getDate() and setDate(), now getDay() is calling getDate() and setDay() is calling setDate() 24* Readme improvements 25 26##### Version 0.94 27* changed getDate() to getDay() and setDate() to setDay() 28* updated keywords.txt 29* updated example 30 31##### Version 0.93 32* added keywords.txt for syntax highlighting 33 34##### Version 0.92 RC 35* Updated for Arduino 1.00; testing with Andreas Giemza (hurik) 36 37##### Version 0.91 38* added multi-byte read/write 39 40##### Version 0.9 RC 41* initial release 42 43## Future 44 - web page documentation 45 46## Credits 47 48Much thanks to John Waters and Maurice Ribble for their 49earlier and very helpful work (even if I didn't wind up 50using any of their code): 51 52- [http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock](http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock) 53- [http://www.glacialwanderer.com/hobbyrobotics/?p=12](http://www.glacialwanderer.com/hobbyrobotics/?p=12) 54 55## Copyright 56 57RealTimeClockDS1307 - library to control a DS1307 RTC module 58Copyright (c) 2011 David H. Brown. All rights reserved 59 60## License 61 62 This library is free software; you can redistribute it and/or 63 modify it under the terms of the GNU Lesser General Public 64 License as published by the Free Software Foundation; either 65 version 2.1 of the License, or (at your option) any later version. 66 67 This library is distributed in the hope that it will be useful, 68 but WITHOUT ANY WARRANTY; without even the implied warranty of 69 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 70 Lesser General Public License for more details. 71 72 You should have received a copy of the GNU Lesser General Public 73 License along with this library; if not, write to the Free Software 74 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 75
RTClib files
csharp
create a folder named 'RTClib' and add the following files into it
1######################################### 2# Syntax Coloring Map RealTimeClockDS1307 3######################################### 4 5 6####################################### 7# 8 Instances (KEYWORD2) 9####################################### 10RTC KEYWORD2 11 12######################################### 13# 14 Methods and Functions (KEYWORD2) 15######################################### 16readClock KEYWORD2 17setClock KEYWORD2 18stop KEYWORD2 19start KEYWORD2 20sqwEnable KEYWORD2 21sqwDisable KEYWORD2 22writeData KEYWORD2 23readData KEYWORD2 24 25getHours KEYWORD2 26getMinutes KEYWORD2 27getSeconds KEYWORD2 28getYear KEYWORD2 29getMonth KEYWORD2 30getDate KEYWORD2 31getDay KEYWORD2 32getDayOfWeek KEYWORD2 33is12hour KEYWORD2 34isPM KEYWORD2 35isStopped KEYWORD2 36getFormatted KEYWORD2 37getFormatted2k KEYWORD2 38 39setSeconds KEYWORD2 40setMinutes KEYWORD2 41setHours KEYWORD2 42setAM KEYWORD2 43setPM KEYWORD2 44set24h KEYWORD2 45switchTo24h KEYWORD2 46switchTo12h KEYWORD2 47setDayOfWeek KEYWORD2 48setDate KEYWORD2 49setDay KEYWORD2 50setMonth KEYWORD2 51setYear KEYWORD2 52 53######################################### 54# 55 Constants (LITERAL1) 56######################################### 57SQW_1Hz LITERAL1 58SQW_4kHz LITERAL1 59SQW_8kHz LITERAL1 60SQW_32kHz LITERAL1 61
RTClib
c_cpp
add this to the RTClib folder. Now you have all the necessary files for the RTClib. Now do the same as I told you with the 'RealTimeClockDS1307' library file.
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 4 Copyright (c) 2011 David H. Brown. All rights reserved 5 6 v0.92 Updated 7 for Arduino 1.00; not re-tested on earlier versions 8 9 Much thanks to John 10 Waters and Maurice Ribble for their 11 earlier and very helpful work (even if 12 I didn't wind up 13 using any of their code): 14 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 15 16 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 17 18 This library is 19 free software; you can redistribute it and/or 20 modify it under the terms of 21 the GNU Lesser General Public 22 License as published by the Free Software Foundation; 23 either 24 version 2.1 of the License, or (at your option) any later version. 25 26 27 This library is distributed in the hope that it will be useful, 28 but WITHOUT 29 ANY WARRANTY; without even the implied warranty of 30 MERCHANTABILITY or FITNESS 31 FOR A PARTICULAR PURPOSE. See the GNU 32 Lesser General Public License for more 33 details. 34 35 You should have received a copy of the GNU Lesser General Public 36 37 License along with this library; if not, write to the Free Software 38 Foundation, 39 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 40*/ 41 42#ifndef 43 RealTimeClockDS1307_h 44#define RealTimeClockDS1307_h 45 46 #if defined(ARDUINO) 47 && ARDUINO >= 100 48 #include "Arduino.h" 49 #else 50 #include "WProgram.h" 51 52 #endif 53 54//#include <HardwareSerial.h> 55//#include <WConstants.h> //need/want 56 'boolean' and 'byte' types used by Arduino 57//#undef round is required to avoid 58 a compile-time 59//"expected unqualified-id before 'double'" error in math.h 60//see: 61 http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247924528/3 62#undef round 63#include 64 <Wire.h> 65 66#define ARDUINO_PIN_T uint8_t 67 68class RealTimeClockDS1307 69{ 70 71 private: 72 byte _reg0_sec; 73 byte _reg1_min; 74 byte _reg2_hour; 75 76 byte _reg3_day; 77 byte _reg4_date; 78 byte _reg5_month; 79 byte 80 _reg6_year; 81 byte _reg7_sqw; 82 byte decToBcd(byte); 83 byte bcdToDec(byte); 84 85 char lowNybbleToASCII(byte); 86 char highNybbleToASCII(byte); 87 public: 88 89 RealTimeClockDS1307(); 90 void readClock();//read registers (incl sqw) to 91 local store 92 void setClock();//update clock registers from local store 93 94 void stop();//immediate; does not require setClock(); 95 void start();//immediate; 96 does not require setClock(); 97 void sqwEnable(byte);//enable the square wave 98 with the specified frequency 99 void sqwDisable(boolean);//disable the square 100 wave, setting output either high or low 101 void writeData(byte, byte);//write 102 a single value to a register 103 void writeData(byte, void *, int);//write several 104 values consecutively 105 byte readData(byte);//read a single value from a register 106 107 void readData(byte, void *, int);//read several values into a buffer 108 109 110 int getHours(); 111 int getMinutes(); 112 int getSeconds(); 113 int 114 getYear(); 115 int getMonth(); 116 int getDate(); 117 int getDay(); 118 119 int getDayOfWeek(); 120 boolean is12hour(); 121 boolean isPM(); 122 boolean 123 isStopped(); 124 //getFormatted writes into a char array provided by you. Format 125 is: 126 // YY-MM-DD HH:II:SS ... plus "A" or "P" if in 12-hour mode 127 128 //and of course a NULL terminator. So, [18] for 24h or [19] for 12h 129 void 130 getFormatted(char *);//see comment above 131 void getFormatted2k(char *);//as 132 getFormatted, but with "20" prepended 133 134 //must also call setClock() after 135 any of these 136 //before next readClock(). Note that invalid dates are not 137 138 //corrected by the clock. All the clock knows is when it should 139 //roll 140 over to the next month rather than the next date in the same month. 141 void 142 setSeconds(int); 143 void setMinutes(int); 144 //setHours rejects values out 145 of range for the current 12/24 mode 146 void setHours(int); 147 void setAM();//does 148 not consider hours; see switchTo24() 149 void setPM();//does not consider hours; 150 see switchTo24() 151 void set24h();//does not consider hours; see switchTo24() 152 153 void switchTo24h();//returns immediately if already 24h 154 void switchTo12h();//returns 155 immediately if already 12h 156 void setDayOfWeek(int);//incremented at midnight; 157 not set by date (no fixed meaning) 158 void setDate(int);//allows 1-31 for *all* 159 months. 160 void setDay(int); 161 void setMonth(int); 162 void setYear(int); 163 164 165 //squarewave frequencies: 166 static const byte SQW_1Hz=0x00; 167 static 168 const byte SQW_4kHz=0x01;//actually 4.096kHz 169 static const byte SQW_8kHz=0x02;//actually 170 8.192kHz 171 static const byte SQW_32kHz=0x03;//actually 32.768kHz 172}; 173 174extern 175 RealTimeClockDS1307 RTC; 176 177#endif 178
RTClib
c_cpp
add this to the RTClib folder
1/* 2 RealTimeClockDS1307 - library to control a DS1307 RTC module 3 4 Copyright (c) 2011 David H. Brown. All rights reserved 5 6 v0.92 Updated 7 for Arduino 1.00; not re-tested on earlier versions 8 9 Much thanks to John 10 Waters and Maurice Ribble for their 11 earlier and very helpful work (even if 12 I didn't wind up 13 using any of their code): 14 - http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock 15 16 - http://www.glacialwanderer.com/hobbyrobotics/?p=12 17 18 This library is 19 free software; you can redistribute it and/or 20 modify it under the terms of 21 the GNU Lesser General Public 22 License as published by the Free Software Foundation; 23 either 24 version 2.1 of the License, or (at your option) any later version. 25 26 27 This library is distributed in the hope that it will be useful, 28 but WITHOUT 29 ANY WARRANTY; without even the implied warranty of 30 MERCHANTABILITY or FITNESS 31 FOR A PARTICULAR PURPOSE. See the GNU 32 Lesser General Public License for more 33 details. 34 35 You should have received a copy of the GNU Lesser General Public 36 37 License along with this library; if not, write to the Free Software 38 Foundation, 39 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 40*/ 41 42/****************************************************************************** 43 44 * Includes 45 ******************************************************************************/ 46 47#include 48 "RealTimeClockDS1307.h" 49#include <Wire.h> 50 51/****************************************************************************** 52 53 * Definitions 54 ******************************************************************************/ 55 56#define 57 DS1307_I2C_ADDRESS 0x68 // This is the I2C address 58 59/****************************************************************************** 60 61 * Constructors 62 ******************************************************************************/ 63 64RealTimeClockDS1307::RealTimeClockDS1307() 65{ 66 67 Wire.begin(); 68 //must NOT attempt to read the clock before 69 //Wire.begin() 70 has not been called; readClock() will hang. 71 //Fortunately, it seems that you 72 can call Wire.begin() 73 //multiple times with no adverse effect). 74} 75 76/****************************************************************************** 77 78 * User API 79 ******************************************************************************/ 80 81/***** 82 CHIP READ/WRITE ******/ 83 84void RealTimeClockDS1307::readClock() 85{ 86 // 87 Reset the register pointer 88 Wire.beginTransmission(DS1307_I2C_ADDRESS); 89 90 Wire.write((uint8_t) 0x00); 91 Wire.endTransmission(); 92 93 Wire.requestFrom(DS1307_I2C_ADDRESS, 94 8); 95 _reg0_sec = Wire.read(); 96 _reg1_min = Wire.read(); 97 _reg2_hour 98 = Wire.read(); 99 _reg3_day = Wire.read(); 100 _reg4_date = Wire.read(); 101 102 _reg5_month = Wire.read(); 103 _reg6_year = Wire.read(); 104 _reg7_sqw = Wire.read(); 105} 106 107void 108 RealTimeClockDS1307::setClock() 109{ 110 //to be paranoid, we're going to first 111 stop the clock 112 //to ensure we don't have rollovers while we're 113 //writing: 114 115 writeData(0,0x80); 116 //now, we'll write everything *except* the second 117 118 Wire.beginTransmission(DS1307_I2C_ADDRESS); 119 Wire.write((uint8_t) 0x01); 120 121 Wire.write(_reg1_min); 122 Wire.write(_reg2_hour); 123 Wire.write(_reg3_day); 124 125 Wire.write(_reg4_date); 126 Wire.write(_reg5_month); 127 Wire.write(_reg6_year); 128 129 Wire.endTransmission(); 130 //now, we'll write the seconds; we didn't have to 131 keep 132 //track of whether the clock was already running, because 133 //_reg0_sec 134 already knows what we want it to be. This 135 //will restart the clock as it writes 136 the new seconds value. 137 writeData(0,_reg0_sec); 138} 139 140void RealTimeClockDS1307::stop() 141{ 142 143 //"Bit 7 of register 0 is the clock halt (CH) bit. 144 //When this bit is set 145 to a 1, the oscillator is disabled." 146 _reg0_sec = _reg0_sec | 0x80; 147 writeData(0,_reg0_sec); 148} 149void 150 RealTimeClockDS1307::start() 151{ 152 //"Bit 7 of register 0 is the clock halt 153 (CH) bit. 154 //When this bit is set to a 1, the oscillator is disabled." 155 156 _reg0_sec = _reg0_sec & ~0x80; 157 writeData(0,_reg0_sec); 158} 159 160void RealTimeClockDS1307::writeData(byte 161 regNo, byte value) 162{ 163 if(regNo > 0x3F) { return; } 164 Wire.beginTransmission(DS1307_I2C_ADDRESS); 165 166 Wire.write(regNo); 167 Wire.write(value); 168 Wire.endTransmission(); 169} 170 171void 172 RealTimeClockDS1307::writeData(byte regNo, void * source, int length) 173{ 174 char 175 * p = (char*) source; 176 if(regNo > 0x3F || length > 0x3F) { return; } 177 Wire.beginTransmission(DS1307_I2C_ADDRESS); 178 179 Wire.write(regNo); 180 for(int i=0; i<length; i++) { 181 Wire.write(*p); 182 183 p++; 184 } 185 Wire.endTransmission(); 186} 187 188byte RealTimeClockDS1307::readData(byte 189 regNo) 190{ 191 if(regNo > 0x3F) { return 0xff; } 192 Wire.beginTransmission(DS1307_I2C_ADDRESS); 193 194 Wire.write(regNo); 195 Wire.endTransmission(); 196 Wire.requestFrom(DS1307_I2C_ADDRESS, 197 1); 198 return Wire.read(); 199} 200 201void RealTimeClockDS1307::readData(byte 202 regNo, void * dest, int length) 203{ 204 char * p = (char*) dest; 205 if(regNo 206 > 0x3F || length > 0x3F) { return; } 207 Wire.beginTransmission(DS1307_I2C_ADDRESS); 208 209 Wire.write(regNo); 210 Wire.endTransmission(); 211 Wire.requestFrom(DS1307_I2C_ADDRESS, 212 length); 213 for(int i=0; i<length; i++) { 214 *p=Wire.read(); 215 p++; 216 217 } 218} 219 220 221void RealTimeClockDS1307::sqwEnable(byte frequency) 222{ 223 224 if(frequency > 3) { return; } 225 //bit 4 is enable (0x10); 226 //bit 7 is current 227 output state if disabled 228 _reg7_sqw = _reg7_sqw & 0x80 | 0x10 | frequency; 229 230 writeData(0x07, _reg7_sqw); 231} 232 233void RealTimeClockDS1307::sqwDisable(boolean 234 outputLevel) 235{ 236 //bit 7 0x80 output + bit 4 0x10 enable both to zero, 237 238 //the OR with the boolean shifted up to bit 7 239 _reg7_sqw = _reg7_sqw & ~0x90 240 | (outputLevel << 7); 241 writeData(0x07, _reg7_sqw); 242 //note: per the data 243 sheet, "OUT (Output control): This bit controls 244 //the output level of the 245 SQW/OUT pin when the square wave 246 //output is disabled. If SQWE = 0, the logic 247 level on the 248 //SQW/OUT pin is 1 if OUT = 1 and is 0 if OUT = 0." 249 //"The 250 SQW/OUT pin is open drain and requires an external 251 //pull-up resistor." 252 253 //It is worth mentioning that on the Sparkfun breakout board, 254 //BOB-00099, 255 a LED connected to the SQW pin through a resistor to 256 //Vcc+5V illuminated when 257 OUT=0 and was dark when OUT=1, the 258 //opposite of what I expected until I remembered 259 that it is 260 //an open drain (google it if you need to). Basically, they don't 261 262 //so much mean a logic level (e.g., +3.3V rel Gnd) as they mean 263 //high or 264 low *impeadance* to ground (drain). So High is basically 265 //an open switch. 266 Low connects to ground. 267} 268 269 270/***** GETTERS ******/ 271 272boolean RealTimeClockDS1307::is12hour() 273 274{ 275 //12-hour mode has bit 6 of the hour register set high 276 return ((_reg2_hour 277 & 0x40) == 0x40); 278} 279boolean RealTimeClockDS1307::isPM() 280{ 281 //if in 282 12-hour mode, but 5 of the hour register indicates PM 283 if(is12hour()) { 284 285 return ((_reg2_hour & 0x20) == 0x20); 286 } 287 //otherwise, let's consider 288 any time with the hour >11 to be PM: 289 return (getHours() > 11); 290} 291boolean 292 RealTimeClockDS1307::isStopped() 293{ 294 //bit 7 of the seconds register stopps 295 the clock when high 296 return ((_reg0_sec & 0x80) == 0x80); 297} 298 299int RealTimeClockDS1307::getHours() 300{ 301 302 if(is12hour()) { 303 //do not include bit 5, the am/pm indicator 304 return 305 bcdToDec(_reg2_hour & 0x1f); 306 } 307 //bits 4-5 are tens of hours 308 return 309 bcdToDec(_reg2_hour & 0x3f); 310} 311int RealTimeClockDS1307::getMinutes() 312{ 313 314 //could mask with 0x7f but shouldn't need to 315 return bcdToDec(_reg1_min); 316} 317int 318 RealTimeClockDS1307::getSeconds() 319{ 320 //need to mask oscillator start/stop 321 bit 7 322 return bcdToDec(_reg0_sec & 0x7f); 323} 324int RealTimeClockDS1307::getYear() 325{ 326 327 return bcdToDec(_reg6_year); 328} 329int RealTimeClockDS1307::getMonth() 330{ 331 332 //could mask with 0x1f but shouldn't need to 333 return bcdToDec(_reg5_month); 334} 335int 336 RealTimeClockDS1307::getDate() 337{ 338 //could mask with 0x3f but shouldn't need 339 to 340 return bcdToDec(_reg4_date); 341} 342int RealTimeClockDS1307::getDay() 343{ 344 345 return getDate(); 346} 347int RealTimeClockDS1307::getDayOfWeek() 348{ 349 //could 350 mask with 0x07 but shouldn't need to 351 return bcdToDec(_reg3_day); 352} 353 354void 355 RealTimeClockDS1307::getFormatted(char * buffer) 356{ 357 int i=0; 358 //target 359 string format: YY-MM-DD HH:II:SS 360 buffer[i++]=highNybbleToASCII(_reg6_year); 361 362 buffer[i++]=lowNybbleToASCII(_reg6_year); 363 buffer[i++]='-'; 364 buffer[i++]=highNybbleToASCII(_reg5_month 365 & 0x1f); 366 buffer[i++]=lowNybbleToASCII(_reg5_month); 367 buffer[i++]='-'; 368 369 buffer[i++]=highNybbleToASCII(_reg4_date & 0x3f); 370 buffer[i++]=lowNybbleToASCII(_reg4_date); 371 372 buffer[i++]=' '; 373 if(is12hour()) { 374 buffer[i++]=highNybbleToASCII(_reg2_hour 375 & 0x1f); 376 } else { 377 buffer[i++]=highNybbleToASCII(_reg2_hour & 0x3f); 378 379 } 380 buffer[i++]=lowNybbleToASCII(_reg2_hour); 381 buffer[i++]=':'; 382 buffer[i++]=highNybbleToASCII(_reg1_min 383 & 0x7f); 384 buffer[i++]=lowNybbleToASCII(_reg1_min); 385 buffer[i++]=':'; 386 387 buffer[i++]=highNybbleToASCII(_reg0_sec & 0x7f); 388 buffer[i++]=lowNybbleToASCII(_reg0_sec); 389 390 if(is12hour()) { 391 if(isPM()) { 392 buffer[i++]='P'; 393 } else { 394 395 buffer[i++]='A'; 396 } 397 } 398 buffer[i++]=0x00; 399} 400 401void RealTimeClockDS1307::getFormatted2k(char 402 * buffer) 403{ 404 buffer[0]='2'; 405 buffer[1]='0'; 406 getFormatted(&buffer[2]); 407} 408 409/**** 410 SETTERS *****/ 411 412void RealTimeClockDS1307::setSeconds(int s) 413{ 414 if (s 415 < 60 && s >=0) 416 { 417 //need to preserve oscillator bit 418 _reg0_sec 419 = decToBcd(s) | (_reg0_sec & 0x80); 420 } 421} 422void RealTimeClockDS1307::setMinutes(int 423 m) 424{ 425 if (m < 60 && m >=0) 426 { 427 _reg1_min = decToBcd(m); 428 } 429} 430void 431 RealTimeClockDS1307::setHours(int h) 432{ 433 if (is12hour()) 434 { 435 if 436 (h >= 1 && h <=12) 437 { 438 //preserve 12/24 and AM/PM bits 439 _reg2_hour 440 = decToBcd(h) | (_reg2_hour & 0x60); 441 } 442 } else { 443 if (h >= 0 && 444 h <=24) 445 { 446 //preserve 12/24 bit 447 _reg2_hour = decToBcd(h) 448 | (_reg2_hour & 0x40); 449 } 450 }//else 451}//setHours 452 453void RealTimeClockDS1307::set24h() 454{ 455 456 //"Bit 6 of the hours register is defined as the 457 //"12- or 24-hour mode 458 select bit. 459 //"When high, the 12-hour mode is selected" 460 //So, mask the 461 curent value with the complement turn off that bit: 462 _reg2_hour = _reg2_hour 463 & ~0x40; 464} 465void RealTimeClockDS1307::setAM() 466{ 467 //"In the 12-hour 468 mode, bit 5 is the AM/PM bit with logic high being PM" 469 //so we need to OR 470 with 0x40 to set 12-hour mode and also 471 //turn off the PM bit by masking with 472 the complement 473 _reg2_hour = _reg2_hour & ~0x20 | 0x40; 474} 475void RealTimeClockDS1307::setPM() 476{ 477 478 //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" 479 480 //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also 481 //turn 482 on the PM bit: 483 _reg2_hour = _reg2_hour | 0x60; 484} 485 486void RealTimeClockDS1307::switchTo12h() 487{ 488 489 if(is12hour()) { return; } 490 int h = getHours(); 491 if (h < 12) { 492 setAM(); 493 494 } else { 495 h = h-12; 496 setPM(); 497 } 498 if (h==0) 499 { 500 h=12; 501 502 } 503 setHours(h); 504} 505void RealTimeClockDS1307::switchTo24h() 506{ 507 if(!is12hour()) 508 { return ; } 509 int h = getHours(); 510 if(h==12) {//12 PM is just 12; 12 AM 511 is 0 hours. 512 h = 0; 513 } 514 if (isPM()) 515 {//if it was 12 PM, then 516 h=0 above and so we're back to 12: 517 h = h+12; 518 } 519 set24h(); 520 setHours(h); 521} 522 523void 524 RealTimeClockDS1307::setDayOfWeek(int d) 525{ 526 if (d > 0 && d < 8) 527 { 528 529 _reg3_day = decToBcd(d); 530 } 531} 532 533void RealTimeClockDS1307::setDate(int 534 d) 535{ 536 if (d > 0 && d < 32) 537 { 538 _reg4_date = decToBcd(d); 539 } 540} 541void 542 RealTimeClockDS1307::setDay(int d) 543{ 544 setDate(d); 545} 546 547void RealTimeClockDS1307::setMonth(int 548 m) 549{ 550 if (m > 0 && m < 13) 551 { 552 _reg5_month = decToBcd(m); 553 } 554} 555void 556 RealTimeClockDS1307::setYear(int y) 557{ 558 if (y >= 0 && y <100) 559 { 560 _reg6_year 561 = decToBcd(y); 562 } 563} 564 565 566 567/***************************************** 568 569 * Private methods 570 *****************************************/ 571byte RealTimeClockDS1307::decToBcd(byte 572 b) 573{ 574 return ( ((b/10) << 4) + (b%10) ); 575} 576 577// Convert binary coded 578 decimal to normal decimal numbers 579byte RealTimeClockDS1307::bcdToDec(byte b) 580{ 581 582 return ( ((b >> 4)*10) + (b%16) ); 583} 584 585char RealTimeClockDS1307::lowNybbleToASCII(byte 586 b) 587{ 588 b = b & 0x0f; 589 if(b < 10) { 590 //0 is ASCII 48 591 return 592 48+b; 593 } 594 //A is ASCII 55 595 return 55+b; 596} 597char RealTimeClockDS1307::highNybbleToASCII(byte 598 b) 599{ 600 return lowNybbleToASCII(b >> 4); 601} 602 603/***** INSTANCE *******/ 604 605RealTimeClockDS1307 606 RTC = RealTimeClockDS1307(); 607
Readme
clojure
Copy this also into the same folder you created named "RealTimeClockDS1307".
1My goal in creating yet another DS1307 library was to provide 2easy 3 access to some of the other functions I needed from the chip, 4specifically its 5 square wave output and its battery-backed RAM. 6 7## Documentation 8@todo 9 Mostly comments in `RealTimeClockDS1307.h` 10 11## Examples (in /examples folder) 12 13- 14 `RealTimeClockDS1307_Test.pde` allow you to turn the clock on/off, 15set date/time, 16 set 12/24h, [de]activate the square wave, and 17read/write memory from the Serial 18 Monitor. 19 20- `RealTimeClockDS1307.fz` is a Fritzing breadboard layout showing 21the 22 basic hookup of the Sparkfun RTC module to an Arduino. Included 23is an optional 24 resistor+LED to show the square wave (note that it's 25an open drain, so you hook 26 up to it rather differently than, say, 27pin 13). 28 29## Changelog 30 31##### 32 Version 0.95 33* Reverse renaming of getDate() and setDate(), now getDay() is calling 34 getDate() and setDay() is calling setDate() 35* Readme improvements 36 37##### 38 Version 0.94 39* changed getDate() to getDay() and setDate() to setDay() 40* updated 41 keywords.txt 42* updated example 43 44##### Version 0.93 45* added keywords.txt 46 for syntax highlighting 47 48##### Version 0.92 RC 49* Updated for Arduino 1.00; 50 testing with Andreas Giemza (hurik) 51 52##### Version 0.91 53* added multi-byte 54 read/write 55 56##### Version 0.9 RC 57* initial release 58 59## Future 60 61 - web page documentation 62 63## Credits 64 65Much thanks to John Waters and 66 Maurice Ribble for their 67earlier and very helpful work (even if I didn't wind 68 up 69using any of their code): 70 71- [http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock](http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock) 72- 73 [http://www.glacialwanderer.com/hobbyrobotics/?p=12](http://www.glacialwanderer.com/hobbyrobotics/?p=12) 74 75## 76 Copyright 77 78RealTimeClockDS1307 - library to control a DS1307 RTC module 79Copyright 80 (c) 2011 David H. Brown. All rights reserved 81 82## License 83 84 This library 85 is free software; you can redistribute it and/or 86 modify it under the terms 87 of the GNU Lesser General Public 88 License as published by the Free Software 89 Foundation; either 90 version 2.1 of the License, or (at your option) any later 91 version. 92 93 This library is distributed in the hope that it will be useful, 94 95 but WITHOUT ANY WARRANTY; without even the implied warranty of 96 MERCHANTABILITY 97 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 98 Lesser General Public License 99 for more details. 100 101 You should have received a copy of the GNU Lesser General 102 Public 103 License along with this library; if not, write to the Free Software 104 105 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 106
library.properties(name)
c_cpp
add this to the RTClib folder
1My goal in creating yet another DS1307 library was to provide 2easy 3 access to some of the other functions I needed from the chip, 4specifically its 5 square wave output and its battery-backed RAM. 6 7## Documentation 8@todo 9 Mostly comments in `RealTimeClockDS1307.h` 10 11## Examples (in /examples folder) 12 13- 14 `RealTimeClockDS1307_Test.pde` allow you to turn the clock on/off, 15set date/time, 16 set 12/24h, [de]activate the square wave, and 17read/write memory from the Serial 18 Monitor. 19 20- `RealTimeClockDS1307.fz` is a Fritzing breadboard layout showing 21the 22 basic hookup of the Sparkfun RTC module to an Arduino. Included 23is an optional 24 resistor+LED to show the square wave (note that it's 25an open drain, so you hook 26 up to it rather differently than, say, 27pin 13). 28 29## Changelog 30 31##### 32 Version 0.95 33* Reverse renaming of getDate() and setDate(), now getDay() is calling 34 getDate() and setDay() is calling setDate() 35* Readme improvements 36 37##### 38 Version 0.94 39* changed getDate() to getDay() and setDate() to setDay() 40* updated 41 keywords.txt 42* updated example 43 44##### Version 0.93 45* added keywords.txt 46 for syntax highlighting 47 48##### Version 0.92 RC 49* Updated for Arduino 1.00; 50 testing with Andreas Giemza (hurik) 51 52##### Version 0.91 53* added multi-byte 54 read/write 55 56##### Version 0.9 RC 57* initial release 58 59## Future 60 61 - web page documentation 62 63## Credits 64 65Much thanks to John Waters and 66 Maurice Ribble for their 67earlier and very helpful work (even if I didn't wind 68 up 69using any of their code): 70 71- [http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock](http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock) 72- 73 [http://www.glacialwanderer.com/hobbyrobotics/?p=12](http://www.glacialwanderer.com/hobbyrobotics/?p=12) 74 75## 76 Copyright 77 78RealTimeClockDS1307 - library to control a DS1307 RTC module 79Copyright 80 (c) 2011 David H. Brown. All rights reserved 81 82## License 83 84 This library 85 is free software; you can redistribute it and/or 86 modify it under the terms 87 of the GNU Lesser General Public 88 License as published by the Free Software 89 Foundation; either 90 version 2.1 of the License, or (at your option) any later 91 version. 92 93 This library is distributed in the hope that it will be useful, 94 95 but WITHOUT ANY WARRANTY; without even the implied warranty of 96 MERCHANTABILITY 97 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 98 Lesser General Public License 99 for more details. 100 101 You should have received a copy of the GNU Lesser General 102 Public 103 License along with this library; if not, write to the Free Software 104 105 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 106
another file
c_cpp
add this to the 'RealTimeClockDS1307' folder.
1######################################### 2# Syntax Coloring Map RealTimeClockDS1307 3######################################### 4 5 6####################################### 7# 8 Instances (KEYWORD2) 9####################################### 10RTC KEYWORD2 11 12######################################### 13# 14 Methods and Functions (KEYWORD2) 15######################################### 16readClock KEYWORD2 17setClock KEYWORD2 18stop KEYWORD2 19start KEYWORD2 20sqwEnable KEYWORD2 21sqwDisable KEYWORD2 22writeData KEYWORD2 23readData KEYWORD2 24 25getHours KEYWORD2 26getMinutes KEYWORD2 27getSeconds KEYWORD2 28getYear KEYWORD2 29getMonth KEYWORD2 30getDate KEYWORD2 31getDay KEYWORD2 32getDayOfWeek KEYWORD2 33is12hour KEYWORD2 34isPM KEYWORD2 35isStopped KEYWORD2 36getFormatted KEYWORD2 37getFormatted2k KEYWORD2 38 39setSeconds KEYWORD2 40setMinutes KEYWORD2 41setHours KEYWORD2 42setAM KEYWORD2 43setPM KEYWORD2 44set24h KEYWORD2 45switchTo24h KEYWORD2 46switchTo12h KEYWORD2 47setDayOfWeek KEYWORD2 48setDate KEYWORD2 49setDay KEYWORD2 50setMonth KEYWORD2 51setYear KEYWORD2 52 53######################################### 54# 55 Constants (LITERAL1) 56######################################### 57SQW_1Hz LITERAL1 58SQW_4kHz LITERAL1 59SQW_8kHz LITERAL1 60SQW_32kHz LITERAL1 61
Downloadable files
Clock Schematic
This is the schematic of the project.
Clock Schematic
Clock Schematic
This is the schematic of the project.
Clock Schematic
Comments
Only logged in users can leave comments
shivakumarj1995
0 Followers
•0 Projects
Table of contents
Intro
18
0