Poll
Question: how to read rtc value every 500ms using timer1 interrupt?
how to call rtc data read function in interrupt function - 0 (0%)
ds1307 and timer interrupt - 1 (100%)
Total Voters: 1

Pages: [1]   Go Down
Author Topic: Timer interrupt and DS1307 RTC  (Read 2090 times)
0 Members and 1 Guest are viewing this topic.
bangalore, india
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Know thyself it is supreme Knowledge
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 : http://www.glacialwanderer.com/hobbyrobotics/?p=12 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.

Code:
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
Code:
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
Code:
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.

    
        
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Quote
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.
Logged

bangalore, india
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Know thyself it is supreme Knowledge
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
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.)
« Last Edit: August 24, 2011, 08:57:20 am by sjkr06 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I tried with micros() function...the time taken for the function 1040 microseconds.
And what about all that sssslllloooowwww serial output at 9600 baud?

Quote
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.
Logged

bangalore, india
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Know thyself it is supreme Knowledge
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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]
« Last Edit: August 24, 2011, 09:15:17 am by sjkr06 » Logged

bangalore, india
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Know thyself it is supreme Knowledge
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

code continue ..

Code:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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.
« Last Edit: August 24, 2011, 09:15:58 am by sjkr06 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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:
Code:
      while((data = key()) == 0);
you can change it.
Code:
      while((data = key()) == 0)
      {
        // If it's time to update the display,
           // Update the display
      }
Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 514
Posts: 26259
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

bangalore, india
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Know thyself it is supreme Knowledge
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to:  

Powered by SMF 1.1.19 | SMF © 2013, Simple Machines