arduino sketch: removed debug setting of dawn time
[fuzzy_alarm_clock.git] / arduino_sketch / fuzzy_alarm_clock_ds1307 / fuzzy_alarm_clock_ds1307.pde
blobd74a5820210758eedfd8d8b32e46a7c882820dbf
1 #include <Wire.h>
3 #include <RealTimeClockDS1307.h>
5 // minutes of "dawn" before alarm
6 #define TIN 30
7 // "dawn" + "daylight"
8 #define TDAY 45
9 // "dawn" + "daylight" + blue blinding light
10 #define TOUT 75
12 // number of available alarms; max 10 for storage in the DS1307 ram 
13 #define NALARMS 4
15 // pins and addressed
16 #define RPIN 5
17 #define YPIN 6
18 #define BPIN 9
20 #define APIN0 3
21 #define APIN1 11
23 int st = 0; // alarm status (minutes from alarm - TIN)
24 char alarms[NALARMS][5]; // alarm settings
25 char cmin; // current minute
26 int a = -1; // current alarm
27 char dbg = 0; // print debug informations
28 bool ringing = false; // sound the alarm
30 #define NFREQ 9
31 int freq[] = { 255, 192, 128, 96, 64, 96, 128, 192, 255 }; // frequencies for the alarm
33 void setup () {
34     Serial.begin(9600);
35     Wire.begin();
37     pinMode(RPIN,OUTPUT);
38     pinMode(YPIN,OUTPUT);
39     pinMode(BPIN,OUTPUT);
41     pinMode(APIN0,INPUT);
42     pinMode(APIN1,INPUT);
43     TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
44     TCCR2B = _BV(WGM22) | _BV(CS22);
46     digitalWrite(RPIN,255);
47     digitalWrite(YPIN,255);
48     digitalWrite(BPIN,0);
49    
50     // if the RTC is already running read alarms and status, 
51     // otherwise set everything to a sane default
52     if ( RTC.readData(0x00) >> 7 ) {
53         for ( int i = 0 ; i < NALARMS ; i ++ ) {
54             for ( int j = 0; j < 5 ; j ++ ) {
55                 alarms[i][j] = 0;
56             }
57         }
58         st = 0;
59         a = -1;
60         save_status();
61     } else {
62         st = RTC.readData(0x08);
63         a = RTC.readData(0x09);
64         cmin = RTC.readData(0x0a);
65         // This only works if the arduino had no power for a 
66         // "short" time. This is by design. :D
67         RTC.readClock();
68         st = st + (RTC.getMinutes() - cmin) % 60;
69         cmin = RTC.getMinutes();
70         save_status();
71         for ( int i = 0; i < NALARMS ; i ++ ) {
72             for ( int j = 0; j < 5 ; j ++ ) {
73                 alarms[i][j] = RTC.readData(0x0b + i*5 + j);
74             }
75         }
76     }
77     
80 void loop () {
81   
82   // read commands from serial
83   check_serial();
84   
85   // read time, check alarms
86   check_time();
88   if ( dbg ) {
89       s_print_time();
90       Serial.print("st: ");
91       Serial.print(st,DEC);
92       Serial.print(", a: ");
93       Serial.print(a,DEC);
94       Serial.print(", cmin: ");
95       Serial.println(cmin,DEC);
96   }
97   
98   // act on status: LEDs and buzzer
99   if ( st > 0 ) {
100       set_leds();
101   }
102   if ( st == TIN ) {
103       ringing = true;
104   } else {
105       ringing = false;
106   }
107   if ( ringing ) {
108       ring_alarm();
109   }
110   // wait about till the next second
112   delay(1000);
113   
116 void save_status() {
117     RTC.writeData(0x08,st);
118     RTC.writeData(0x09,a);
119     RTC.writeData(0x0a,cmin);
122 // ****** Serial interface management *************************************** //
124 void check_serial() {
125     int rec = Serial.read();
126     switch (rec) {
127         case 'a':
128             s_set_alarm();
129             break;
130         case 's':
131             s_set_time();
132             break;
133         case 'p':
134             s_print_alarms();
135             break;
136         case 't':
137             s_print_time();
138             break;
139         case 'd':
140             s_toggle_debug();
141             break;
142         case 'h':
143             s_print_help();
144             break;
145     }
148 void s_set_alarm() {
149     int i = s_read_dig();
150     for ( int j = 0; j < 5 ; j++) {
151         alarms[i][j] = s_read_2hex();
152     }
153     for ( int j = 0; j < 5 ; j++ ) {
154         RTC.writeData(0x0b + i*5 + j,alarms[i][j]);
155     }
156     Serial.print("Alarm ");
157     Serial.print(i,DEC);
158     Serial.println(" set.");
161 void s_set_time() {
162     RTC.start();
163     RTC.setYear(s_read_2dig());
164     RTC.setMonth(s_read_2dig());
165     RTC.setDate(s_read_2dig());
166     RTC.setDayOfWeek(s_read_dig());
167     RTC.setHours(s_read_2dig());
168     RTC.setMinutes(s_read_2dig());
169     RTC.setSeconds(s_read_2dig());
170     RTC.setClock();
171     Serial.print("Time set: ");
172     s_print_time();
175 int s_read_dig() {
176     int rec;
177     rec = Serial.read();
178     while ( rec == -1 ) {
179         rec = Serial.read();
180     }
181     return rec - 48;
184 int s_read_2dig() {
185     int n;
186     n = s_read_dig() * 10;
187     n = n + s_read_dig();
188     return n;
191 int s_read_hex() {
192     int rec;
193     rec = Serial.read();
194     while ( rec == -1 ) {
195         rec = Serial.read();
196     }
197     if ( rec >= 48 && rec < 58 ) {
198         return rec - 48;
199     } else if ( rec >= 65 && rec < 71 ) {
200         return rec - 55;
201     } else if ( rec >= 97 && rec < 102 ) {
202         return rec - 87;
203     } else {
204         return 0;
205     }
208 int s_read_2hex() {
209     int n;
210     n = s_read_hex() * 16;
211     n = n + s_read_hex();
212     return n;
215 void s_print_alarms() {
216     for ( int i = 0; i < NALARMS ; i++) {
217         Serial.print(i,DEC);
218         Serial.print(" - ");
219         for ( int j = 0; j < 5 ; j++) {
220             Serial.print(alarms[i][j],DEC);
221             Serial.print(" ");
222         }
223         Serial.println("");
224     }
227 void s_print_time() {
228     RTC.readClock();
229     Serial.print(RTC.getYear(),DEC);
230     Serial.print("/");
231     Serial.print(RTC.getMonth(),DEC);
232     Serial.print("/");
233     Serial.print(RTC.getDate(),DEC);
234     Serial.print(" (");
235     Serial.print(RTC.getDayOfWeek(),DEC);
236     Serial.print(") ");
237     Serial.print(RTC.getHours(),DEC);
238     Serial.print(":");
239     Serial.print(RTC.getMinutes(),DEC);
240     Serial.print(":");
241     Serial.println(RTC.getSeconds(),DEC);
244 void s_toggle_debug() {
245     if ( dbg ) {
246         dbg = 0;
247     } else {
248         dbg = 1;
249     }
252 void s_print_help() {
253     Serial.println("");
254     Serial.println("  a<s> - set an alarm");
255     Serial.println("         <s> is nhhhhhhhhhh");
256     Serial.println("         alarm ID");
257     Serial.println("         one bit (in hex) for day of week");
258     Serial.println("         hex values for month, day");
259     Serial.println("         hex values for hour, minutes");
260     Serial.println("         (relative to start-of-dawn time)");
261     Serial.println("  s<s> - set the clock");
262     Serial.println("         <s> is yymmgguHHMMSS");
263     Serial.println("  p    - print the alarms");
264     Serial.println("  t    - print the clock");
265     Serial.println("  d    - toggle printing of debug informations");
266     Serial.println("  h    - print this help");
269 // ****** Time management *************************************************** //
271 // Set the current time
272 void set_time(int y,int m,int d, int w, int hh, int mm, int ss) {
273     RTC.setYear(y);
274     RTC.setMonth(m);
275     RTC.setDate(m);
276     RTC.setDayOfWeek(w);
277     RTC.setHours(hh);
278     RTC.setMinutes(mm);
279     RTC.setSeconds(ss);
280     RTC.switchTo24h();
281     RTC.setClock();
284 void check_time() {
285     RTC.readClock();
287     int mm = RTC.getMinutes();
288     int hour = RTC.getHours();
289     int wday = RTC.getDayOfWeek();
290     int day = RTC.getDate();
291     int month = RTC.getMonth();
293     if ( a < 0 ) {
294         for ( int i = 0; i < NALARMS ; i ++ ) {
295             // check alarm i
296             if ( ( alarms[i][0] & ( 1 << (wday - 1) ) ) || 
297                     (month == alarms[i][1] && day == alarms[i][2]) ) {
298                 // this is alarm day!
299                 if ( hour == alarms[i][3] && mm == alarms[i][4]) {
300                     // this is alarm hour!
301                     a = i;
302                     st = 1;
303                     cmin = mm;
304                     save_status();
305                     if ( ( alarms[i][0] & 128 ) == 0 ) {
306                         // this alarm won't be repeated
307                         alarms[i] = { 0,0,0,0,0 };
308                         for ( int j = 0; j < 5 ; j++ ) {
309                             RTC.writeData(0x0b + i*5 + j,0);
310                         }
311                     }
312                     break;
313                 }
314             } 
315         }
316     } else {
317         if ( cmin != mm ) {
318             cmin = mm;
319             st++;
320             save_status();
321         } 
322     }
326 // ****** LED management **************************************************** //
328 void set_leds() {
329   if ( st > 0 && st <= TIN) {
330       int y = int(float(st*255)/TIN);
331       int r = 255 - y;
332       analogWrite(RPIN,r);
333       analogWrite(YPIN,y);
334   } else if ( st > TIN && st < TDAY ) {
335       analogWrite(RPIN,0);
336       analogWrite(YPIN,255);
337       analogWrite(BPIN,0);
338   } else if (st >= TDAY && st < TOUT) {
339       analogWrite(RPIN,0);
340       analogWrite(YPIN,0);
341       analogWrite(BPIN,255);
342   } else if (st == TOUT) {
343       // reset stuff
344       st = 0;
345       a = -1;
346       save_status();
347       analogWrite(RPIN,255);
348       analogWrite(YPIN,0);
349       analogWrite(BPIN,0);
350   }
353 // PC speaker
355 void ring_alarm() {
357     pinMode(APIN1,OUTPUT);
358     for (int i=0; i<NFREQ ; i++) {
359         OCR2A = freq[i];
360         delay(50);
361     }
362     pinMode(APIN1,INPUT);
366 // vim: set filetype=c: