Arduino sketch: fixed serial reading of hex digit a
[fuzzy_alarm_clock.git] / ds1307 / arduino_sketch / fuzzy_alarm_clock_ds1307.pde
blob8c24791ec390064f6953667a4c841bca6426cd74
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 3
17 #define YPIN 5
18 #define BPIN 6
20 int st = 0; // alarm status (minutes from alarm - TIN)
21 char alarms[NALARMS][5]; // alarm settings
22 char cmin; // current minute
23 int a = -1; // current alarm
24 char dbg = 0; // print debug informations
26 void setup () {
27     Serial.begin(9600);
28     Wire.begin();
30     pinMode(RPIN,OUTPUT);
31     pinMode(YPIN,OUTPUT);
32     pinMode(BPIN,OUTPUT);
34     digitalWrite(RPIN,255);
35     digitalWrite(YPIN,255);
36     digitalWrite(BPIN,0);
37    
38     // if the RTC is already running read alarms and status, 
39     // otherwise set everything to a sane default
40     if ( RTC.readData(0x00) >> 7 ) {
41         for ( int i = 0 ; i < NALARMS ; i ++ ) {
42             for ( int j = 0; j < 5 ; j ++ ) {
43                 alarms[i][j] = 0;
44             }
45         }
46         st = 0;
47         a = -1;
48         save_status();
49     } else {
50         st = RTC.readData(0x08);
51         a = RTC.readData(0x09);
52         cmin = RTC.readData(0x0a);
53         // This only works if the arduino had no power for a 
54         // "short" time. This is by design. :D
55         RTC.readClock();
56         st = st + (RTC.getMinutes() - cmin) % 60;
57         cmin = RTC.getMinutes();
58         save_status();
59         for ( int i = 0; i < NALARMS ; i ++ ) {
60             for ( int j = 0; j < 5 ; j ++ ) {
61                 alarms[i][j] = RTC.readData(0x0b + i*5 + j);
62             }
63         }
64     }
65     
68 void loop () {
69   
70   // read commands from serial
71   check_serial();
72   
73   // read time, check alarms
74   check_time();
76   if ( dbg ) {
77       s_print_time();
78       Serial.print("st: ");
79       Serial.print(st,DEC);
80       Serial.print(", a: ");
81       Serial.print(a,DEC);
82       Serial.print(", cmin: ");
83       Serial.println(cmin,DEC);
84   }
85   
86   // act on status: LEDs and buzzer
87   if ( st > 0 ) {
88       set_leds();
89   }
90   
91   // wait about till the next second
93   delay(1000);
94   
97 void save_status() {
98     RTC.writeData(0x08,st);
99     RTC.writeData(0x09,a);
100     RTC.writeData(0x0a,cmin);
103 // ****** Serial interface management *************************************** //
105 void check_serial() {
106     int rec = Serial.read();
107     switch (rec) {
108         case 'a':
109             s_set_alarm();
110             break;
111         case 's':
112             s_set_time();
113             break;
114         case 'p':
115             s_print_alarms();
116             break;
117         case 't':
118             s_print_time();
119             break;
120         case 'd':
121             s_toggle_debug();
122             break;
123         case 'h':
124             s_print_help();
125             break;
126     }
129 void s_set_alarm() {
130     int i = s_read_dig();
131     for ( int j = 0; j < 5 ; j++) {
132         alarms[i][j] = s_read_2hex();
133     }
134     for ( int j = 0; j < 5 ; j++ ) {
135         RTC.writeData(0x0b + i*5 + j,alarms[i][j]);
136     }
137     Serial.print("Alarm ");
138     Serial.print(i,DEC);
139     Serial.println(" set.");
142 void s_set_time() {
143     RTC.start();
144     RTC.setYear(s_read_2dig());
145     RTC.setMonth(s_read_2dig());
146     RTC.setDate(s_read_2dig());
147     RTC.setDayOfWeek(s_read_dig());
148     RTC.setHours(s_read_2dig());
149     RTC.setMinutes(s_read_2dig());
150     RTC.setSeconds(s_read_2dig());
151     RTC.setClock();
152     Serial.print("Time set: ");
153     s_print_time();
156 int s_read_dig() {
157     int rec;
158     rec = Serial.read();
159     while ( rec == -1 ) {
160         rec = Serial.read();
161     }
162     return rec - 48;
165 int s_read_2dig() {
166     int n;
167     n = s_read_dig() * 10;
168     n = n + s_read_dig();
169     return n;
172 int s_read_hex() {
173     int rec;
174     rec = Serial.read();
175     while ( rec == -1 ) {
176         rec = Serial.read();
177     }
178     if ( rec >= 48 && rec < 58 ) {
179         return rec - 48;
180     } else if ( rec >= 65 && rec < 71 ) {
181         return rec - 55;
182     } else if ( rec >= 97 && rec < 102 ) {
183         return rec - 87;
184     } else {
185         return 0;
186     }
189 int s_read_2hex() {
190     int n;
191     n = s_read_hex() * 16;
192     n = n + s_read_hex();
193     return n;
196 void s_print_alarms() {
197     for ( int i = 0; i < NALARMS ; i++) {
198         Serial.print(i,DEC);
199         Serial.print(" - ");
200         for ( int j = 0; j < 5 ; j++) {
201             Serial.print(alarms[i][j],DEC);
202             Serial.print(" ");
203         }
204         Serial.println("");
205     }
208 void s_print_time() {
209     RTC.readClock();
210     Serial.print(RTC.getYear(),DEC);
211     Serial.print("/");
212     Serial.print(RTC.getMonth(),DEC);
213     Serial.print("/");
214     Serial.print(RTC.getDate(),DEC);
215     Serial.print(" (");
216     Serial.print(RTC.getDayOfWeek(),DEC);
217     Serial.print(") ");
218     Serial.print(RTC.getHours(),DEC);
219     Serial.print(":");
220     Serial.print(RTC.getMinutes(),DEC);
221     Serial.print(":");
222     Serial.println(RTC.getSeconds(),DEC);
225 void s_toggle_debug() {
226     if ( dbg ) {
227         dbg = 0;
228     } else {
229         dbg = 1;
230     }
233 void s_print_help() {
234     Serial.println("");
235     Serial.println("  a<s> - set an alarm");
236     Serial.println("         <s> is nhhhhhhhhhh");
237     Serial.println("         where hh are hex values");
238     Serial.println("  s<s> - set the clock");
239     Serial.println("         <s> is yymmgguHHMMSS");
240     Serial.println("  p    - print the alarms");
241     Serial.println("  t    - print the clock");
242     Serial.println("  d    - toggle printing of debug informations");
243     Serial.println("  h    - print this help");
246 // ****** Time management *************************************************** //
248 // Set the current time
249 void set_time(int y,int m,int d, int w, int hh, int mm, int ss) {
250     RTC.setYear(y);
251     RTC.setMonth(m);
252     RTC.setDate(m);
253     RTC.setDayOfWeek(w);
254     RTC.setHours(hh);
255     RTC.setMinutes(mm);
256     RTC.setSeconds(ss);
257     RTC.switchTo24h();
258     RTC.setClock();
261 void check_time() {
262     RTC.readClock();
264     int mm = RTC.getMinutes();
265     int hour = RTC.getHours();
266     int wday = RTC.getDayOfWeek();
267     int day = RTC.getDate();
268     int month = RTC.getMonth();
270     if ( a < 0 ) {
271         for ( int i = 0; i < NALARMS ; i ++ ) {
272             // check alarm i
273             if ( ( alarms[i][0] & ( 1 << (wday - 1) ) ) || 
274                     (month == alarms[i][1] && day == alarms[i][2]) ) {
275                 // this is alarm day!
276                 if ( hour == alarms[i][3] && mm == alarms[i][4]) {
277                     // this is alarm hour!
278                     a = i;
279                     st = 1;
280                     cmin = mm;
281                     save_status();
282                     if ( ( alarms[i][0] & 128 ) == 0 ) {
283                         // this alarm won't be repeated
284                         alarms[i] = { 0,0,0,0,0 };
285                         for ( int j = 0; j < 5 ; j++ ) {
286                             RTC.writeData(0x0b + i*5 + j,0);
287                         }
288                     }
289                     break;
290                 }
291             } 
292         }
293     } else {
294         if ( cmin != mm ) {
295             cmin = mm;
296             st++;
297             save_status();
298         } 
299     }
303 // ****** LED management **************************************************** //
305 void set_leds() {
306   if ( st > 0 && st <= TIN) {
307       int y = int(float(st*255)/TIN);
308       int r = 255 - y;
309       analogWrite(RPIN,r);
310       analogWrite(YPIN,y);
311   } else if ( st > TIN && st < TDAY ) {
312       analogWrite(RPIN,0);
313       analogWrite(YPIN,255);
314       analogWrite(BPIN,0);
315   } else if (st >= TDAY && st < TOUT) {
316       analogWrite(RPIN,0);
317       analogWrite(YPIN,0);
318       analogWrite(BPIN,255);
319   } else if (st == TOUT) {
320       // reset stuff
321       st = 0;
322       a = -1;
323       save_status();
324       analogWrite(RPIN,255);
325       analogWrite(YPIN,0);
326       analogWrite(BPIN,0);
327   }
330 // vim: set filetype=c: