Friday, March 6, 2015

Arduino Real Time Clock Using DS1307

Interfacing Arduino with DS1307 real time clock

This topic shows how to interface Arduino with DS1307 real time clock to make a clock and calender.
To understand the project and code easily you have to read the datasheet of the DS1307.
DS1307 Pin assignment:
The picture is taken from ds1307 datasheet and it shows the pin assignment of our chip RTC:

Arduino real time clock using DS1307 circuit:

arduino real time clock ds1307 button arduino code

On the circuit schematic there are two buttons used to set the time and date.
The LCD display shows both time and date at the same time, and the LED connected to the ds1307 toggles on and off (can be programmed on the software).
The I2C bus needs pullup resistors to run that why I used the 10K as a pullup resistors.
Arduino real time clock using DS1307 code: 
We have to follow the table shown below write/read date to/from ds1307:
Arduino real time clock using ds1307 buttons

To write data to the ds1307RTC you have to follow these steps:
1 - Start I2C protocol,
2 - Send the DS1307 address which is in binary 11010000 (0x68),
3 - Send register address according to the below table (for example hour register is 0x02),
4 - Write register value,
5 - Stop the I2C protocol. 
Writing data to ds1307 Arduino code:

  Wire.beginTransmission(0x68);//Start I2C with device #0x68
  Wire.write(address); // Set the register pointer to (address) 
  Wire.write(data_);  //Write (data_) to register #(address)
  Wire.endTransmission(); //Stop I2C protocol


To read data from ds1307 you have to do the following:
1 - Start I2C protocol,
2 - Send the DS1307 address which is in binary 11010000,
3 - Send register address,
3 - Stop I2C protocol,
4 - Start I2C protocol in read mode.
Reading data from ds1307 RTC Arduino code:

  Wire.beginTransmission(0x68);//Start I2C with device #0x68
  Wire.write(0x00);// Set the register pointer to (0x00)
  Wire.endTransmission();//Stop I2C protocol
  Wire.requestFrom(0x68, 7);//Start I2C in read mode
     second = Wire.read(); //Read seconds
     minute = Wire.read(); //Read minutes
     hour = Wire.read();   //Read hours
     day = Wire.read();    //Read day
     date = Wire.read();   //Read date
     month = Wire.read();  //Read month
     year = Wire.read();   //Read year

 Arduino real time clock using DS1307 code:
The following code is the full code of our application you can easily adjust time and calender using two buttons one connected to pin 8 and the other button connected to pin 9 of the Arduino uno board.
The following picture is taken from my project:

Arduino real time clock using ds1307 buttons
 // Real Time Clock Using DS1307
 // Arduino UNO board used
 // Written by: BENCHEROUDA Okba
 // http://elecnote.blogspot.com
 // E-mail: electronnote@gmail.com
 // Use at your own risk !

#include <LiquidCrystal.h>
#include <Wire.h>
 char *text;
 unsigned char second, second10, minute, minute10, hour, hour10,
               day, date, date10, month, month10, year, year10,
               i = 0;
 LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
 void setup() {
 lcd.begin(16, 2);
 Wire.begin();
 pinMode(8, INPUT_PULLUP); // Button 1
 pinMode(9, INPUT_PULLUP); // Button 2
 }
 // Display data
 void display_(){
 second10 = (second & 0x70) >> 4;
     second = second & 0x0F;
     minute10  =  (minute & 0x70) >> 4;
     minute = minute & 0x0F;
     hour10  =  (hour & 0x30) >> 4;
     hour = hour & 0x0F;
     day = day & 0x07;
     date10  =  (date & 0x30) >> 4;
     date = date & 0x0F;
     month10  =  (month & 0x10) >> 4;
     month = month & 0x0F;
     year10  =  (year & 0xF0) >> 4;
     year = year & 0x0F;
     switch(day){
       case 1: text = "Sun"; break;
       case 2: text = "Mon"; break;
       case 3: text = "Tue"; break;
       case 4: text = "Wed"; break;
       case 5: text = "Thu"; break;
       case 6: text = "Fri"; break;
       case 7: text = "Sat"; break;}
     lcd.setCursor(0, 0); lcd.print(text);
     lcd.setCursor(6, 0); lcd.print(date);
     lcd.setCursor(5, 0); lcd.print(date10);
     lcd.setCursor(9, 0); lcd.print(month);
     lcd.setCursor(8, 0); lcd.print(month10);
     lcd.setCursor(14, 0); lcd.print(year);
     lcd.setCursor(13, 0); lcd.print(year10);
     lcd.setCursor(13, 1); lcd.print(second);
     lcd.setCursor(12, 1); lcd.print(second10);
     lcd.setCursor(10, 1); lcd.print(minute);
     lcd.setCursor(9, 1); lcd.print(minute10);
     lcd.setCursor(7, 1); lcd.print(hour);
     lcd.setCursor(6, 1); lcd.print(hour10);  
 }
 // End display data
 // Write data
 void write_value(char address, char data_){
  Wire.beginTransmission(0x68);
  Wire.write(address);
  Wire.write(data_);
  Wire.endTransmission();}
  // End write data
 void loop() {   //Main loop
     write_value( 7 , 0x10);  //Set SQWE frequency at 1Hz
     return_:
     lcd.clear();
     lcd.setCursor(7, 0); lcd.print("/  /20");
     lcd.setCursor(8, 1); lcd.print(":  :");
     while(1){
     if (digitalRead(8) == 0)
     i++;
     if (i == 1){
     write_value( 0 , 0x80);//Stop oscillator and reset seconds
     lcd.clear();
     lcd.setCursor(4, 0); lcd.print("Minutes:");
     minute = minute + minute10 * 10;
     delay(500);
     while(1){
     if (digitalRead(8) == 0){ delay(500);
     i++;}
     if(i != 1){
     minute = ((minute/10) << 4) + (minute % 10);
     write_value( 1 , minute);
     goto return_;}
     if (digitalRead(9) == 0) minute++; delay(200);
     if (minute > 59) minute = 0;
     lcd.setCursor(7, 1); lcd.print(minute / 10);
     lcd.setCursor(8, 1); lcd.print(minute % 10);}}
     if (i == 2){
     lcd.clear();
     lcd.setCursor(5, 0); lcd.print("Hours:");
     hour = hour + hour10 * 10;
     delay(500);
     while(1){
     if (digitalRead(8) == 0){ delay(500);
     i++; }
     if(i != 2){
     hour = ((hour/10) << 4) + (hour % 10);
     write_value( 2 , hour);
     goto return_;}
     if (digitalRead(9) == 0) hour++; delay(200);
     if (hour > 23) hour = 0;
     lcd.setCursor(7, 1); lcd.print(hour / 10);
     lcd.setCursor(8, 1); lcd.print(hour % 10);}}
     if (i == 3){
     lcd.clear();
     lcd.setCursor(6, 0); lcd.print("Day:");
     delay(500);
     while(1){
     if (digitalRead(8) == 0){delay(500);
     i++ ; } 
     if(i != 3){
     write_value( 3 , day);
     goto return_;}
     if (digitalRead(9) == 0) day++; delay(200);
     if (day > 7) day = 1;
     switch(day){
       case 1: text = "Sunday   "; break;
       case 2: text = "Monday   "; break;
       case 3: text = "Tuesday  "; break;
       case 4: text = "Wednesday"; break;
       case 5: text = "Thursday "; break;
       case 6: text = "Friday   "; break;
       case 7: text = "Saturday "; break;}
     lcd.setCursor(4, 1); lcd.print(text);
     }}
     if (i == 4){
     lcd.clear();
     lcd.setCursor(6, 0); lcd.print("Date:");
     date = date + date10 * 10;
     delay(500);
     while(1){
     if (digitalRead(8) == 0){ delay(500);
     i++ ; }
     if(i != 4){
     date = ((date/10) << 4) + (date % 10);
     write_value( 4 , date);
     goto return_;}
     if (digitalRead(9) == 0) date++ ; delay(200);
     if (date > 31) date = 1;
     lcd.setCursor(7, 1); lcd.print(date/10);
     lcd.setCursor(8, 1); lcd.print(date%10);}}
     if (i == 5){
     lcd.clear();
     lcd.setCursor(5, 0); lcd.print("Month:");
     month = month + month10 * 10;
     delay(500);
     while(1){
     if (digitalRead(8) == 0){delay(500);
     i++ ; }
     if(i != 5){
     month = ((month/10) << 4) + (month % 10);
     write_value( 5 , month);
     goto return_;}
     if (digitalRead(9) == 0) month++ ; delay(200);
     if (month > 12) month = 1;
     lcd.setCursor(7, 1); lcd.print(month / 10);
     lcd.setCursor(8, 1); lcd.print(month % 10); }}
     if (i == 6){
     lcd.clear();
     lcd.setCursor(6, 0); lcd.print("Year:");
     year = year + year10 * 10;
     delay(500);
     while(1){
     if (digitalRead(8) == 0){delay(500);
     i = 0;}
     if(i != 6){
     year = ((year/10) << 4) + (year % 10);
     write_value( 0 , 0); //Start oscillator and reset seconds
     write_value( 6 , year);
     goto return_;}
     if (digitalRead(9) == 0) year++; delay(200);
     if (year > 99) year = 0;
     lcd.setCursor(6, 1); lcd.print("20");
     lcd.setCursor(8, 1); lcd.print(year / 10);
     lcd.setCursor(9, 1); lcd.print(year % 10);}}
     // Read data
     Wire.beginTransmission(0x68);
     Wire.write(0x00);
     Wire.endTransmission();
     Wire.requestFrom(0x68, 7); 
     second = Wire.read();
     minute = Wire.read();
     hour = Wire.read();
     day = Wire.read();
     date = Wire.read();
     month = Wire.read();
     year = Wire.read();
     // End read data
     display_();  // Display data
     }   
 }  // End of program


Arduino real time clock using DS1307 video: