Timer interrupt and DS1307 RTC

Hi,
I would like to interface DS1307 RTC with arduino. actually i want function like,new RTC value every 500ms using timer interrupt program. for DS1307 interface i got information from this link : Hobby Robotics » An I2C Bus Example Using the DS1307 Real-Time Clock and for the timer function <timer1.h> library.
when i am trying to call the getDateDs1307() inside timer interrupt function, the program not executing. I tried with serial print function for each line, but it is on getting out from the getDateDs1307() function. it is not working. but if i call the getDateDs1307() function in loop or setup function it is working correctly.

void setup()
{
  Wire.begin(); // I2C communication begin
  Serial.begin(9600);

  Timer1.initialize(500000);  // initialize the timer as clock period as 500ms.
  Timer1.attachInterrupt(clock,500000); // enable the timer interrupt function
}

and the interrupt code is

void clock()
{
  Timer1.stop();
  getDateDs1307();
  Serial.print(bcdToDec(hour),DEC);
  Serial.print(" : ");
  Serial.print(bcdToDec(min),DEC);    
  Serial.print(" : ");
  Serial.println(bcdToDec(sec),DEC);
  }
  Timer1.start();
}

and rtc value read code is

void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

  second     = (Wire.receive() & 0x7f);
  minute     = (Wire.receive());
  hour       = (Wire.receive() & 0x3f);  

}

I want with timer interrupt function because this is part of my project. any one can you help me.

and the interrupt code is

A little math and you will see that the interrupt handler takes more time to execute than elapses between interrupts.

Your ISR should do nothing more than set a flag indicating that loop() needs to do something next time around. Then, loop() should do all the heavy lifting.

Your premise, though, is confusing.

actually i want function like,new RTC value every 500ms using timer interrupt program.

The Arduino is pretty good at keeping track of time, at least for short intervals. So, syncing the Arduino time with the RTC once a minute should be good enough. Every half second is way more often than is required.

Hi,
I tried with micros() function. the time taken for the function 1040 microseconds. i think and sure the total interrupt function will run within 500 ms.

long mcsec = micros();
  getDateDs1307();
  Serial.println(micros() - mcsec, DEC);

I am using while loop in my main program same time i want the RTC time every second to display in LCD. if any one know how to do. (using interrupt or any other technique.)

I tried with micros() function...the time taken for the function 1040 microseconds.

And what about all that sssslllloooowwww serial output at 9600 baud?

I am using while loop in my main program same time i want the RTC time every second to display in LCD.

What is the while loop doing? It sounds to me like some fundamental changes to the code are required. Post all of your code, if you want help.

Hi,
   I posted full code. this project based on home automation device control. 
    Hardware list:
        1. ds1307
        2. 6x8 keypad matrix.
        3. 20 x 4 lcd display.

           while((data = key()) == 0) - for getting keypad value.


[code]
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <EEPROM.h>
int latchPin = 9;
int clockPin = 10;
int dataPin = 8;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int lat_Pin = A2;
int clk_Pin = A3;
int dat_Pin = A1;

byte switchVar1 = 0; 
int teamA = 100,teamB = 200;

int count = 0,count1 = 0,count2 = 60;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const char keymap[] = {
  'C', '7', '1', 'I', 'O', 'U',
  'D', '8', '2', 'J', 'P', 'V',
  'E', '9', '3', 'K', 'Q', 'W',
  'F', '0', '4', 'L', 'R', 'X',
  'G', 'A', '5', 'M', 'S', 'Y',
  'H', 'B', '6', 'N', 'T', 'Z',
  'z', 'x', 'w', 'a', 's', 'r',
  ' ', 'y', ' ', 'b', 'u', 'd'
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char lcd_data[4][20];

int row_c = 0;
int clo_c = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 13, 11, 5, 4, 3, 7);

#include "TimerOne.h"

int command = 0;   
byte second = 45, minute = 12, hour = 9, dayOfWeek = 6, dayOfMonth = 20, month = 5, year = 11;
byte start = 0,dec = 0;
char data ;

byte clk = 0;
byte clk_old = 0;

long previousMillis = 0; 
long interval = 1000; 
byte secA,secB,minA,minB;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  Wire.begin();
  Serial.begin(9600);

  Timer1.initialize(500000);
  Timer1.attachInterrupt(clock,500000);


  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  pinMode(lat_Pin, OUTPUT);
  pinMode(clk_Pin, OUTPUT);
  pinMode(dat_Pin, INPUT);

  lcd.begin(20, 4); 
  for(int i = 0;i < 4;i++)
  {
    for(int j=0;j< 20;j++)
    {
      lcd_data[i][j] = ' ';
    }
  }

  lcd.clear(); 
  lcd.setCursor(0,0);

  
  long mcsec = micros();
  getDateDs1307();
  Serial.println(micros() - mcsec, DEC);

  lcd_data[0][10]  = (second >> 4) + 48;
  lcd_data[0][11] = (second & 0x0f) + 48;

  lcd_data[0][7] = (minute >> 4) + 48;
  lcd_data[0][8] = (minute & 0x0f) + 48;

  lcd_data[2][2] = ((teamA % 1000) / 100) + 48;
  lcd_data[2][3] = ((teamA % 100) / 10) + 48;
  lcd_data[2][4] = (teamA % 10 ) + 48;

  lcd_data[2][15] = ((teamB % 1000) / 100) + 48;
  lcd_data[2][16] = ((teamB % 100) / 10) + 48;
  lcd_data[2][17] = (teamB % 10 ) + 48;
  

  load_to_lcd_data();


}
void clock()
{
  Timer1.stop();
  getDateDs1307();
  if(second != clk)
  {
    clk = second;
    count1 += 1;
    if(count1 == 60)
      count1 = 0;
    count2 -= 1;  
    if(count2 < 0)
      count2 = 59;
    int count_tmp = decToBcd(count1);
    lcd_data[1][3]  = (count_tmp >> 4) + 48;
    lcd_data[1][4] = (count_tmp & 0x0f) + 48;
    count_tmp = decToBcd(count2);
    lcd_data[1][15] = (count_tmp >> 4) + 48;
    lcd_data[1][16] = (count_tmp & 0x0f) + 48; 

    load_to_lcd_data();

  }
  Timer1.start();
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()

{
main:

  data = key();
    if(data  != 0)
  {

    if(data == 'x')
    {
      for(int j=0;j< 20;j++)
      {
        lcd_data[3][j] = ' ';
      }
      lcd_data[3][1] = 'T';
      lcd_data[3][2] = 'E';
      lcd_data[3][3] = 'A';
      lcd_data[3][4] = 'M';
      lcd_data[3][5] = ' ';
      lcd_data[3][6] = 'A';      
      lcd_data[3][7] = ':';      


      while((data = key()) == 0);
      if(data == 'b')
        goto main;
      if(data == 'w')
        teamA++;
      if(data == 'z')
        teamA--;

      lcd_data[2][2] = ((teamA % 1000) / 100) + 48;
      lcd_data[2][3] = ((teamA % 100) / 10) + 48;
      lcd_data[2][4] = (teamA % 10 ) + 48;

    }
    if(data == 'y')
    {
      for(int j=0;j< 20;j++)
      {
        lcd_data[3][j] = ' ';
      }
      lcd_data[3][1] = 'T';
      lcd_data[3][2] = 'E';
      lcd_data[3][3] = 'A';
      lcd_data[3][4] = 'M';
      lcd_data[3][5] = ' ';
      lcd_data[3][6] = 'B';      
      lcd_data[3][7] = ':'; 



      while((data = key()) == 0);
      if(data == 'b')
        goto main;
      if(data == 'w')
        teamB++;
      if(data == 'z')
        teamB--;

      lcd_data[2][15] = ((teamB % 1000) / 100) + 48;
      lcd_data[2][16] = ((teamB % 100) / 10) + 48;
      lcd_data[2][17] = (teamB % 10 ) + 48;

    }
    //    Serial.print(data);

    if(data == 's')
    {
      for(int j=0;j< 20;j++)
      {
        lcd_data[3][j] = ' ';
      }
      lcd_data[3][0] = 'P';
      lcd_data[3][1] = 'R';
      lcd_data[3][2] = 'E';
      lcd_data[3][3] = 'S';
      lcd_data[3][4] = 'S';
      lcd_data[3][5] = ' ';      
      lcd_data[3][6] = 'N';
      lcd_data[3][7] = '/';
      lcd_data[3][8] = 'T';
      lcd_data[3][9] = ' ';
      lcd_data[3][10] = 'N';
      lcd_data[3][11] = 'A';
      lcd_data[3][12] = 'M';      
      lcd_data[3][13] = '/';
      lcd_data[3][14] = 'T';
      lcd_data[3][15] = 'I';
      lcd_data[3][16] = 'M';      
      lcd_data[3][17] = 'E'; 
      while((data = key()) == 0);
      if(data == 'b')
        goto main;
      if(data == 'N')
      {
        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        if(data == 'A')
        {
          while((data = key()) == 0);
          if(data == 'b')
            goto main;
          lcd_data[0][2] = data;
          while((data = key()) == 0);
          if(data == 'b')
            goto main;
          lcd_data[0][3] = data;
          while((data = key()) == 0);
          if(data == 'b')
            goto main;
          lcd_data[0][4] = data;
        }
        if(data == 'B')
        {
          while((data = key()) == 0);
          if(data == 'b')
            goto main;
          lcd_data[0][15] = data;
          while((data = key()) == 0);
          if(data == 'b')
            goto main;
          lcd_data[0][16] = data;
          while((data = key()) == 0);
          if(data == 'b')
            goto main;
          lcd_data[0][17] = data;
        }
      }
      if(data == 'T')
      {

        for(int j=0;j< 20;j++)
        {
          lcd_data[3][j] = ' ';
        }
        lcd_data[3][0] = 'S';
        lcd_data[3][1] = 'E';
        lcd_data[3][2] = 'T';
        lcd_data[3][3] = ' ';
        lcd_data[3][4] = 'T';
        lcd_data[3][5] = 'I';      
        lcd_data[3][6] = 'M';
        lcd_data[3][7] = 'E';
        lcd_data[3][8] = '=';
        lcd_data[3][11] = ':';
        lcd_data[3][14] = ':';

        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        lcd_data[3][9] = data;
        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        lcd_data[3][10] = data;
        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        lcd_data[3][12] = data; 
        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        lcd_data[3][13] = data;
        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        lcd_data[3][15] = data;
        while((data = key()) == 0);
        if(data == 'b')
          goto main;
        lcd_data[3][16] = data;

        setDateDs1307();
        getDateDs1307();

        lcd_data[0][10]  = (second >> 4) + 48;
        lcd_data[0][11] = (second & 0x0f) + 48;

        lcd_data[0][7] = (minute >> 4) + 48;
        lcd_data[0][8] = (minute & 0x0f) + 48;



      }
    }
  }



  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) 
  {
    getDateDs1307();
    lcd_data[0][10]  = (second >> 4) + 48;
    lcd_data[0][11] = (second & 0x0f) + 48;

    lcd_data[0][7] = (minute >> 4) + 48;
    lcd_data[0][8] = (minute & 0x0f) + 48;

    previousMillis = currentMillis;   
  }


}

remaining code nest..

[/code]

code continue ..

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setDateDs1307()                
{

  second = (byte) ((lcd_data[3][15] - 48) * 10 + (lcd_data[3][16] - 48));
  minute = (byte) ((lcd_data[3][12] - 48) * 10 + (lcd_data[3][13] - 48));
  hour   = (byte) ((lcd_data[3][9] - 48) * 10 + (lcd_data[3][10] - 48));

  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.send(decToBcd(second));    //  Wire.send(decToBcd(second));  
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour)); 
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.endTransmission();  

  Wire.endTransmission();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  second     = (Wire.receive() & 0x7f);
  minute     = (Wire.receive());
  hour       = (Wire.receive() & 0x3f);  

}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////


char key()
{
  char key_value = 0;
  int reles = 0;
  int count = 0;
  while(reles == 0)
  {
    count = 0;
    for (int numberToDisplay = 1; numberToDisplay <= 128; numberToDisplay = numberToDisplay << 1) {
      char data = numberToDisplay;
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, numberToDisplay);    
      digitalWrite(latchPin, HIGH);

      digitalWrite(lat_Pin,HIGH);
      digitalWrite(lat_Pin,LOW);
      switchVar1 = shiftIn(dat_Pin, clk_Pin);
      if(switchVar1 == 0){
        count++;
        if(count == 8)
          reles = 1;
      }
      else
      {
        key_value  = key_find(numberToDisplay,switchVar1); 
      }
    }
  }
  return key_value ;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    //    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);

  }
  return myDataIn;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char key_find (int row,int coloumn)
{
  char char_decode = 0;
  char row_decode = 0;
  char coloumn_decode = 0;
  switch(row){
  case 1 :
    row_decode = 0;
    break;      
  case 2 : 
    row_decode = 6;
    break;  
  case 4 : 
    row_decode = 12;
    break;   
  case 8 : 
    row_decode = 18;
    break;   
  case 16 : 
    row_decode = 24;
    break;  
  case 32 : 
    row_decode = 30;
    break;  
  case 64 : 
    row_decode = 36;
    break;  
  case 128 : 
    row_decode = 42;
    break;  
  }
  switch (coloumn){
  case 4:
    coloumn_decode = 0;
    break;
  case 8:
    coloumn_decode = 1;
    break;
  case 16:
    coloumn_decode = 2;
    break;
  case 32:
    coloumn_decode = 3;
    break;
  case 64:
    coloumn_decode = 4;
    break;
  case 128:
    coloumn_decode = 5;
    break;
  }
  char_decode = keymap[row_decode + coloumn_decode];
  return char_decode;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void load_to_lcd_data()
{

  for(int i = 0;i < 4;i++)
  {
    for(int j=0;j< 20;j++)
    {
      lcd.print(lcd_data[i][j]);
    }
  }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

please help me.. thank you.

please help me

Go through your spaghetti code, and get rid of main: and all goto statements. They are the source of your problem.

If you have a blocking activity, like waiting for a keypress:

      while((data = key()) == 0);

you can change it.

      while((data = key()) == 0)
      {
        // If it's time to update the display,
           // Update the display
      }

The DS1307 has a 1 second pulse output. You could use that as a hardware interrupt, on every rising edge and falling edge (is there a change setting also?) you could have an interrupt and do whatever it is you're doing.

Hi,
thank you very much..
I added RTC reading function inside the while loop. now it is working fine. thank you very much.