Pages: [1]   Go Down
Author Topic: countdown clock  (Read 3189 times)
0 Members and 1 Guest are viewing this topic.
Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,
New to the forum, first post. I am trying to create a countdown clock for a friend who is retiring.  I have a Arduino uno, Adafruit data logger, Adafruit rgb shield with a 2x16 - rgb lcd. I've been able to get the date and time to display but don't have any idea how to compare the retirement date with the datetime now.  The retirement date is april 30 2014 at 10pm and I want to display days, hours,
and minutes left. Sounds simple.
thanks

here is what I have so far.
Code:
//  RetirementClock.ino


#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// #defines the backlight color
#define BLUE 0x4

RTC_DS1307 RTC;

void setup () {
  Wire.begin();
    RTC.begin(); 
      Serial.begin(9600);
   
   
   // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  lcd.setBacklight(BLUE);
  lcd.setCursor(0, 0);
   
 
}

void loop () {
 String temp;
 String thischar;
  DateTime now = RTC.now();
    lcd.setCursor(0, 0);
    //make sure to display two digits wide
     if (now.month() <10) {
    temp.concat("0");
    temp.concat(now.month());
    lcd.print(temp);
  }
  else{
    lcd.print(now.month(), DEC);
  } 
  lcd.print('/');
  temp = "";
  //make sure to display two digits wide
  if (now.day() <10) {
    temp.concat("0");
    temp.concat(now.day());
    lcd.print(temp);
  }
  else{
  lcd.print(now.day(), DEC);
  }
  lcd.print('/');
  temp = "";
  //make sure to display two digits wide
  thischar.concat(now.year());
  temp.concat(thischar.charAt(2));
  temp.concat(thischar.charAt(3));
  lcd.print(temp);
 
 
    lcd.setCursor(0, 1);
     temp = "";
  //make sure to display two digits wide
  if (now.hour() <10) {
    temp.concat("0");
    temp.concat(now.hour());
    lcd.print(temp);
  }
  else{
  lcd.print(now.hour(), DEC);
  }
  lcd.print(":");
  temp = "";
  //make sure to display two digits wide
  if (now.minute() <10) {
    temp.concat("0");
    temp.concat(now.minute());
    lcd.print(temp);
  }
  else{
  lcd.print(now.minute(), DEC);
  }
  lcd.print(":");
  temp = "";
  //make sure to display two digits wide
  if (now.second() <10) {
    temp.concat("0");
    temp.concat(now.second());
    lcd.print(temp);
  }
  else{
  lcd.print(now.second(), DEC);
  }
     
    delay(1000);
 }
 
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49392
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There is a Time library that allows you to create time objects with arbitrary dates and time. Use that to create a retirementDate object. It has functions to compute the minutes, hours, days, etc. to another time (now.minutesToTime_t(retirementDate), for example).
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the tip. I'll post the code once I figure out how to create an object.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49392
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
once I figure out how to create an object.
Once you download the library, and install it in the libraries folder in your sketchbook (create it if it does not exist), and restart the IDE, all you need is:
Code:
Time retirementDate(/* the date and time info goes here */);
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok I see what you mean, but in what format does the date and time have to be in.
Maybe something like this.

 
Code:
Time retirementDate(04/30/2014, 22:00:00);

Or does it need to be in unixtime?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49392
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
but in what format does the date and time have to be in.
What did you see when you looked in the library? There are examples, you know.
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok this looks like what am looking for.

Code:
time_t now();              // return the current time as seconds since Jan 1 1970
void    setTime(time_t t);
void    setTime(int hr,int min,int sec,int day, int month, int yr);
void    adjustTime(long adjustment);

So the format is (hr,min,sec,day,month,yr).

Code:
/* Useful Macros for converting elapsed time to a time_t */
#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN) 
#define hoursToTime_t   ((H)) ( (H) * SECS_PER_HOUR) 
#define daysToTime_t    ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
#define weeksToTime_t   ((W)) ( (W) * SECS_PER_WEEK) 

Now the macros that I think I should use are the daysToTime_t,  hoursToTime_t and minutesToTime_t. But I am still a little confused as to what this macro is doing and how. Objects are the hardest thing to learn in C++.
The first D in  daysToTime_t  would be now() and the second retiremenDate() this doesn't look right the second D looks like it's asking for the number of days * sec per day but that is not what I want. I want to give it the date and it return the days left. What am I missing here.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49392
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But I am still a little confused as to what this macro is doing and how. Objects are the hardest thing to learn in C++.
Objects and macros are completely unrelated.

If you think objects are hard, you've obviously never learned about pointers.

It is not necessary to know how code works in order to be able to use it.

The macros are not determining the difference between two days/hours/mins/weeks. They are converting a number of days to a time_t format, or the number of minutes to a time_t format.

There is a makeTime() method, at the bottom of the class. Create an instance of the TimeElements structure. Set the date and time members. Then, pass that instance to makeTime() to get a time_t variable.

The difference between two time_t variables (which is also what now() returns) is a matter of subtraction, giving a difference in seconds.

The numberOfHours, numberOfMinutes, and numberOfSeconds macros are then useful for converting the time_t difference to hours, minutes, and seconds.
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It is not necessary to know how code works in order to be able to use it.

That's me I am the greatest copy and paste artist ever. I try to learn from guys like yourself that know what their doing by trying snip-its of code and seeing what it does. Thanks for the help. I'll keep trying.
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I finally was able to get the dates left between two dates and here's the code.

Code:
/*
 * RetirementClock.ino
 * countdown the days, hours and minutes till retirement.
 */

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>

void setup () {
  Wire.begin();
     Serial.begin(9600);
     setSyncProvider(RTC.get);
       time_t start,end;
       end = 1398895200L; // April 30, 2014 @ 22:00:00 hrs.
       start = end - now();
     Serial.print(now());
     Serial.println("");   
     Serial.print(start);
     Serial.println("");
     Serial.print(start / 86400L);
     Serial.println(""); 


void loop () {
   
}

and the output looks like this

1333908198
64987002
752

Now on to the hours and minutes left. Any Ideas anyone? I was thinking 22:00:00hrs minus now().
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK got it working.

Code:



/*
 * RetirementClock.ino
 * countdown the days, hours and minutes till retirement.
 */

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// #defines the backlight color
#define BLUE 0x4

void setup () {
  Wire.begin();
     Serial.begin(9600);
   
   
   // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  lcd.setBacklight(BLUE);
  lcd.setCursor(0, 0);
  setSyncProvider(RTC.get);
 
}

void loop () {
  time_t daysleft,retirementdate;
       retirementdate = 1398895200L; // April 30, 2014 @ 22:00:00 hrs.
       daysleft = retirementdate - now();
       long nineoclock   = 75600;
       long tenoclock    = 79200;
       long elevenoclock = 82800;
       long twelveoclock = 86399;
     lcd.setCursor(0, 0);
     lcd.print("Days ");
     lcd.print(daysleft / SECS_PER_DAY);
     
     if (elapsedSecsToday(now()) < nineoclock)
     {
       lcd.setCursor(10, 0);
       lcd.print("Hrs ");
       printDigits((nineoclock - elapsedSecsToday(now()))/ SECS_PER_HOUR);
     }
     else if ((elapsedSecsToday(now()) > nineoclock) && (elapsedSecsToday(now()) < tenoclock ))
     {
       lcd.setCursor(10, 0);
       lcd.print("Hrs ");
       lcd.print("0");
     }
     else if ((elapsedSecsToday(now()) > tenoclock) && (elapsedSecsToday(now()) < elevenoclock))
     {
       lcd.setCursor(10, 0);
       lcd.print("Hrs ");
       lcd.print("23");
     }
     else
     {
       lcd.setCursor(10, 0);
       lcd.print("Hrs ");
       lcd.print("22");
     }
  lcd.setCursor(0, 1);
  lcd.print("Min ");
  printDigits(59 - minute());
     
  lcd.setCursor(7, 1);
  lcd.print("Sec ");
  printDigits(59 - second());
  delay(1000);
   
 }
 
void printDigits(int digits){
  // utility function for digital clock display: prints leading 0
   if(digits < 10)
    lcd.print('0');
    lcd.print(digits);
}

Well it took a few days but it's working so far. It was not easy trying out some of the macros and functions in the time library.
There are two other macros that I'd like to try but I don't understand there syntax,  daysToTime_t, makeTime and I haven't found any examples of there use.
Logged

Miami, FL. U.S.A.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just cleaned up the code a little bit. Next I think I'll add the capability to input the retirement date. So that means I have to add a menu(to select from input or display), date converter(to convert the date from string to time_t).

Code:



/*
 * RetirementClock.ino
 * countdown the days, hours and minutes till retirement.
 */

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// #defines the backlight color
#define BLUE 0x4

void setup () {
  Wire.begin();
     Serial.begin(9600);
   
   
   // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  lcd.setBacklight(BLUE);
  lcd.setCursor(0, 0);
  lcd.clear();
   
 
}

void loop () {
 
  setSyncProvider(RTC.get);
  time_t daysleft,retirementdate; // setup the fields needed.
       retirementdate = 2280614400L; // January 01, 2042
       daysleft = retirementdate - now(); // subtract todays date from the retirement date to get the days left.
     // Display the days left before retirement.     
     lcd.setCursor(0, 0);
     lcd.print("Days ");
     displayDaysDigits(daysleft / SECS_PER_DAY);
     
     // Display the hours left before midnight.
     lcd.setCursor(10, 0);
     lcd.print("Hrs ");
     displayTimeDigits(23 - hour());
     
     // Display the minutes left in a hour.
     lcd.setCursor(0, 1);
     lcd.print("Min ");
     displayTimeDigits(59 - minute());
     
     // Display the seconds left in a minute.
     lcd.setCursor(7, 1);
     lcd.print("Sec ");
     displayTimeDigits(59 - second());
     delay(1000);
   
 }
 
void displayTimeDigits(int digits){
  // utility function for time display: displays leading 0.
   if(digits < 10)
    lcd.print('0');
    lcd.print(digits);
}

void displayDaysDigits(int digits){
  // utility function for days display: displays leading spaces.
   if(digits <= 9)
    {
    lcd.print("    ");
    lcd.print(digits);
    }
    else if(digits <= 99)
    {
    lcd.print("   ");
    lcd.print(digits);
    }
    else if(digits <= 999)
    {
    lcd.print("  ");
    lcd.print(digits);
    }
    else if(digits <= 99)
    {
    lcd.print(" ");
    lcd.print(digits);
    }
    else
    {
    lcd.print(digits);
    }
}
Logged

Pages: [1]   Go Up
Jump to: