Overview
This page contains information relevant to both the DS1302 and DS1307 real-time clock (RTC) chips. All information specific to one chip will be pointed out.
View additional chip-specific guides: DS1302, DS1307
This guide uses my DS130X library. Download the library in Zip format
All example code is under File > Examples > DS130X > (your RTC).
Printing Date and Time
After installing the library, go to the DateAndTime > PrintDateTime example.
/*
PrintDateTime.ino
Sketch to print the date and time strings from the RTC.
Created August 28, 2020
DS1302 connections:
CLK to 2
DAT to 3
CE to 4
*/
#include <DS130X.h>
DS1302 rtc(3, 2, 4); // DAT, CLK, CE
void setup() {
// Set time and date
rtc.setWriteProtect(false);
rtc.setDate(28, 8, 20, FRIDAY); // Friday, 28 August 2020
rtc.setTime(10, 5, 50); // 10:05:50
Serial.begin(9600); // Open serial port
}
void loop() {
// Read day of week, date, and time strings
String dow = rtc.dowAbbr(); // Day of week (abbreviated)
String date = rtc.dateStr(); // Read date
String time = rtc.timeStr(); // Read time
// Print the data in format:
// dow, date time
Serial.println(dow + ", " + date + " " + time);
delay(1000); // Delay one second
}
Creating the RTC Object
The DS1302 constructor takes parameters in the order:
dataPin
: Arduino pin that the RTC's DAT pin is connected toclockPin
: Arduino pin that the RTC's CLK pin is connected tocePin
: Arduino pin that the RTC's CE pin is connected to
The DS1307 constructor takes no parameters. Wire.begin
must be called to intialize the I2C bus before using the RTC.
Writing Date and Time
DS1302 only: Before writing to the RTC's registers, we need call setWriteProtect(false);
which sets the write protect bit. When write protect is enabled, the write
and writeRaw
methods won't do anything, but it is disabled, these methods will write data to the chip.
setTime
takes parameters in the order:
hour
: Hour to set (0-23)minute
: Minute to set (0-59)second
: Second to set (0-59)
setDate
takes parameters in the order:
day
: Day of month to set (1-31)month
: Month to set (1-12)year
: Year to set (0-99)dayOfWk
: Day of week to set (use the weekday constants:SUNDAY
,MONDAY
, etc.)
Reading Date and Time
These functions return parts of the current date/time in predetermined formats:
dowAbbr
: Day of week abbreviationdateStr
: Date as a string (dd/mm/yy format)timeStr
: Time as a string (hh:mm:ss)
At the end of each loop iteration, the program pauses for one second so it doesn't read too quickly.
Reading and Writing Registers
An example of reading registers is at DateAndTime > ReadData.
/*
ReadData.ino
Sketch to read unformatted time data from the RTC.
Created August 28, 2020
DS1302 connections:
CLK to 2
DAT to 3
CE to 4
*/
#include <DS130X.h>
DS1302 rtc(3, 2, 4); // DAT, CLK, CE
void setup() {
// Set time and date
rtc.setWriteProtect(false);
rtc.setDate(28, 8, 20, FRIDAY); // Friday, 28 August 2020
rtc.setTime(10, 5, 50); // 10:05:50
Serial.begin(9600); // Open serial port
}
void loop() {
// Read time from RTC
uint8_t hours = rtc.read(HOURS);
uint8_t minutes = rtc.read(MINUTES);
uint8_t seconds = rtc.read(SECONDS);
Serial.println("Hour: " + String(hours));
Serial.println("Minute: " + String(minutes));
Serial.println("Second: " + String(seconds));
Serial.println();
// Read date from RTC
uint8_t dayOfWeek = rtc.read(DAY_OF_WEEK);
uint8_t dayOfMonth = rtc.read(DAY_OF_MONTH);
uint8_t month = rtc.read(MONTHS);
uint8_t year = rtc.read(YEARS);
Serial.println("Day of week: " + String(dayOfWeek));
Serial.println("Day: " + String(dayOfMonth));
Serial.println("Month: " + String(month));
Serial.println("Year: " + String(year));
Serial.println("--------------------"); // Print a separator
delay(1000); // 1 second pause
}
Available Registers
The RTC classes have four methods to read and write to registers:
read
readRaw
write
writeRaw
All four methods will require you to specify a register to perform operations on. There are two ways to do this. The first way is to specify a register constant:
SECONDS
(range 0-59)MINUTES
(0-59)HOURS
(0-23)DAY_OF_WEEK
(1-7)DAY_OF_MONTH
(1-31)MONTHS
(1-12)YEARS
(0-99)TCR_GET
(DS1302 only, read-only)TCR_SET
(DS1302 only, write-only)SQW_OUT
(DS1307 only)
You can also specify a register address. For example, with a DS1302, write(0x80)
writes to the register 0x80 (the seconds register). (On the DS1307, this register is 0x00.)
note:
DS1302 only:
The read registers are always one higher than the write registers. For example, to write to the minutes register, use write(0x82, x);
to write and read(0x83);
to read.
If you are using a register constant (like MINUTES
), this difference is already handled, and you can use write(MINUTES, x);
and read(MINUTES);
important:
Writing to the seconds register will overwrite the halt bit to 0. Keep this in mind when using this method - call setHalt
after setting the seconds register (See "Additional Functions").
Register Operations
read
and readRaw
both take a single parameter: the register to read from.
read
will convert the register data from BCD to base-10 and apply a bitmask, if necessary. readRaw
will directly return the register's data without converting or masking.
write
and writeRaw
both take two parameters in the order:
reg
: Register address to write tovalue
: Data to write to the register
write
expects the value to be in base-10, then converts it to BCD to write. writeRaw
expects the value to be in BCD, and directly writes to the register without converting.
note:
When writing to the seconds register with writeRaw
, you can explicitly set the halt bit (bit #7, the MSB, in the seconds register).
Reading and Writing RAM
Register operations can be used for operating on the RTC's RAM. An example is at Other > RAMReadWrite.
/*
RAMReadWrite.ino
Sketch to demonstrate reading and writing the DS1307's RAM.
Created August 30, 2020
DS1302 connections:
CLK to 2
DAT to 3
CE to 4
*/
#include <DS130X.h>
DS1302 rtc(3, 2, 4); // DAT, CLK, CE
void setup() {
rtc.setWriteProtect(false);
Serial.begin(9600);
// Write to all bytes of RAM
Serial.println("Writing to RAM");
int value = 0; // Value to hold in RAM
for (int i = rtc.ramWStart(); i <= rtc.ramWEnd(); i += 2) {
// Add 2 to counter to skip every other address (the read address)
// ramWStart() returns the starting address for writing RAM.
// ramWEnd() returns the ending address for writing RAM.
rtc.write(i, value); // Write to RAM
value++; // New value for next address
}
// Read from all bytes of RAM
Serial.println("Reading from RAM");
for (int i = rtc.ramRStart(); i <= rtc.ramREnd(); i += 2) {
// Add 2 to counter to skip every other address (the write address)
// ramRStart() returns the starting address for reading RAM.
// ramREnd() returns the ending address for reading RAM.
uint8_t ramValue = rtc.read(i); // Read from RAM
// Print the value in RAM
Serial.println("Address 0x" + String(i, HEX) + " has value " + String(ramValue));
}
}
void loop() {} // No loop
Addresses and Bounds
Using the below functions as the lower and upper bounds of a for loop, we can iterate through each address.
To operate on a single byte, use read
or write
and set the register value to the desired address.
DS1302 Specifics
The DS1302 class has four methods to get the lowest and highest RAM addresses, split into read and write:
ramWStart, ramWEnd
for write start and write end, respectivelyramRStart, ramREnd
for read start and read end, respectively
In each loop, the increment statement is i += 2
. Since the addresses alternate between read and write, we have to skip every other one.
RAM byte | Address | Function |
---|---|---|
0 | 0xC0 | Write |
0xC1 | Read | |
1 | 0xC2 | Write |
0xC3 | Read | |
2 | 0xC4 | Write |
0xC5 | Read | |
⋮ |
DS1307 Specifics
The DS1307 class has two methods to get the lowest and highest RAM addresses:
ramStart
for the startramEnd
for the end
All addresses can be written to and read from.
Additional Functions
Halt Bit
When the RTC is halted (determined by the halt bit), its oscillator is disabled and goes into low-power mode. This means that it won't keep track of time until you set it back to normal mode.
The RTC's setHalt
method writes to this halt bit. It takes a Boolean parameter: true
to enable the halt bit, false
to disable.
important:
DS1307 only: The SQW output won't work when the RTC is halted.