#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 #define NALARMS 4 // pins and addressed #define RPIN 3 #define YPIN 5 #define BPIN 6 #define DS1307_ADDRESS 0x68 int st = 0; // alarm status (minutes from alarm - TIN) char alarms[NALARMS][5]; char cmin; // current minute int a = -1; // current alarm void setup () { Serial.begin(9600); Wire.begin(); set_time(11,9,2,5,0,0,0); pinMode(RPIN,OUTPUT); pinMode(YPIN,OUTPUT); pinMode(BPIN,OUTPUT); digitalWrite(RPIN,255); digitalWrite(YPIN,0); digitalWrite(BPIN,0); // read alarms and status from storage for ( int i = 0 ; i < NALARMS ; i ++ ) { alarms[i][0] = 0; } st = 0; a = -1; } void loop () { // read commands from serial // read time, check alarms check_time(); Serial.println(st); // act on status: LEDs and buzzer if ( st > 0 ) { set_leds(); } // wait about till the next second delay(1000); } // Set the current time void set_time(int y,int m,int d, int w, int hh, int mm, int ss) { Wire.beginTransmission(DS1307_ADDRESS); Wire.send(0); Wire.send(bin2bcd(ss)); Wire.send(bin2bcd(mm)); Wire.send(bin2bcd(hh)); Wire.send(w); Wire.send(bin2bcd(d)); Wire.send(bin2bcd(m)); Wire.send(bin2bcd(y)); Wire.send(0); Wire.endTransmission(); } void check_time() { Wire.beginTransmission(DS1307_ADDRESS); Wire.send(0); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 6); Wire.receive(); int mm = bcd2bin(Wire.receive()); int hour = bcd2bin(Wire.receive()); int wday = Wire.receive(); int day = bcd2bin(Wire.receive()); int month = bcd2bin(Wire.receive()); 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 = 0; cmin = mm; if ( ( alarms[i][0] & 128 ) == 0 ) { // this alarm won't be repeated alarms[i] = { 0,0,0,0,0 }; } break; } } } } else { if ( cmin < mm ) { cmin = mm; st++; } } } 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) { 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); } } // BCD helper functions from adafruit-RTClib static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } // vim: set filetype=c: