Pages: [1] 2   Go Down
Author Topic: DS1307 RTC help :)  (Read 1665 times)
0 Members and 1 Guest are viewing this topic.
Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys!

I have my LCD clock and sensor temperature working fine.

However, I don't know how the DS1307 RTC really works, so I have a couples questions:

1 - If I increase the day by one, does the weekday also increases by one?

2 - Does this RTC knows when a month has 28/29/30/31 days?

3 - Does the RTC knows when the year is leap (bissextile).

4 - Finally, if all the above are true, do I need to add anything else on my code so it works like a real calendar/clock?

Regarding the manual setup up of the clock... How can I do it? I am thinking in 2 pushbuttons but how do I code it?

Code:
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include <LiquidCrystal.h>
#include "RTClib.h"

RTC_DS1307 RTC;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte graus[8] = {
  0b01110,
  0b10001,
  0b10001,
  0b01110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

int pin=0; // analog pin
long int temp=0, Vin=0, k=0;
long double samples[20];
long double min = (-424.0/6.25);


void setup ()
{
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  lcd.begin(16, 2);  
  lcd.createChar(0, graus);
  analogReference(INTERNAL);

  if (! RTC.isrunning())
  {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }  
  
}


void loop () {
  DateTime now = RTC.now();
  lcd.home();    

  if (now.hour() < 10)
  {
    lcd.print('0');
    lcd.print(now.hour(), DEC);
    lcd.print(':');
  }
  else
  {
    lcd.print(now.hour(), DEC);
    lcd.print(':');
  }

  if (now.minute() < 10)
  {
    lcd.print('0');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
  }
  else
  {
    lcd.print(now.minute(), DEC);
    lcd.print(':');
  }

  if (now.second() < 10)
  {
    lcd.print('0');
    lcd.print(now.second(), DEC);
  }  
  else {
    lcd.print(now.second(), DEC);
  }


  lcd.setCursor(0,1);

  if (now.day() < 10)
  {
    lcd.print('0');
    lcd.print(now.day(), DEC);
    lcd.print('/');
  }
  else
  {
    lcd.print(now.day(), DEC);
    lcd.print('/');
  }

  if (now.month() < 10)
  {
    lcd.print('0');
    lcd.print(now.month(), DEC);
    lcd.print('/');
  }
  else
  {
    lcd.print(now.month(), DEC);
    lcd.print('/');
  }

  lcd.print(now.year(), DEC);

  lcd.setCursor(12, 1);
  if (now.dayOfWeek() == 0)
    lcd.print("Sun");

  if (now.dayOfWeek() == 1)
    lcd.print("Mon");  

  if (now.dayOfWeek() == 2)
    lcd.print("Tue");

  if (now.dayOfWeek() == 3)
    lcd.print("Wed");

  if (now.dayOfWeek() == 4)
    lcd.print("Thu");

  if (now.dayOfWeek() == 5)
    lcd.print("Fri");

  if (now.dayOfWeek() == 6)
    lcd.print("Sat");


  for(k=0 ; k<=19 ; k++)
  {
    samples[k] = (analogRead(pin)*(1100/1088));
    Vin = Vin + samples[k];
    delay(2);
  }

  temp = (Vin/20 /1024.0 * 1088.0 / 6.25) + min;

  if (temp >=0 & temp <=9)
  {
    lcd.setCursor(11, 0);
    lcd.print("  ");
    lcd.print(temp, DEC);    
  }

  if (temp >=10 & temp <=99)
  {
    lcd.setCursor(11, 0);
    lcd.print(" ");
    lcd.print(temp, DEC);
  }

  if (temp >=100 & temp <=150)
  {
    lcd.setCursor(11, 0);
    lcd.print(temp, DEC);
  }

  if (temp >=-9 & temp <=-1)
  {
    lcd.setCursor(11, 0);
    lcd.print(" ");
    lcd.print(temp, DEC);
  }

  if (temp >=-99 & temp <=-10)
  {
    lcd.setCursor(11, 0);
    lcd.print(temp, DEC);
  }

  lcd.setCursor(14, 0);
  lcd.write((uint8_t)0);
  lcd.print("C");

 
  Vin=0;
  temp = 0;
  k=0;

  delay(200);
  
}
« Last Edit: January 02, 2012, 11:25:52 am by KenshinPT » Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The datasheet for the DS1307 is here - http://www.maxim-ic.com/datasheet/index.mvp/id/2688

Basically, the answer to your questions is yes.

Quote
Real-Time Clock (RTC) Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of the week, and Year with Leap-Year Compensation Valid Up to 2100
Logged

Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 93
Posts: 3968
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1 - If I increase the day by one, does the weekday also increases by one?

2 - Does this RTC knows when a month has 28/29/30/31 days?

3 - Does the RTC knows when the year is leap (bissextile).

4 - Finally, if all the above are true, do I need to add anything else on my code so it works like a real calendar/clock?

Regarding the manual setup up of the clock... How can I do it? I am thinking in 2 pushbuttons but how do I code it?

1-Yes, 2-Yes, 3-Yes. 4-Depends on how you want it to work. Turns out that setting the time may be the tougher part, IMHO! I might start with more than two buttons. It's worth it to first write down and maybe draw some pictures of how the buttons would work. Consider, both the time and the date (including the year) need to be set. If it's an alarm clock, another button or two may be needed.
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you so much for your help!! smiley

Regarding the manual set-up, I think I know how to do it... but the problem is that I don't know which variable I should increment?

I tried:

if (button is pressed)
{
 debounce();
 now.day++;
}

But this wont work... I think the problem relies on the variable to change: seconds, minutes, days...

Thanks you so much for your help

Happy new year 2012 of coding smiley-razz
 
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After each button press, you'll need to construct a DateTime value, then call RTC.adjust().
Logged

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After each button press, you'll need to construct a DateTime value, then call RTC.adjust().

Great! I got it and it's working. Thanks smiley

Now, I have two more questions - sorry smiley

1 a)- When I do this: ABCD%1000 the result is always CD, right? I am asking this because I don't won't to display 4 digits of the year. I just want the last 2 digits.

1 b) However, when the year is 2100, the result is 100, right? Is there any efficient way to solve this problem? That is, when year is 2100, the result should be 00.

2 - When I set up manually the date I can have like 62 minutes or 75 seconds or 25 hours... I thought the RCT was smarter. Does this mean that I have do code something to roll over when the hour digit reachs 23 and rolls to 00.
Logged

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

Quote
When I do this: ABCD%1000 the result is always CD, right?
Wrong. The result is always BCD. If you change 1000 to 100, the result will be CD.

Quote
However, when the year is 2100, the result, 100, right? Is there any efficient way to solve this problem? That is, when year is 2100, the result should be 00.
Sure. See above.

Quote
Does this mean that I have do code something to roll over when the hour digit reachs 23 and rolls to 00.
The answer to that seems pretty obvious, doesn't it?
Logged

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
When I do this: ABCD%1000 the result is always CD, right?
Wrong. The result is always BCD. If you change 1000 to 100, the result will be CD.

Quote
However, when the year is 2100, the result, 100, right? Is there any efficient way to solve this problem? That is, when year is 2100, the result should be 00.
Sure. See above.

Quote
Does this mean that I have do code something to roll over when the hour digit reachs 23 and rolls to 00.
The answer to that seems pretty obvious, doesn't it?

Thanks! smiley
Logged

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Step by step I am getting the clock/calendar working smoothly smiley

However, I found something that must be solved:

When I try to set any of the clock/date parameters the clock freezes... that is, if I press the pushbuttom to set the year for 5 seconds, after releasing it, the clock has stopped for 5 seconds  smiley-eek-blue

Code:
if (digitalRead(buttonPin) == 1)
  {
    {
      RTC.adjust(DateTime(now.year()+1,now.month(),now.day(),now.hour(),now.minute(),now.second()));
    }
  }

}

After solving this problem I'll add a debounce for the pushbuttom  smiley-mr-green
Logged

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

Quote
After solving this problem I'll add a debounce for the pushbuttom
No, you've got the steps in the wrong order. Stop the button from bouncing, and you may not have the other problem.

Post all of your code, too. It's impossible to tell what you are doing wrong with just that snippet.
Logged

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
After solving this problem I'll add a debounce for the pushbuttom
No, you've got the steps in the wrong order. Stop the button from bouncing, and you may not have the other problem.

Post all of your code, too. It's impossible to tell what you are doing wrong with just that snippet.

Hey, thanks for the help.

The code is here:

Code:
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include <LiquidCrystal.h>
#include "RTClib.h"

RTC_DS1307 RTC;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte graus[8] = {
  0b01110,
  0b10001,
  0b10001,
  0b01110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

int pin=0; // analog pin
long int temp=0, Vin=0, k=0;
long double samples[20];
long double min = (-424.0/6.25);

const int buttonPin = 10;     // the number of the pushbutton pin

void setup ()
{
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  lcd.begin(16, 2);   
  lcd.createChar(0, graus);
  analogReference(INTERNAL);

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT); 

  if (! RTC.isrunning())
  {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  } 

}

void loop () {
  DateTime now = RTC.now();
  lcd.home();   

//Print time on LCD
  if (now.hour() < 10)
  {
    lcd.print('0');
    lcd.print(now.hour(), DEC);
    lcd.print(':');
  }
  else
  {
    lcd.print(now.hour(), DEC);
    lcd.print(':');
  }

  if (now.minute() < 10)
  {
    lcd.print('0');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
  }
  else
  {
    lcd.print(now.minute(), DEC);
    lcd.print(':');
  }

  if (now.second() < 10)
  {
    lcd.print('0');
    lcd.print(now.second(), DEC);
  } 
  else {
    lcd.print(now.second(), DEC);
  }


//Print date on LCD
  lcd.setCursor(0,1);

  if (now.day() < 10)
  {
    lcd.print('0');
    lcd.print(now.day(), DEC);
    lcd.print('/');
  }
  else
  {
    lcd.print(now.day(), DEC);
    lcd.print('/');
  }


  switch(now.month())
  {
    case 1:lcd.print("Jan/"); break;     
    case 2:lcd.print("Feb/"); break;
    case 3:lcd.print("Mar/"); break;
    case 4:lcd.print("Apr/"); break;
    case 5:lcd.print("May/"); break;
    case 6:lcd.print("Jun/"); break;
    case 7:lcd.print("Jul/"); break;
    case 8:lcd.print("Aug/"); break;     
    case 9:lcd.print("Sep/"); break;
    case 10:lcd.print("Oct/"); break;
    case 11:lcd.print("Nov/"); break;
    case 12:lcd.print("Dec/"); break;
    default:lcd.print("Err/");
  }

  lcd.print(now.year(), DEC);
 
//Print weekday on LCD
  lcd.setCursor(13, 1);
  switch(now.dayOfWeek())
  {
    case 0:lcd.print("Sun"); break;     
    case 1:lcd.print("Mon"); break;
    case 2:lcd.print("Tue"); break;
    case 3:lcd.print("Wed"); break;
    case 4:lcd.print("Thu"); break;
    case 5:lcd.print("Fri"); break;
    case 6:lcd.print("Sat"); break;
    default:lcd.print("Err");
  }

  for(k=0 ; k<=19 ; k++)
  {
    samples[k] = (analogRead(pin)*(1100/1088));
    Vin = Vin + samples[k];
    delay(2);
  }

  temp = (Vin/20 /1024.0 * 1088.0 / 6.25) + min;

  if (temp >=0 & temp <=9)
  {
    lcd.setCursor(11, 0);
    lcd.print("  ");
    lcd.print(temp, DEC);   
  }

  if (temp >=10 & temp <=99)
  {
    lcd.setCursor(11, 0);
    lcd.print(" ");
    lcd.print(temp, DEC);
  }

  if (temp >=100 & temp <=150)
  {
    lcd.setCursor(11, 0);
    lcd.print(temp, DEC);
  }

  if (temp >=-9 & temp <=-1)
  {
    lcd.setCursor(11, 0);
    lcd.print(" ");
    lcd.print(temp, DEC);
  }

  if (temp >=-99 & temp <=-10)
  {
    lcd.setCursor(11, 0);
    lcd.print(temp, DEC);
  }

  lcd.setCursor(14, 0);
  lcd.write((uint8_t)0);
  lcd.print("C");

  Vin=0;
  temp = 0;
  k=0;

  delay(250);

  if (digitalRead(buttonPin) == 1)
  {
    {
      RTC.adjust(DateTime(now.year(),now.month()+1,now.day(),now.hour(),now.minute(),now.second()));
    }
  }

}
Logged

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

Code:
    samples[k] = (analogRead(pin)*(1100/1088));
1100/1088 = 1. Is this necessary? 1100.0/1088.0 (= 1.011) might be.

Why are you storing an array of doubles, when the array is never used again? Why are you storing ints in a double array?

Putting the code to show the time and date in a function would greatly shorten loop(), to make it easier to follow.

Code:
  delay(250);

  if (digitalRead(buttonPin) == 1)
  {
    {
      RTC.adjust(DateTime(now.year(),now.month()+1,now.day(),now.hour(),now.minute(),now.second()));
    }
  }
Every 1/4 of a second (plus the time it takes to do all the other stuff in loop), you see if it is necessary to update the month, and, if it is, set the time 1/4 of a second (plus) late. Why? now was a snapshot of the time at the start of loop(). You should get the current time again, just before adjusting it.
Logged

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    samples[k] = (analogRead(pin)*(1100/1088));
1100/1088 = 1. Is this necessary? 1100.0/1088.0 (= 1.011) might be.
It's a correction factor for the thermometer. My Vref is 1088mV and not 1100mV. Is this the right thing to do?

Why are you storing an array of doubles, when the array is never used again? Why are you storing ints in a double array?
It was once used but then I changed the code and I forgot to change de declaration of "samples" variable. So, you're right smiley

Putting the code to show the time and date in a function would greatly shorten loop(), to make it easier to follow.
I'll do that for sure. This is in version Beta 0.1 smiley-razz

Code:
  delay(250);

  if (digitalRead(buttonPin) == 1)
  {
    {
      RTC.adjust(DateTime(now.year(),now.month()+1,now.day(),now.hour(),now.minute(),now.second()));
    }
  }
Every 1/4 of a second (plus the time it takes to do all the other stuff in loop), you see if it is necessary to update the month, and, if it is, set the time 1/4 of a second (plus) late. Why? now was a snapshot of the time at the start of loop(). You should get the current time again, just before adjusting it.
Got it smiley Thanks for the tip
Logged

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

Quote
It's a correction factor for the thermometer. My Vref is 1088mV and not 1100mV. Is this the right thing to do?
A correction factor of (1100/1088 =) 1 seems useless. A correction factor of 1100.0/1088.0 (= 1.011) might be.
Logged

Portugal
Offline Offline
Jr. Member
**
Karma: 0
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It's a correction factor for the thermometer. My Vref is 1088mV and not 1100mV. Is this the right thing to do?
A correction factor of (1100/1088 =) 1 seems useless. A correction factor of 1100.0/1088.0 (= 1.011) might be.

 smiley-eek-blue Thanks! I totally forgot the floating point!!!

Is this particular to arduino IDE? I believe, and hope:), that when I do 1100/1088 in others C IDE/compilers the result is 1.011029411... or not?

for example:

Code:
(...)
double var;

var=1100/1088;

printf(%f, var);
(...)

What do I get on my screen?  smiley-roll
« Last Edit: January 04, 2012, 10:16:43 am by KenshinPT » Logged

Pages: [1] 2   Go Up
Jump to: