The design is the "raw electronics" look. The arduino is mounted on the back of the large LCD display by nothing more than a stacked header, and hot glued to a small piece of wood for a base.
The code is built on top of the basic example for a clock that syncs from the PC, found here:
The Arduino Time Library on the Arduino Playground
http://www.arduino.cc/playground/Code/Time
When plugged into the PC and using the Arduino serial monitor, it waits for you to enter a unix timestamp.
You can generate these from web sites like these ones:
http://www.timestampgenerator.com/
http://www.unixtimestamp.com/index.php
They have the form of seconds since Jan 01 1970, type in T1297687386
Type that in the start the clock. There are PC programs out there that run a host to send that string, like gobetwino if you want to do that to, you don't need to. This is just a manual start.
Change this variable in the code to the unix timestamp of the event you want to count down to
signed long tapeout = 1309539600;
The hardware is nothing more than an arduino interfaced to a huge 20x4 backlit LCD module, using the 4 bit wide parallel communication mode. The pinout is a very slight mod to the descriptions in the Arduino examples, because I like to group the pins all on one header. This is exactly like the setup in the Arduino examples.
I use an external wall wart as power, so it doesn't have to be plugged into the PC all the time.
Here is the code
* Sketch for 4x20 LCD to display current time and date, and countdown of weeks, days, hours, min to an event
*
*/
#include <Time.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6 , 5, 4, 3, 2);
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message
signed long tapeout = 1309539600;
// to make sure the display is cleared once a day
int yesterday = 0;
int weeksleft = 0;
int daysleft = 0;
int hoursleft = 0;
int minleft = 0;
void setup() {
lcd.begin(20, 4);
lcd.clear();
//backlight on pin 8
pinMode(8, OUTPUT);
digitalWrite(8, LOW);
Serial.begin(9600);
setSyncProvider( requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");
Serial.println("Unix Timestamp");
Serial.println("Example T1297674000");
lcd.setCursor(0,0);
lcd.print("Waiting for PC time sync...");
}
void loop(){
if(Serial.available() )
{
processSyncMessage();
digitalWrite(8, HIGH);
}
if(timeStatus()!= timeNotSet)
{
digitalClockDisplay();
// clear the display if the day changes to clear glitches
if (day() != yesterday) {
//lcd.clear();
yesterday = day();
}
}
delay(20000); //can be set to 1000, this makes the display more stable
}
void digitalClockDisplay(){
//turn on backlight only during workday
if((hour() >= 8) & (hour() < 19)) digitalWrite(8, HIGH);
else digitalWrite(8, LOW);
// digital clock display of the time
lcd.setCursor(0,0);
Serial.print(hour());
lcd.print(hourFormat12());
printDigits(minute());
//printDigits(second());
Serial.print(" ");
if (isAM()) lcd.print(" AM ");
if (isPM()) lcd.print(" PM ");
Serial.print(dayStr(weekday()));
lcd.print(dayStr(weekday()));
Serial.print(" ");
lcd.print(" ");
lcd.setCursor(0,1);
Serial.print(day());
lcd.print(day());
Serial.print(" ");
lcd.print(" ");
Serial.print(monthShortStr(month()));
lcd.print(monthShortStr(month()));
Serial.print(" ");
lcd.print(" ");
Serial.print(year());
lcd.print(year());
Serial.println();
lcd.setCursor(0,2);
if (tapeout < now()) {
weeksleft = (now() - tapeout)/60/60/24/7;
daysleft = (now() - tapeout)/60/60/24 - weeksleft*7;
hoursleft = (now() - tapeout)/60/60 - daysleft*24 - weeksleft*7*24;
minleft = (now() - tapeout)/60 - hoursleft*60 - daysleft*24*60 - weeksleft*7*24*60;
lcd.print( weeksleft );
lcd.print("wk ");
lcd.print( daysleft );
lcd.print("d ");
lcd.print( hoursleft );
lcd.print("h ");
lcd.print( minleft );
lcd.print("m ");
lcd.setCursor(0,3);
lcd.print("Late! OMG! Ship It! ");
} else {
weeksleft = (tapeout - now())/60/60/24/7;
daysleft = (tapeout - now())/60/60/24 - weeksleft*7 ;
hoursleft = (tapeout - now())/60/60 - daysleft*24 - weeksleft*7*24;
minleft = (tapeout - now())/60 - hoursleft*60 - daysleft*24*60 - weeksleft*7*24*60;
lcd.print( weeksleft );
lcd.print("wk ");
lcd.print( daysleft );
lcd.print("d ");
lcd.print( hoursleft );
lcd.print("h ");
lcd.print( minleft );
lcd.print("m ");
lcd.setCursor(0,3);
lcd.print("To Santan Tapeout! ");
}
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
lcd.print(":");
if(digits < 10){
Serial.print('0');
lcd.print('0');
}
Serial.print(digits);
lcd.print(digits);
}
void processSyncMessage() {
lcd.clear();
// if time sync available from serial port, update time and return true
while(Serial.available() >= TIME_MSG_LEN ){ // time message consists of a header and ten ascii digits
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
setTime(pctime); // Sync Arduino clock to the time received on the serial port
}
}
}
time_t requestSync()
{
Serial.print(TIME_REQUEST,BYTE);
return 0; // the time will be sent later in response to serial mesg
}
does not compile on latest IDE error at
ReplyDeleteSerial.print(TIME_REQUEST,BYTE); but i'm a noob so don't know why ..
More fascinating that Mathematicians utilize "LCD" as Lowest Common Denominator. Atkins Diet utilized LCD as Low Carbohydrate Diet. Back to LCD as Liquid Crystal Display, raise projection HDTVs ordinarily are LCD, DLP or LCoS which implies Liquid Crystal on Silicon, they are gradually getting to be adversaries of plasma.Best 55 inch tvs
ReplyDelete