#include #include // minutes of "dawn" before alarm #define TIN 30 // "dawn" + "daylight" #define TDAY 45 // "dawn" + "daylight" + blue blinding light #define TOUT 75 // number of available alarms; max 10 for storage in the DS1307 ram #define NALARMS 4 // pins and addressed #define RPIN 3 #define YPIN 5 #define BPIN 6 int st = 0; // alarm status (minutes from alarm - TIN) char alarms[NALARMS][5]; // alarm settings char cmin; // current minute int a = -1; // current alarm char dbg = 0; // print debug informations void setup () { Serial.begin(9600); Wire.begin(); pinMode(RPIN,OUTPUT); pinMode(YPIN,OUTPUT); pinMode(BPIN,OUTPUT); digitalWrite(RPIN,255); digitalWrite(YPIN,255); digitalWrite(BPIN,0); // DEBUG: we want to read the setup messages delay(5000); digitalWrite(YPIN,0); // if the RTC is already running read alarms and status, // otherwise set everything to the default if ( RTC.readData(0x00) >> 7 ) { Serial.println("Setup the clock"); for ( int i = 0 ; i < NALARMS ; i ++ ) { for ( int j = 0; j < 5 ; j ++ ) { alarms[i][j] = 0; } } st = 0; a = -1; } else { st = RTC.readData(0x08); a = RTC.readData(0x09); cmin = RTC.readData(0x0a); // FIXME: we want to update st to the time passed // since the data was saved for ( int i = 0; i < NALARMS ; i ++ ) { for ( int j = 0; j < 5 ; j ++ ) { alarms[i][j] = RTC.readData(0x0b + i*5 + j); } } } } void loop () { // read commands from serial check_serial(); // read time, check alarms check_time(); if ( dbg ) { s_print_time(); Serial.print("st: "); Serial.print(st,DEC); Serial.print(", a: "); Serial.print(a,DEC); Serial.print(", cmin: "); Serial.println(cmin,DEC); } // act on status: LEDs and buzzer if ( st > 0 ) { set_leds(); } // wait about till the next second delay(1000); } // ****** Serial interface management *************************************** // void check_serial() { int rec = Serial.read(); switch (rec) { case 'a': s_set_alarm(); break; case 's': s_set_time(); break; case 'p': s_print_alarms(); break; case 't': s_print_time(); break; case 'd': s_toggle_debug(); break; case 'h': s_print_help(); break; } } void s_set_alarm() { int i = s_read_dig(); for ( int j = 0; j < 5 ; j++) { alarms[i][j] = s_read_2hex(); } for ( int j = 0; j < 5 ; j++ ) { RTC.writeData(0x0b + i*5 + j,alarms[i][j]); } Serial.print("Alarm "); Serial.print(i,DEC); Serial.println(" set."); } void s_set_time() { RTC.setYear(s_read_2dig()); RTC.setMonth(s_read_2dig()); RTC.setDate(s_read_2dig()); RTC.setDayOfWeek(s_read_dig()); RTC.setHours(s_read_2dig()); RTC.setMinutes(s_read_2dig()); RTC.setSeconds(s_read_2dig()); RTC.setClock(); Serial.print("Time set: "); s_print_time(); } int s_read_dig() { int rec; rec = Serial.read(); while ( rec == -1 ) { rec = Serial.read(); } return rec - 48; } int s_read_2dig() { int n; n = s_read_dig() * 10; n = n + s_read_dig(); return n; } int s_read_hex() { int rec; rec = Serial.read(); while ( rec == -1 ) { rec = Serial.read(); } if ( rec >= 48 && rec < 58 ) { return rec - 48; } else if ( rec >= 65 && rec < 71 ) { return rec - 55; } else if ( rec > 97 && rec < 102 ) { return rec - 87; } else { return 0; } } int s_read_2hex() { int n; n = s_read_hex() * 16; n = n + s_read_hex(); return n; } void s_print_alarms() { for ( int i = 0; i < NALARMS ; i++) { Serial.print(i,DEC); Serial.print(" - "); for ( int j = 0; j < 5 ; j++) { Serial.print(alarms[i][j],DEC); Serial.print(" "); } Serial.println(""); } } void s_print_time() { RTC.readClock(); Serial.print(RTC.getYear(),DEC); Serial.print("/"); Serial.print(RTC.getMonth(),DEC); Serial.print("/"); Serial.print(RTC.getDate(),DEC); Serial.print(" ("); Serial.print(RTC.getDayOfWeek(),DEC); Serial.print(") "); Serial.print(RTC.getHours(),DEC); Serial.print(":"); Serial.print(RTC.getMinutes(),DEC); Serial.print(":"); Serial.println(RTC.getSeconds(),DEC); } void s_toggle_debug() { if ( dbg ) { dbg = 0; } else { dbg = 1; } } void s_print_help() { Serial.println(""); Serial.println(" a - set an alarm"); Serial.println(" is"); Serial.println(" s - set the clock"); Serial.println(" is yymmgguHHMMSS"); Serial.println(" p - print the alarms"); Serial.println(" t - print the clock"); Serial.println(" d - toggle printing of debug informations"); Serial.println(" h - print this help"); } // ****** Time management *************************************************** // // Set the current time void set_time(int y,int m,int d, int w, int hh, int mm, int ss) { RTC.setYear(y); RTC.setMonth(m); RTC.setDate(m); RTC.setDayOfWeek(w); RTC.setHours(hh); RTC.setMinutes(mm); RTC.setSeconds(ss); RTC.switchTo24h(); RTC.setClock(); } void check_time() { RTC.readClock(); int mm = RTC.getMinutes(); int hour = RTC.getHours(); int wday = RTC.getDayOfWeek(); int day = RTC.getDate(); int month = RTC.getMonth(); if ( a < 0 ) { for ( int i = 0; i < NALARMS ; i ++ ) { // check alarm i if ( ( alarms[i][0] & ( 1 << (wday - 1) ) ) || (month == alarms[i][1] && day == alarms[i][2]) ) { // this is alarm day! if ( hour == alarms[i][3] && mm == alarms[i][4]) { // this is alarm hour! a = i; st = 1; cmin = mm; if ( ( alarms[i][0] & 128 ) == 0 ) { // this alarm won't be repeated alarms[i] = { 0,0,0,0,0 }; for ( int j = 0; j < 5 ; j++ ) { RTC.writeData(0x0b + i*5 + j,0); } } break; } } } } else { if ( cmin != mm ) { cmin = mm; st++; } } } // ****** LED management **************************************************** // void set_leds() { if ( st > 0 && st <= TIN) { int y = int(float(st*255)/TIN); int r = 255 - y; analogWrite(RPIN,r); analogWrite(YPIN,y); } else if ( st > TIN && st < TDAY ) { analogWrite(RPIN,0); analogWrite(YPIN,255); analogWrite(BPIN,0); } else if (st >= TDAY && st < TOUT) { analogWrite(RPIN,0); analogWrite(YPIN,0); analogWrite(BPIN,255); } else if (st == TOUT) { // reset stuff st = 0; a = -1; analogWrite(RPIN,255); analogWrite(YPIN,0); analogWrite(BPIN,0); } } // vim: set filetype=c: