/* 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); }