Summary

This code shows how to communicate with the RTC DS1307 Real Time Clock, which is used to set and retrieve the date/time of the chip. As a bonus there are some additional bytes of data that can be used as general purpose memory. The main reason for my use of this code is to be able to log events that occur in my applications. I recommend for you to get the RTC DS1307 data sheet to help with understanding what was done here. The bottom line is that I have created this program to accept commands via serial communication with a PC to instruct the Arduino to send or receive data via I2C to the storage registers of the RTC DS1307 chip.

RTC Module Schematic

DS1307 Chip Schematic

I just wanted to make a note on this schematic. I used the voltage divider method to get 3vdc to pin 3, but you can also use a 3vdc battery if you desire. You can also try to change the resistor values so they do not use 100mA as my solution does. I did not know how much current pin 3 required, so I chose low resistor values. I suspect you could use a much higher value and get the same result without using all that current. I left the values as I have used them, because I know it works, but feel free to experiment if you use this method which you would probably want to optimize if you plan on using a battery for your 5vdc source.

Method

If you want to take the easy route, spend the extra bucks and buy a Spark Fun ready to go unit for around $15. However, if you really prefer spending an extra hour or so (In my case 4 hours, but you get the benefit of my labor ;~), then buy a few chips from Digikey or Mouser. I think I spent a couple bucks to pay for the chip and the crystal, I ended up having to use two resistors as well, but those were from my existing inventory. If you go the chip route, just keep in mind that shipping can be significant, so you will want to buy more than just the chip.

The reason I had to use the resistors, was to create a voltage divider to create a voltage on the battery backup pin. As I found out and fortunately you will not endure because you are reading this right now, is that the battery pin must have 2.5-3vdc to operate properly or the chip will stop responding to IC2 requests. Ok, we all know the rule, "When all else fails, READ THE DIRECTIONS". As wisdom will have it, I eventually read this seemingly insignificant information in the Data Sheet. Well if I get the time I will outline all the details on the parts and schematic, but the bottom line is that I was still to cheap to buy a 3v battery, so I just used the voltage divider to drop the 5vdc supply. The absolute most funny part is that the chip does run just fine without the 3vdc...... sometimes. Meaning you think you have it all worked out and then......... sometimes. Hence four hours. But your not going to make that mistake are you? Because you are here. Soooooooo, after all is said and done the chip is very stable and works as expected and is reliable.

Concerning the semi-non-volatile memory on this chip, I have included the ability to initialize and read the memory. Originally I was unable to read/write all the registers, but someone had resolved this issue by understanding the limitation of this chip or I2C, I am not entirely sure. However, the solution was to limit the number of register writes to 32 registers per I2C session. The code now includes this fix and all registers can be written by creating two I2C sessions.

This page does not cover the clock output pin that has several settings for outputting a clock frequency, so I will leave it to the reader to figure that function out, as I have no need for that right now. Another interesting feature on this chip is that the time and memory is maintained as long as you have that battery backup at 2.5-3v. But if the chip goes into backup mode, you will not be able to read or write to any of the registers. One misleading piece of data in the Data Sheet is that the memory is non-volatile, well that is true as long as you have the battery backup power. In my voltage divider method, when the power is gone it is gone-gone, so basically no data is retained, but that is exactly why I made the date/time setting command, because I just reset it from the host software that I use to control the Arduino. Go to Arduino Communications to see how I am communicating with the Arduino.

I2C

Arduino 1.0

The current code examples have been updated to Arduino 1.0. The only difference in these examples is from the wire.h Library. The methods have changed as follows:

Reading Memory - The process is essentially the same as Reading date/time with two small differences

(1) You have to set the register pointer where you want to read the memory.

(2) You have to indicate how many bytes to read.

Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x08);// Set the register pointer to (0x08) to read first memory byte
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS,1);// In this case only read one byte
temp_byte = Wire.read();// Read the desired byte

Writing Data

Write date/time.

Open the I2C communication in write mode.

Set the register pointer to (0x00) - To write the date/time you reset the pointer to the first register.

Writing Memory - The process is essentially the same as writing date/time with two small differences

(1) You have to set the register pointer where you want to write the memory.

(2) Now write the byte value you want in that memory location.

Note: You can continue writing and the register pointer will go to the next memory location. When the pointer reaches the end of the memory it will start back at the beginning, which will overwrite your date/time if you are not careful.

RTC_DS1307_v.01 User Guide

Not much to say here, I tend to use the Arduino in the Arduino Communications Method, so maybe someday I will present the other part of the controlling SW I made for this tool, but I will have to make changes to get it to work correctly for this particular set-up.

For now just enter the commands from the Arduino Environment or your favorite serial communications method.

Example to set the time for 25-Jan-2012 @ 19:57:11 for the 4 day of the week, use this command - T1157194250112

Q1 - This command will initialize all the non date/time memory to 255 (0xff)

I do this because when the RTC DS1307 goes into back up mode it returns 0 for any register, so for memory usage a 0 will be considered a failure to read memory and 255 will be a default value. Meaning it is considered null.