Serial management
[fuzzy_alarm_clock.git] / ds1307 / arduino_sketch / fuzzy_alarm_clock_ds1307.pde
blob224706aa9aa55d97ca6fecd0d903e8ddbebf6993
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     // DEBUG: we want to read the setup messages
39     
40     delay(5000);
41     digitalWrite(YPIN,0);
43     // if the RTC is already running read alarms and status, 
44     // otherwise set everything to the default
45     if ( RTC.readData(0x00) >> 7 ) {
46         Serial.println("Setup the clock");
47         for ( int i = 0 ; i < NALARMS ; i ++ ) {
48             for ( int j = 0; j < 5 ; j ++ ) {
49                 alarms[i][j] = 0;
50             }
51         }
52         st = 0;
53         a = -1;
54     } else {
55         st = RTC.readData(0x08);
56         a = RTC.readData(0x09);
57         cmin = RTC.readData(0x0a);
58         // FIXME: we want to update st to the time passed 
59         // since the data was saved
60         for ( int i = 0; i < NALARMS ; i ++ ) {
61             for ( int j = 0; j < 5 ; j ++ ) {
62                 alarms[i][j] = RTC.readData(0x0b + i*5 + j);
63             }
64         }
65     }
66     
69 void loop () {
70   
71   // read commands from serial
72   check_serial();
73   
74   // read time, check alarms
75   check_time();
77   if ( dbg ) {
78       s_print_time();
79       Serial.print("st: ");
80       Serial.print(st,DEC);
81       Serial.print(", a: ");
82       Serial.print(a,DEC);
83       Serial.print(", cmin: ");
84       Serial.println(cmin,DEC);
85   }
86   
87   // act on status: LEDs and buzzer
88   if ( st > 0 ) {
89       set_leds();
90   }
91   
92   // wait about till the next second
94   delay(1000);
95   
98 // ****** Serial interface management *************************************** //
100 void check_serial() {
101     int rec = Serial.read();
102     switch (rec) {
103         case 'a':
104             s_set_alarm();
105             break;
106         case 's':
107             s_set_time();
108             break;
109         case 'p':
110             s_print_alarms();
111             break;
112         case 't':
113             s_print_time();
114             break;
115         case 'd':
116             s_toggle_debug();
117             break;
118         case 'h':
119             s_print_help();
120             break;
121     }
124 void s_set_alarm() {
125     int i = s_read_dig();
126     for ( int j = 0; j < 5 ; j++) {
127         alarms[i][j] = s_read_2hex();
128     }
129     for ( int j = 0; j < 5 ; j++ ) {
130         RTC.writeData(0x0b + i*5 + j,alarms[i][j]);
131     }
132     Serial.print("Alarm ");
133     Serial.print(i,DEC);
134     Serial.println(" set.");
137 void s_set_time() {
138     RTC.setYear(s_read_2dig());
139     RTC.setMonth(s_read_2dig());
140     RTC.setDate(s_read_2dig());
141     RTC.setDayOfWeek(s_read_dig());
142     RTC.setHours(s_read_2dig());
143     RTC.setMinutes(s_read_2dig());
144     RTC.setSeconds(s_read_2dig());
145     RTC.setClock();
146     Serial.print("Time set: ");
147     s_print_time();
150 int s_read_dig() {
151     int rec;
152     rec = Serial.read();
153     while ( rec == -1 ) {
154         rec = Serial.read();
155     }
156     return rec - 48;
159 int s_read_2dig() {
160     int n;
161     n = s_read_dig() * 10;
162     n = n + s_read_dig();
163     return n;
166 int s_read_hex() {
167     int rec;
168     rec = Serial.read();
169     while ( rec == -1 ) {
170         rec = Serial.read();
171     }
172     if ( rec >= 48 && rec < 58 ) {
173         return rec - 48;
174     } else if ( rec >= 65 && rec < 71 ) {
175         return rec - 55;
176     } else if ( rec > 97 && rec < 102 ) {
177         return rec - 87;
178     } else {
179         return 0;
180     }
183 int s_read_2hex() {
184     int n;
185     n = s_read_hex() * 16;
186     n = n + s_read_hex();
187     return n;
190 void s_print_alarms() {
191     for ( int i = 0; i < NALARMS ; i++) {
192         Serial.print(i,DEC);
193         Serial.print(" - ");
194         for ( int j = 0; j < 5 ; j++) {
195             Serial.print(alarms[i][j],DEC);
196             Serial.print(" ");
197         }
198         Serial.println("");
199     }
202 void s_print_time() {
203     RTC.readClock();
204     Serial.print(RTC.getYear(),DEC);
205     Serial.print("/");
206     Serial.print(RTC.getMonth(),DEC);
207     Serial.print("/");
208     Serial.print(RTC.getDate(),DEC);
209     Serial.print(" (");
210     Serial.print(RTC.getDayOfWeek(),DEC);
211     Serial.print(") ");
212     Serial.print(RTC.getHours(),DEC);
213     Serial.print(":");
214     Serial.print(RTC.getMinutes(),DEC);
215     Serial.print(":");
216     Serial.println(RTC.getSeconds(),DEC);
219 void s_toggle_debug() {
220     if ( dbg ) {
221         dbg = 0;
222     } else {
223         dbg = 1;
224     }
227 void s_print_help() {
228     Serial.println("");
229     Serial.println("  a<s> - set an alarm");
230     Serial.println("         <s> is");
231     Serial.println("  s<s> - set the clock");
232     Serial.println("         <s> is yymmgguHHMMSS");
233     Serial.println("  p    - print the alarms");
234     Serial.println("  t    - print the clock");
235     Serial.println("  d    - toggle printing of debug informations");
236     Serial.println("  h    - print this help");
239 // ****** Time management *************************************************** //
241 // Set the current time
242 void set_time(int y,int m,int d, int w, int hh, int mm, int ss) {
243     RTC.setYear(y);
244     RTC.setMonth(m);
245     RTC.setDate(m);
246     RTC.setDayOfWeek(w);
247     RTC.setHours(hh);
248     RTC.setMinutes(mm);
249     RTC.setSeconds(ss);
250     RTC.switchTo24h();
251     RTC.setClock();
254 void check_time() {
255     RTC.readClock();
257     int mm = RTC.getMinutes();
258     int hour = RTC.getHours();
259     int wday = RTC.getDayOfWeek();
260     int day = RTC.getDate();
261     int month = RTC.getMonth();
263     if ( a < 0 ) {
264         for ( int i = 0; i < NALARMS ; i ++ ) {
265             // check alarm i
266             if ( ( alarms[i][0] & ( 1 << (wday - 1) ) ) || 
267                     (month == alarms[i][1] && day == alarms[i][2]) ) {
268                 // this is alarm day!
269                 if ( hour == alarms[i][3] && mm == alarms[i][4]) {
270                     // this is alarm hour!
271                     a = i;
272                     st = 1;
273                     cmin = mm;
274                     if ( ( alarms[i][0] & 128 ) == 0 ) {
275                         // this alarm won't be repeated
276                         alarms[i] = { 0,0,0,0,0 };
277                         for ( int j = 0; j < 5 ; j++ ) {
278                             RTC.writeData(0x0b + i*5 + j,0);
279                         }
280                     }
281                     break;
282                 }
283             } 
284         }
285     } else {
286         if ( cmin != mm ) {
287             cmin = mm;
288             st++;
289         } 
290     }
294 // ****** LED management **************************************************** //
296 void set_leds() {
297   if ( st > 0 && st <= TIN) {
298       int y = int(float(st*255)/TIN);
299       int r = 255 - y;
300       analogWrite(RPIN,r);
301       analogWrite(YPIN,y);
302   } else if ( st > TIN && st < TDAY ) {
303       analogWrite(RPIN,0);
304       analogWrite(YPIN,255);
305       analogWrite(BPIN,0);
306   } else if (st >= TDAY && st < TOUT) {
307       analogWrite(RPIN,0);
308       analogWrite(YPIN,0);
309       analogWrite(BPIN,255);
310   } else if (st == TOUT) {
311       // reset stuff
312       st = 0;
313       a = -1;
314       analogWrite(RPIN,255);
315       analogWrite(YPIN,0);
316       analogWrite(BPIN,0);
317   }
320 // vim: set filetype=c: