/*
countdown.pde
Eric Ayars
8/18/11
Countdown timer
This program displays days, hours, minutes, and seconds until some
specified time. At that time (and aftwards) it displays a message.
*/
#include <Wire.h>
#include "DS3231.h"
#include <LiquidCrystal.h>
#include <avr/sleep.h>
#define SECONDSINDAY 86400
#define SECONDSINHOUR 3600
#define SECONDSINMINUTE 60
unsigned long remSeconds, remMinutes, remHours, remDays;
byte year, month, day, hour, minute, second, DoW;
// Put your target date here.
byte targetYear = 11;
byte targetMonth = 12;
byte targetDay = 25;
byte targetHour = 0;
byte targetMinute = 0;
byte targetSecond = 0;
unsigned int monthdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
bool century, h24, ampm;
unsigned long targetDate;
unsigned long Now, dT;
DS3231 RTC;
LiquidCrystal lcd(8,9,7,6,5,4);
unsigned long secondsSince2000(unsigned int year, byte month, byte day, byte hour, byte minute, byte second)
{
// This code stolen from someene else's DS1337 library. It was called
// "date_to_epoch_seconds()" there, but it didn't do epoch seconds,
// just seconds since 2000. That's fine in this case, since seconds
// since 2000 is sufficient for this purpose.
unsigned long sse = (((unsigned long)year)*365*24*60*60) + ((((unsigned long)year+3)>>2) + ((unsigned long)year%4==0 && (unsigned long)month>2))*24*60*60 + \
((unsigned long)monthdays[month-1] + (unsigned long)day-1) *24*60*60 + ((unsigned long)hour*60*60) + ((unsigned long)minute*60) + (unsigned long)second;
return sse;
}
void celebrate() {
// Put whatever you want here. You could of course do more than just
// a static message.
lcd.setCursor(0, 0);
lcd.print(" Merry ");
lcd.setCursor(0, 1);
lcd.print(" Christmas! ");
// Stay stuck here, leaving the message.
set_sleep_mode(SLEEP_MODE_POWER_DOWN);
sleep_enable();
sleep_mode();
/* It wouldn't be difficult to change this so that it displayed the
Merry Christmas message for a day and then started counting down
to next year. I decided not to make it Christmas-specific, though,
so it can also be used for other nice countdowns such as the end
of the school term and so on. */
}
void setup() {
Wire.begin();
lcd.begin(2,16);
targetDate =secondsSince2000(targetYear, targetMonth, targetDay, targetHour, targetMinute, targetSecond);
}
void loop() {
year = RTC.getYear();
month = RTC.getMonth(century);
if (century) year += 100;
day = RTC.getDate();
hour = RTC.getHour(h24, ampm);
if ((h24) && (ampm)) hour += 12;
minute = RTC.getMinute();
second = RTC.getSecond();
Now = secondsSince2000(year, month, day, hour, minute, second);
// Are we past the countdown?
if (Now >= targetDate) {
celebrate();
}
// Here's the time remaining.
dT = targetDate - Now;
// Figure out whole days remaining
remDays = dT/SECONDSINDAY;
// Here's the leftover HMS
remSeconds = dT%SECONDSINDAY;
// Figure out the whole hours remaining
remHours = remSeconds/SECONDSINHOUR;
// Here's the leftover MS
remSeconds = remSeconds%SECONDSINHOUR;
// Figure out the whole minutes remaining
remMinutes = remSeconds/SECONDSINMINUTE;
// Here's the leftover S
remSeconds = remSeconds%SECONDSINMINUTE;
// Make sure we're dealing with a blank display
lcd.clear();
// Print the top line to the display
lcd.setCursor(0,0);
lcd.print(remDays, DEC);
lcd.setCursor(4,0);
lcd.print("Days ");
lcd.setCursor(9,0);
lcd.print(remHours, DEC);
lcd.setCursor(12,0);
lcd.print("Hrs ");
// Print the bottom line to the display
lcd.setCursor(0,1);
lcd.print(remMinutes, DEC);
lcd.setCursor(4,1);
lcd.print("Min ");
lcd.setCursor(9,1);
lcd.print(remSeconds, DEC);
lcd.setCursor(12,1);
lcd.print("Sec ");
// No need running this more than 4x per second, really...
delay(250);
}