![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Internet alarm clock
Dependencies: EthernetNetIf NTPClient_NetServices mbed
main.cpp@0:df4b49a4be1a, 2010-10-07 (annotated)
- Committer:
- TyPatrick
- Date:
- Thu Oct 07 19:05:22 2010 +0000
- Revision:
- 0:df4b49a4be1a
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TyPatrick | 0:df4b49a4be1a | 1 | #include "main.h" |
TyPatrick | 0:df4b49a4be1a | 2 | |
TyPatrick | 0:df4b49a4be1a | 3 | /******************************************************************* |
TyPatrick | 0:df4b49a4be1a | 4 | * Print_lcd |
TyPatrick | 0:df4b49a4be1a | 5 | * |
TyPatrick | 0:df4b49a4be1a | 6 | * This function clears the LCD, then either prints 1. the alarm time |
TyPatrick | 0:df4b49a4be1a | 7 | * or 2. the current time and alarm clock menu state. |
TyPatrick | 0:df4b49a4be1a | 8 | ******************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 9 | void print_lcd() |
TyPatrick | 0:df4b49a4be1a | 10 | { |
TyPatrick | 0:df4b49a4be1a | 11 | lcd.cls(); |
TyPatrick | 0:df4b49a4be1a | 12 | /* Menu options 2 and above deal with the alarm */ |
TyPatrick | 0:df4b49a4be1a | 13 | if (menu > 1) |
TyPatrick | 0:df4b49a4be1a | 14 | print_time(ahour, amin); |
TyPatrick | 0:df4b49a4be1a | 15 | else |
TyPatrick | 0:df4b49a4be1a | 16 | print_time(cTime->tm_hour, cTime->tm_min); |
TyPatrick | 0:df4b49a4be1a | 17 | print_menu(); |
TyPatrick | 0:df4b49a4be1a | 18 | } |
TyPatrick | 0:df4b49a4be1a | 19 | |
TyPatrick | 0:df4b49a4be1a | 20 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 21 | * Print_time |
TyPatrick | 0:df4b49a4be1a | 22 | * |
TyPatrick | 0:df4b49a4be1a | 23 | * This function takes an hour(in 24hr time) and a minute and |
TyPatrick | 0:df4b49a4be1a | 24 | * prints the correct format to the lcd. |
TyPatrick | 0:df4b49a4be1a | 25 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 26 | void print_time(int hour, int minute) |
TyPatrick | 0:df4b49a4be1a | 27 | { |
TyPatrick | 0:df4b49a4be1a | 28 | /* Variable tmphr is 24 hour time adjusted for timezone */ |
TyPatrick | 0:df4b49a4be1a | 29 | int tmphr = hour + timezone; |
TyPatrick | 0:df4b49a4be1a | 30 | while (tmphr < 0) |
TyPatrick | 0:df4b49a4be1a | 31 | tmphr += 24; |
TyPatrick | 0:df4b49a4be1a | 32 | tmphr %= 24; |
TyPatrick | 0:df4b49a4be1a | 33 | |
TyPatrick | 0:df4b49a4be1a | 34 | /* Variable printhr is 12 hour time for printing */ |
TyPatrick | 0:df4b49a4be1a | 35 | int printhr = tmphr % 12; |
TyPatrick | 0:df4b49a4be1a | 36 | if (printhr == 0) |
TyPatrick | 0:df4b49a4be1a | 37 | printhr += 12; |
TyPatrick | 0:df4b49a4be1a | 38 | lcd.printf("%2d:%02d ", printhr, minute); |
TyPatrick | 0:df4b49a4be1a | 39 | |
TyPatrick | 0:df4b49a4be1a | 40 | /* tmphr allows for checking of AM/PM */ |
TyPatrick | 0:df4b49a4be1a | 41 | if ((tmphr > 11) && (tmphr < 24)) |
TyPatrick | 0:df4b49a4be1a | 42 | lcd.printf("PM\n"); |
TyPatrick | 0:df4b49a4be1a | 43 | else |
TyPatrick | 0:df4b49a4be1a | 44 | lcd.printf("AM\n"); |
TyPatrick | 0:df4b49a4be1a | 45 | } |
TyPatrick | 0:df4b49a4be1a | 46 | |
TyPatrick | 0:df4b49a4be1a | 47 | /******************************************************************* |
TyPatrick | 0:df4b49a4be1a | 48 | * Print_menu |
TyPatrick | 0:df4b49a4be1a | 49 | * |
TyPatrick | 0:df4b49a4be1a | 50 | * This function prints the menu state of the alarm clock to the LCD. |
TyPatrick | 0:df4b49a4be1a | 51 | * The menu options are 1. Viewing current time 2. Setting Timezone |
TyPatrick | 0:df4b49a4be1a | 52 | * 3. Setting alarm hour 4. Setting alarm minute 5. Toggling alarm |
TyPatrick | 0:df4b49a4be1a | 53 | ******************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 54 | void print_menu() |
TyPatrick | 0:df4b49a4be1a | 55 | { |
TyPatrick | 0:df4b49a4be1a | 56 | switch (menu){ |
TyPatrick | 0:df4b49a4be1a | 57 | case 0: |
TyPatrick | 0:df4b49a4be1a | 58 | break; |
TyPatrick | 0:df4b49a4be1a | 59 | case 1: |
TyPatrick | 0:df4b49a4be1a | 60 | lcd.printf("TZ is (UTC) %+d\n", timezone); |
TyPatrick | 0:df4b49a4be1a | 61 | break; |
TyPatrick | 0:df4b49a4be1a | 62 | case 2: |
TyPatrick | 0:df4b49a4be1a | 63 | lcd.printf("Set Alarm Hour\n"); |
TyPatrick | 0:df4b49a4be1a | 64 | break; |
TyPatrick | 0:df4b49a4be1a | 65 | case 3: |
TyPatrick | 0:df4b49a4be1a | 66 | lcd.printf("Set Alarm Min\n"); |
TyPatrick | 0:df4b49a4be1a | 67 | break; |
TyPatrick | 0:df4b49a4be1a | 68 | case 4: |
TyPatrick | 0:df4b49a4be1a | 69 | lcd.printf("Alarm is "); |
TyPatrick | 0:df4b49a4be1a | 70 | if (alarmstate == false) |
TyPatrick | 0:df4b49a4be1a | 71 | lcd.printf("Off\n"); |
TyPatrick | 0:df4b49a4be1a | 72 | else |
TyPatrick | 0:df4b49a4be1a | 73 | lcd.printf("On\n"); |
TyPatrick | 0:df4b49a4be1a | 74 | break; |
TyPatrick | 0:df4b49a4be1a | 75 | default: |
TyPatrick | 0:df4b49a4be1a | 76 | lcd.printf("Invalid menu %d\n", menu); |
TyPatrick | 0:df4b49a4be1a | 77 | break; |
TyPatrick | 0:df4b49a4be1a | 78 | } |
TyPatrick | 0:df4b49a4be1a | 79 | } |
TyPatrick | 0:df4b49a4be1a | 80 | |
TyPatrick | 0:df4b49a4be1a | 81 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 82 | * Change_menu |
TyPatrick | 0:df4b49a4be1a | 83 | * |
TyPatrick | 0:df4b49a4be1a | 84 | * This function uses a dedicated pushbutton that changes the menu. |
TyPatrick | 0:df4b49a4be1a | 85 | * The state variable, menu, gives the user the ability to cycle |
TyPatrick | 0:df4b49a4be1a | 86 | * through the 5 alarm clock menus. |
TyPatrick | 0:df4b49a4be1a | 87 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 88 | void change_menu() |
TyPatrick | 0:df4b49a4be1a | 89 | { |
TyPatrick | 0:df4b49a4be1a | 90 | alarm_snooze(); |
TyPatrick | 0:df4b49a4be1a | 91 | menu = (menu + 1) % 5; |
TyPatrick | 0:df4b49a4be1a | 92 | print_lcd(); |
TyPatrick | 0:df4b49a4be1a | 93 | } |
TyPatrick | 0:df4b49a4be1a | 94 | |
TyPatrick | 0:df4b49a4be1a | 95 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 96 | * Push_plus |
TyPatrick | 0:df4b49a4be1a | 97 | * |
TyPatrick | 0:df4b49a4be1a | 98 | * This function uses a dedicated pushbutton to only increment or |
TyPatrick | 0:df4b49a4be1a | 99 | * "Add" the value of variables of an alarm clock i.e. minute, hour, |
TyPatrick | 0:df4b49a4be1a | 100 | * time zone |
TyPatrick | 0:df4b49a4be1a | 101 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 102 | void push_plus() |
TyPatrick | 0:df4b49a4be1a | 103 | { |
TyPatrick | 0:df4b49a4be1a | 104 | alarm_snooze(); |
TyPatrick | 0:df4b49a4be1a | 105 | button_press(1); |
TyPatrick | 0:df4b49a4be1a | 106 | } |
TyPatrick | 0:df4b49a4be1a | 107 | |
TyPatrick | 0:df4b49a4be1a | 108 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 109 | * Push_minus |
TyPatrick | 0:df4b49a4be1a | 110 | * |
TyPatrick | 0:df4b49a4be1a | 111 | * This function uses a dedicated pushbutton to only decrement |
TyPatrick | 0:df4b49a4be1a | 112 | * or "Subtract" the value of variables of an alarm clock |
TyPatrick | 0:df4b49a4be1a | 113 | * i.e. minute, hour, time zone |
TyPatrick | 0:df4b49a4be1a | 114 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 115 | void push_minus() |
TyPatrick | 0:df4b49a4be1a | 116 | { |
TyPatrick | 0:df4b49a4be1a | 117 | alarm_snooze(); |
TyPatrick | 0:df4b49a4be1a | 118 | button_press(-1); |
TyPatrick | 0:df4b49a4be1a | 119 | } |
TyPatrick | 0:df4b49a4be1a | 120 | |
TyPatrick | 0:df4b49a4be1a | 121 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 122 | * Button_press |
TyPatrick | 0:df4b49a4be1a | 123 | * |
TyPatrick | 0:df4b49a4be1a | 124 | * This function performs an action based on which menu item is |
TyPatrick | 0:df4b49a4be1a | 125 | * currently selected. It is called whenever the "Add" or |
TyPatrick | 0:df4b49a4be1a | 126 | * "Subtract" button is pressed. |
TyPatrick | 0:df4b49a4be1a | 127 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 128 | void button_press(int input) |
TyPatrick | 0:df4b49a4be1a | 129 | { |
TyPatrick | 0:df4b49a4be1a | 130 | switch (menu) |
TyPatrick | 0:df4b49a4be1a | 131 | { |
TyPatrick | 0:df4b49a4be1a | 132 | case 0: |
TyPatrick | 0:df4b49a4be1a | 133 | break; |
TyPatrick | 0:df4b49a4be1a | 134 | case 1: |
TyPatrick | 0:df4b49a4be1a | 135 | timezone += 12; |
TyPatrick | 0:df4b49a4be1a | 136 | timezone += input; |
TyPatrick | 0:df4b49a4be1a | 137 | while (timezone < 0) |
TyPatrick | 0:df4b49a4be1a | 138 | timezone += 24; |
TyPatrick | 0:df4b49a4be1a | 139 | timezone %= 24; |
TyPatrick | 0:df4b49a4be1a | 140 | timezone -= 12; |
TyPatrick | 0:df4b49a4be1a | 141 | break; |
TyPatrick | 0:df4b49a4be1a | 142 | case 2: |
TyPatrick | 0:df4b49a4be1a | 143 | ahour += input; |
TyPatrick | 0:df4b49a4be1a | 144 | while (ahour < 0) |
TyPatrick | 0:df4b49a4be1a | 145 | ahour += 24; |
TyPatrick | 0:df4b49a4be1a | 146 | ahour %= 24; |
TyPatrick | 0:df4b49a4be1a | 147 | break; |
TyPatrick | 0:df4b49a4be1a | 148 | case 3: |
TyPatrick | 0:df4b49a4be1a | 149 | amin += input; |
TyPatrick | 0:df4b49a4be1a | 150 | while (amin < 0) |
TyPatrick | 0:df4b49a4be1a | 151 | amin += 60; |
TyPatrick | 0:df4b49a4be1a | 152 | amin %= 60; |
TyPatrick | 0:df4b49a4be1a | 153 | break; |
TyPatrick | 0:df4b49a4be1a | 154 | case 4: |
TyPatrick | 0:df4b49a4be1a | 155 | alarmstate = !alarmstate; // Turn alarm on/off |
TyPatrick | 0:df4b49a4be1a | 156 | break; |
TyPatrick | 0:df4b49a4be1a | 157 | default: |
TyPatrick | 0:df4b49a4be1a | 158 | lcd.printf("Invalid state %d\n", menu); |
TyPatrick | 0:df4b49a4be1a | 159 | break; |
TyPatrick | 0:df4b49a4be1a | 160 | } |
TyPatrick | 0:df4b49a4be1a | 161 | print_lcd(); |
TyPatrick | 0:df4b49a4be1a | 162 | } |
TyPatrick | 0:df4b49a4be1a | 163 | |
TyPatrick | 0:df4b49a4be1a | 164 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 165 | * Alarm_ring |
TyPatrick | 0:df4b49a4be1a | 166 | * |
TyPatrick | 0:df4b49a4be1a | 167 | * This function rings the alarm by flashing the leds |
TyPatrick | 0:df4b49a4be1a | 168 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 169 | void alarm_ring() |
TyPatrick | 0:df4b49a4be1a | 170 | { |
TyPatrick | 0:df4b49a4be1a | 171 | if (led == 0x0F) |
TyPatrick | 0:df4b49a4be1a | 172 | led = 0; |
TyPatrick | 0:df4b49a4be1a | 173 | else |
TyPatrick | 0:df4b49a4be1a | 174 | led = (led << 1) | 1; |
TyPatrick | 0:df4b49a4be1a | 175 | } |
TyPatrick | 0:df4b49a4be1a | 176 | |
TyPatrick | 0:df4b49a4be1a | 177 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 178 | * Alarm_snooze |
TyPatrick | 0:df4b49a4be1a | 179 | * |
TyPatrick | 0:df4b49a4be1a | 180 | * This function turns off the alarm |
TyPatrick | 0:df4b49a4be1a | 181 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 182 | void alarm_snooze() |
TyPatrick | 0:df4b49a4be1a | 183 | { |
TyPatrick | 0:df4b49a4be1a | 184 | if (ringflag == true) { |
TyPatrick | 0:df4b49a4be1a | 185 | ringflag = false; |
TyPatrick | 0:df4b49a4be1a | 186 | snooze = true; |
TyPatrick | 0:df4b49a4be1a | 187 | ring.detach(); |
TyPatrick | 0:df4b49a4be1a | 188 | led = 0; |
TyPatrick | 0:df4b49a4be1a | 189 | } |
TyPatrick | 0:df4b49a4be1a | 190 | } |
TyPatrick | 0:df4b49a4be1a | 191 | |
TyPatrick | 0:df4b49a4be1a | 192 | /****************************************************************** |
TyPatrick | 0:df4b49a4be1a | 193 | * Alarm_check |
TyPatrick | 0:df4b49a4be1a | 194 | * |
TyPatrick | 0:df4b49a4be1a | 195 | * This function compares the alarm time vs the current time. Once |
TyPatrick | 0:df4b49a4be1a | 196 | * alarm time and real time match it begins ringing the alarm. |
TyPatrick | 0:df4b49a4be1a | 197 | * Once the times differ then it turns off the alarm. |
TyPatrick | 0:df4b49a4be1a | 198 | *****************************************************************/ |
TyPatrick | 0:df4b49a4be1a | 199 | void alarm_check() |
TyPatrick | 0:df4b49a4be1a | 200 | { |
TyPatrick | 0:df4b49a4be1a | 201 | if ((cTime->tm_min == amin) && (cTime->tm_hour == ahour)) { |
TyPatrick | 0:df4b49a4be1a | 202 | if ((alarmstate == true) && (ringflag == false) && (snooze == false)) { |
TyPatrick | 0:df4b49a4be1a | 203 | ringflag = true; |
TyPatrick | 0:df4b49a4be1a | 204 | ring.attach(&alarm_ring, .5); // Set up a Ticker for the alarm, |
TyPatrick | 0:df4b49a4be1a | 205 | // calls alarm_ring every .5 seconds until stopped |
TyPatrick | 0:df4b49a4be1a | 206 | } |
TyPatrick | 0:df4b49a4be1a | 207 | } |
TyPatrick | 0:df4b49a4be1a | 208 | else { |
TyPatrick | 0:df4b49a4be1a | 209 | alarm_snooze(); |
TyPatrick | 0:df4b49a4be1a | 210 | snooze = false; |
TyPatrick | 0:df4b49a4be1a | 211 | } |
TyPatrick | 0:df4b49a4be1a | 212 | } |
TyPatrick | 0:df4b49a4be1a | 213 | |
TyPatrick | 0:df4b49a4be1a | 214 | int main() { |
TyPatrick | 0:df4b49a4be1a | 215 | |
TyPatrick | 0:df4b49a4be1a | 216 | /* Set up Ethernet */ |
TyPatrick | 0:df4b49a4be1a | 217 | lcd.cls(); |
TyPatrick | 0:df4b49a4be1a | 218 | lcd.printf("Setting up Eth\n"); |
TyPatrick | 0:df4b49a4be1a | 219 | EthernetErr ethErr = eth.setup(); |
TyPatrick | 0:df4b49a4be1a | 220 | if (ethErr) { |
TyPatrick | 0:df4b49a4be1a | 221 | lcd.cls(); |
TyPatrick | 0:df4b49a4be1a | 222 | lcd.printf("Error with Eth\nNum: %d", ethErr); |
TyPatrick | 0:df4b49a4be1a | 223 | return -1; |
TyPatrick | 0:df4b49a4be1a | 224 | } |
TyPatrick | 0:df4b49a4be1a | 225 | |
TyPatrick | 0:df4b49a4be1a | 226 | |
TyPatrick | 0:df4b49a4be1a | 227 | /* Set up NTP */ |
TyPatrick | 0:df4b49a4be1a | 228 | lcd.printf("Setting up NTP\n"); |
TyPatrick | 0:df4b49a4be1a | 229 | Host server(IpAddr(), 123, "0.uk.pool.ntp.org"); |
TyPatrick | 0:df4b49a4be1a | 230 | ntp.setTime(server); |
TyPatrick | 0:df4b49a4be1a | 231 | |
TyPatrick | 0:df4b49a4be1a | 232 | /* Initialize all the interrupts for each of the pushbuttons */ |
TyPatrick | 0:df4b49a4be1a | 233 | statechange.rise(&change_menu); |
TyPatrick | 0:df4b49a4be1a | 234 | plus.rise(&push_plus); |
TyPatrick | 0:df4b49a4be1a | 235 | minus.rise(&push_minus); |
TyPatrick | 0:df4b49a4be1a | 236 | |
TyPatrick | 0:df4b49a4be1a | 237 | /* Temporary variables for control loop */ |
TyPatrick | 0:df4b49a4be1a | 238 | time_t rtc_time = time(NULL); |
TyPatrick | 0:df4b49a4be1a | 239 | int minute = -1; |
TyPatrick | 0:df4b49a4be1a | 240 | |
TyPatrick | 0:df4b49a4be1a | 241 | /* Initialize alarm time */ |
TyPatrick | 0:df4b49a4be1a | 242 | ahour = 0; |
TyPatrick | 0:df4b49a4be1a | 243 | amin = 0; |
TyPatrick | 0:df4b49a4be1a | 244 | |
TyPatrick | 0:df4b49a4be1a | 245 | /* Main control loop */ |
TyPatrick | 0:df4b49a4be1a | 246 | while(1) |
TyPatrick | 0:df4b49a4be1a | 247 | { |
TyPatrick | 0:df4b49a4be1a | 248 | /* Update current time */ |
TyPatrick | 0:df4b49a4be1a | 249 | rtc_time = time(NULL); |
TyPatrick | 0:df4b49a4be1a | 250 | cTime = localtime(&rtc_time); |
TyPatrick | 0:df4b49a4be1a | 251 | |
TyPatrick | 0:df4b49a4be1a | 252 | /* Only redraw the lcd display if anything changes */ |
TyPatrick | 0:df4b49a4be1a | 253 | if (cTime->tm_min != minute) { |
TyPatrick | 0:df4b49a4be1a | 254 | minute = cTime->tm_min; |
TyPatrick | 0:df4b49a4be1a | 255 | print_lcd(); |
TyPatrick | 0:df4b49a4be1a | 256 | |
TyPatrick | 0:df4b49a4be1a | 257 | /* Update time from NTP server if it's midnight UTC */ |
TyPatrick | 0:df4b49a4be1a | 258 | if ((cTime->tm_min == 0) && (cTime->tm_hour == 0)) { |
TyPatrick | 0:df4b49a4be1a | 259 | Host server(IpAddr(), 123, "0.north-america.pool.ntp.org"); |
TyPatrick | 0:df4b49a4be1a | 260 | ntp.setTime(server); |
TyPatrick | 0:df4b49a4be1a | 261 | } |
TyPatrick | 0:df4b49a4be1a | 262 | } |
TyPatrick | 0:df4b49a4be1a | 263 | |
TyPatrick | 0:df4b49a4be1a | 264 | /* Check to see if the alarm should be started/stopped */ |
TyPatrick | 0:df4b49a4be1a | 265 | alarm_check(); |
TyPatrick | 0:df4b49a4be1a | 266 | } |
TyPatrick | 0:df4b49a4be1a | 267 | return 0; |
TyPatrick | 0:df4b49a4be1a | 268 | } |