Portugal
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« on: January 02, 2012, 11:24:01 am » |
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? // 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
Faraday Member
Karma: 19
Posts: 3117
|
 |
« Reply #1 on: January 02, 2012, 11:47:50 am » |
The datasheet for the DS1307 is here - http://www.maxim-ic.com/datasheet/index.mvp/id/2688Basically, the answer to your questions is yes. 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
Faraday Member
Karma: 47
Posts: 2575
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #2 on: January 02, 2012, 11:50:00 am » |
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
|
|
|
|
|
Portugal
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #3 on: January 02, 2012, 12:05:19 pm » |
Thank you so much for your help!!  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
|
|
|
|
|
Logged
|
|
|
|
|
Gosport, UK
Offline
Faraday Member
Karma: 19
Posts: 3117
|
 |
« Reply #4 on: January 02, 2012, 12:13:45 pm » |
After each button press, you'll need to construct a DateTime value, then call RTC.adjust().
|
|
|
|
|
Logged
|
|
|
|
|
Portugal
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #5 on: January 02, 2012, 06:54:09 pm » |
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  Now, I have two more questions - sorry  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
Brattain Member
Karma: 336
Posts: 36476
Seattle, WA USA
|
 |
« Reply #6 on: January 02, 2012, 06:57:36 pm » |
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. 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. 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
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #7 on: January 03, 2012, 05:23:32 am » |
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. 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. 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! 
|
|
|
|
|
Logged
|
|
|
|
|
Portugal
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #8 on: January 04, 2012, 06:31:20 am » |
Step by step I am getting the clock/calendar working smoothly  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  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 
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 336
Posts: 36476
Seattle, WA USA
|
 |
« Reply #9 on: January 04, 2012, 06:49:49 am » |
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
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #10 on: January 04, 2012, 07:42:00 am » |
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: // 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
Brattain Member
Karma: 336
Posts: 36476
Seattle, WA USA
|
 |
« Reply #11 on: January 04, 2012, 08:03:04 am » |
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. 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
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #12 on: January 04, 2012, 09:44:40 am » |
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  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  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  Thanks for the tip
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 336
Posts: 36476
Seattle, WA USA
|
 |
« Reply #13 on: January 04, 2012, 09:47:36 am » |
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
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #14 on: January 04, 2012, 09:58:51 am » |
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.  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: (...) double var;
var=1100/1088;
printf(%f, var); (...)
What do I get on my screen? 
|
|
|
|
« Last Edit: January 04, 2012, 10:16:43 am by KenshinPT »
|
Logged
|
|
|
|
|
|