#undef int() //hack for arduino 0011 to allow use of stdio: #include //gives us function sprintf #include #define HEARTBEAT 13 #define BUTTON1 5 #define BUTTON2 6 #define MODE_NORMAL 0 #define MODE_SETAHOUR 1 #define MODE_SETAMIN 2 #define ALARM_OFF 0 #define ALARM_ON 1 #define MSG_ALARM_OFF "0" #define MSG_ALARM_ON "1" #define MSG_ALARM_TRIGGER "T" int mode = MODE_NORMAL; int alarm = ALARM_OFF; int sec=30; int min=54; int hour=23; //keep track of time int amin=15; int ahour=8; //keep track of alarmtime // count how many millis have passed since // we increased the seconds last time long delta=0; char buffer[9]; //create object to control an LCD. LCD4Bit lcd = LCD4Bit(2); //2 lines void time_changed() { // call this after every increment of 1 // to any of the three time values if(sec==60) { min=min+1; sec=0; } if(min==60) { hour=hour+1; min=0; } if(hour==24) { hour=0; } } void atime_changed() { // call this after every increment to alarm time values if(amin>=60) { amin=amin - 60; } if(ahour>=24) { ahour=ahour - 24; } } void send_msg(char* msg) { Serial.print(msg); } void button1_onpress() { mode++; if (mode > MODE_SETAMIN) mode = MODE_NORMAL; update_lcd_mode(); } void button2_onpress() { if (mode == MODE_NORMAL) { if (alarm == ALARM_ON) { alarm = ALARM_OFF; send_msg(MSG_ALARM_OFF); } else if (alarm == ALARM_OFF) { alarm = ALARM_ON; send_msg(MSG_ALARM_ON); } update_lcd_mode(); } else if (mode == MODE_SETAHOUR) { ahour = ahour + 1; atime_changed(); update_lcd_atime(); } else if (mode == MODE_SETAMIN) { amin = amin + 1; atime_changed(); update_lcd_atime(); } } void update_lcd_time() { if (sec % 2 == 0) { //true if sec is even number sprintf(buffer, "%2d %2d:%2d", hour, min, sec); } else { sprintf(buffer, "%2d:%2d %2d", hour, min, sec); // : are off every uneven sec } lcd.cursorTo(1, 0); //line=1, x=0. lcd.printIn(buffer); if(ahour==hour && amin==min && alarm == ALARM_ON) { // Animate snoRRRhea when alarm goes off; for 60 secs lcd.cursorTo(2, 0); lcd.printIn("snoRRRhea"); lcd.cursorTo(2, sec%9); // sec%9 is rest of integer division sec/9 lcd.printIn(" "); //moving space sign that covers the letters } } void update_lcd_atime() { lcd.cursorTo(2, 11); sprintf(buffer, "%2d:%2d", ahour, amin); lcd.printIn(buffer); } void update_lcd_mode() { lcd.cursorTo(1, 11); lcd.printIn(" "); if (mode == MODE_NORMAL) { lcd.cursorTo(1, 12); if (alarm == ALARM_ON) lcd.printIn(" ON"); else lcd.printIn("off"); } else if (mode == MODE_SETAHOUR) { lcd.cursorTo(1, 11); lcd.printIn("**"); } else if (mode == MODE_SETAMIN) { lcd.cursorTo(1, 14); lcd.printIn("**"); } } void setup() { pinMode(HEARTBEAT, OUTPUT); //we'll use the debug LED to output a heartbeat Serial.begin(9600); lcd.init(); lcd.clear(); update_lcd_mode(); update_lcd_atime(); lcd.cursorTo(2, 0); lcd.printIn("snoRRRhea"); } void loop() { int b1State, b2State; unsigned long beforems, afterms; digitalWrite(HEARTBEAT, LOW); //light the debug LED beforems = millis(); b1State = digitalRead(BUTTON1); b2State = digitalRead(BUTTON2); delay(10); if (b1State == LOW && digitalRead(BUTTON1) == HIGH) button1_onpress(); else if (b2State == LOW && digitalRead(BUTTON2) == HIGH) button2_onpress(); digitalWrite(HEARTBEAT, HIGH); //light the debug LED afterms=millis(); if (afterms < beforems) //millis reset to zero after 9 hours delta += 20; // let's make an educated guess else delta += (afterms - beforems); if (delta > 1000) { beforems = millis(); sec += 1; time_changed(); update_lcd_time(); if (alarm == ALARM_ON && hour == ahour && min == amin && sec == 0) send_msg(MSG_ALARM_TRIGGER); // this still needs a bit of adjustment; it's not very accurate delta = delta - 1000 - (millis() - beforems); } }