DS-1302 from Maxim (data sheet download) is a cheap RTC chip. Below are some of the salient features.
- Real-Time Clock Counts Seconds,Minutes, Hours, Date of the Month, Month, Day of the Week, and Year with Leap-Year Compensation Valid Up to 2100
- Simple 3-Wire Interface
- 2.0V to 5.5V Full Operation
- TTL-Compatible (VCC = 5V)
- 31 x 8 Battery-Backed General-Purpose RAM
There are breakout boards available on ebay, which will be handy to build RTC based projects with Arduino. Look for China based sellers for a cheap price.
Though there are various modules available but the above two types I found to be working properly.
The below board didn't work at all. Notice the PCB trace which indicates the poor quality.Unfortunately there was no way to know this before delivery.
For those modules which has two power pins (VCC1 and VCC2), power to be connected to VCC2, VCC1 is connected to battery
The below code can be used to used to write and read time from the chip.
Credit for the DS1302 library used here goes to Matt Sparks. The library can be downloaded
from Github and also
from here (in case it goes off from Github).
Below is a code snippet (based on Matt Spark’s work) for setting time and reading it back easily. Please note for writing to the chip VCC2 needs to be given power (I used 5v).
//http://datasheets.maximintegrated.com/en/ds/DS1302.pdf
#include <DS1302.h>
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(2, 3); // RX, TX
namespace {
// Set the appropriate digital I/O pin connections.
const int kCePin = 8; // Chip Enable (Some calls it Reset)
const int kIoPin = 7; // Input/Output
const int kSclkPin = 6; // Serial Clock
// Create a DS1302 object.
DS1302 rtc(kCePin, kIoPin, kSclkPin);
String dayAsString(const Time::Day day) {
switch (day) {
case Time::kSunday: return "Sunday";
case Time::kMonday: return "Monday";
case Time::kTuesday: return "Tuesday";
case Time::kWednesday: return "Wednesday";
case Time::kThursday: return "Thursday";
case Time::kFriday: return "Friday";
case Time::kSaturday: return "Saturday";
}
return "(unknown day)";
}
void printTime() {
// Get the current time and date from the chip.
Time t = rtc.time();
// Name the day of the week.
const String day = dayAsString(t.day);
// Format the time and date and insert into the temporary buffer.
char buf[50];
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
day.c_str(),
t.yr, t.mon, t.date,
t.hr, t.min, t.sec);
// Print the formatted string to serial so we can see the time.
Serial.println(buf);
//mySerial.println(buf);
}
} // end of namespace
void setup() {
Serial.begin(9600);
//mySerial.begin(38400);
// Initialize a new chip by turning off write protection and clearing the clock halt flag.
rtc.writeProtect(false); //should be set to true after writing to prevent accidental writes
rtc.halt(false);
// Year month day hour min sec. DOW
Time t(2016, 2, 28, 19, 9, 30, Time::kSunday);
// Set the time and date on the chip.
rtc.time(t); //after writing once, comment/remove this code to prevent unnecessary/wrong re-writing of the time
}
// Loop and print the time every 5 seconds.
void loop() {
printTime(); //prints the date and time
delay(5000);
}