
Internet alarm clock
Dependencies: EthernetNetIf NTPClient_NetServices mbed
main.cpp
00001 #include "main.h" 00002 00003 /******************************************************************* 00004 * Print_lcd 00005 * 00006 * This function clears the LCD, then either prints 1. the alarm time 00007 * or 2. the current time and alarm clock menu state. 00008 ******************************************************************/ 00009 void print_lcd() 00010 { 00011 lcd.cls(); 00012 /* Menu options 2 and above deal with the alarm */ 00013 if (menu > 1) 00014 print_time(ahour, amin); 00015 else 00016 print_time(cTime->tm_hour, cTime->tm_min); 00017 print_menu(); 00018 } 00019 00020 /****************************************************************** 00021 * Print_time 00022 * 00023 * This function takes an hour(in 24hr time) and a minute and 00024 * prints the correct format to the lcd. 00025 *****************************************************************/ 00026 void print_time(int hour, int minute) 00027 { 00028 /* Variable tmphr is 24 hour time adjusted for timezone */ 00029 int tmphr = hour + timezone; 00030 while (tmphr < 0) 00031 tmphr += 24; 00032 tmphr %= 24; 00033 00034 /* Variable printhr is 12 hour time for printing */ 00035 int printhr = tmphr % 12; 00036 if (printhr == 0) 00037 printhr += 12; 00038 lcd.printf("%2d:%02d ", printhr, minute); 00039 00040 /* tmphr allows for checking of AM/PM */ 00041 if ((tmphr > 11) && (tmphr < 24)) 00042 lcd.printf("PM\n"); 00043 else 00044 lcd.printf("AM\n"); 00045 } 00046 00047 /******************************************************************* 00048 * Print_menu 00049 * 00050 * This function prints the menu state of the alarm clock to the LCD. 00051 * The menu options are 1. Viewing current time 2. Setting Timezone 00052 * 3. Setting alarm hour 4. Setting alarm minute 5. Toggling alarm 00053 ******************************************************************/ 00054 void print_menu() 00055 { 00056 switch (menu){ 00057 case 0: 00058 break; 00059 case 1: 00060 lcd.printf("TZ is (UTC) %+d\n", timezone); 00061 break; 00062 case 2: 00063 lcd.printf("Set Alarm Hour\n"); 00064 break; 00065 case 3: 00066 lcd.printf("Set Alarm Min\n"); 00067 break; 00068 case 4: 00069 lcd.printf("Alarm is "); 00070 if (alarmstate == false) 00071 lcd.printf("Off\n"); 00072 else 00073 lcd.printf("On\n"); 00074 break; 00075 default: 00076 lcd.printf("Invalid menu %d\n", menu); 00077 break; 00078 } 00079 } 00080 00081 /****************************************************************** 00082 * Change_menu 00083 * 00084 * This function uses a dedicated pushbutton that changes the menu. 00085 * The state variable, menu, gives the user the ability to cycle 00086 * through the 5 alarm clock menus. 00087 *****************************************************************/ 00088 void change_menu() 00089 { 00090 alarm_snooze(); 00091 menu = (menu + 1) % 5; 00092 print_lcd(); 00093 } 00094 00095 /****************************************************************** 00096 * Push_plus 00097 * 00098 * This function uses a dedicated pushbutton to only increment or 00099 * "Add" the value of variables of an alarm clock i.e. minute, hour, 00100 * time zone 00101 *****************************************************************/ 00102 void push_plus() 00103 { 00104 alarm_snooze(); 00105 button_press(1); 00106 } 00107 00108 /****************************************************************** 00109 * Push_minus 00110 * 00111 * This function uses a dedicated pushbutton to only decrement 00112 * or "Subtract" the value of variables of an alarm clock 00113 * i.e. minute, hour, time zone 00114 *****************************************************************/ 00115 void push_minus() 00116 { 00117 alarm_snooze(); 00118 button_press(-1); 00119 } 00120 00121 /****************************************************************** 00122 * Button_press 00123 * 00124 * This function performs an action based on which menu item is 00125 * currently selected. It is called whenever the "Add" or 00126 * "Subtract" button is pressed. 00127 *****************************************************************/ 00128 void button_press(int input) 00129 { 00130 switch (menu) 00131 { 00132 case 0: 00133 break; 00134 case 1: 00135 timezone += 12; 00136 timezone += input; 00137 while (timezone < 0) 00138 timezone += 24; 00139 timezone %= 24; 00140 timezone -= 12; 00141 break; 00142 case 2: 00143 ahour += input; 00144 while (ahour < 0) 00145 ahour += 24; 00146 ahour %= 24; 00147 break; 00148 case 3: 00149 amin += input; 00150 while (amin < 0) 00151 amin += 60; 00152 amin %= 60; 00153 break; 00154 case 4: 00155 alarmstate = !alarmstate; // Turn alarm on/off 00156 break; 00157 default: 00158 lcd.printf("Invalid state %d\n", menu); 00159 break; 00160 } 00161 print_lcd(); 00162 } 00163 00164 /****************************************************************** 00165 * Alarm_ring 00166 * 00167 * This function rings the alarm by flashing the leds 00168 *****************************************************************/ 00169 void alarm_ring() 00170 { 00171 if (led == 0x0F) 00172 led = 0; 00173 else 00174 led = (led << 1) | 1; 00175 } 00176 00177 /****************************************************************** 00178 * Alarm_snooze 00179 * 00180 * This function turns off the alarm 00181 *****************************************************************/ 00182 void alarm_snooze() 00183 { 00184 if (ringflag == true) { 00185 ringflag = false; 00186 snooze = true; 00187 ring.detach(); 00188 led = 0; 00189 } 00190 } 00191 00192 /****************************************************************** 00193 * Alarm_check 00194 * 00195 * This function compares the alarm time vs the current time. Once 00196 * alarm time and real time match it begins ringing the alarm. 00197 * Once the times differ then it turns off the alarm. 00198 *****************************************************************/ 00199 void alarm_check() 00200 { 00201 if ((cTime->tm_min == amin) && (cTime->tm_hour == ahour)) { 00202 if ((alarmstate == true) && (ringflag == false) && (snooze == false)) { 00203 ringflag = true; 00204 ring.attach(&alarm_ring, .5); // Set up a Ticker for the alarm, 00205 // calls alarm_ring every .5 seconds until stopped 00206 } 00207 } 00208 else { 00209 alarm_snooze(); 00210 snooze = false; 00211 } 00212 } 00213 00214 int main() { 00215 00216 /* Set up Ethernet */ 00217 lcd.cls(); 00218 lcd.printf("Setting up Eth\n"); 00219 EthernetErr ethErr = eth.setup(); 00220 if (ethErr) { 00221 lcd.cls(); 00222 lcd.printf("Error with Eth\nNum: %d", ethErr); 00223 return -1; 00224 } 00225 00226 00227 /* Set up NTP */ 00228 lcd.printf("Setting up NTP\n"); 00229 Host server(IpAddr(), 123, "0.uk.pool.ntp.org"); 00230 ntp.setTime(server); 00231 00232 /* Initialize all the interrupts for each of the pushbuttons */ 00233 statechange.rise(&change_menu); 00234 plus.rise(&push_plus); 00235 minus.rise(&push_minus); 00236 00237 /* Temporary variables for control loop */ 00238 time_t rtc_time = time(NULL); 00239 int minute = -1; 00240 00241 /* Initialize alarm time */ 00242 ahour = 0; 00243 amin = 0; 00244 00245 /* Main control loop */ 00246 while(1) 00247 { 00248 /* Update current time */ 00249 rtc_time = time(NULL); 00250 cTime = localtime(&rtc_time); 00251 00252 /* Only redraw the lcd display if anything changes */ 00253 if (cTime->tm_min != minute) { 00254 minute = cTime->tm_min; 00255 print_lcd(); 00256 00257 /* Update time from NTP server if it's midnight UTC */ 00258 if ((cTime->tm_min == 0) && (cTime->tm_hour == 0)) { 00259 Host server(IpAddr(), 123, "0.north-america.pool.ntp.org"); 00260 ntp.setTime(server); 00261 } 00262 } 00263 00264 /* Check to see if the alarm should be started/stopped */ 00265 alarm_check(); 00266 } 00267 return 0; 00268 }
Generated on Sun Jul 17 2022 01:39:49 by
