Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: C12832_lcd LM75B mbed
main.cpp
00001 #include "mbed.h" 00002 00003 #include "LM75B.h" 00004 #include "C12832_lcd.h" 00005 #include "keypad.h" 00006 00007 // uncomment to allow DEBUG 00008 //#define DEBUG 00009 00010 #define BUTTON_LEFT (p13) 00011 #define BUTTON_RIGHT (p16) 00012 #define BUTTON_START (p15) 00013 #define BUTTON_STOP (p12) 00014 #define BUTTON_DOOR (p14) 00015 #define TEMP_SCL (p27) 00016 #define TEMP_SDA (p28) 00017 #define ALARM (p26) 00018 00019 #define DOOR_CLOSED (0) 00020 #define DOOR_OPEN (1) 00021 00022 #define LED_OFF (0) 00023 #define LED_ON (1) 00024 00025 #define TRUE (1) 00026 #define FALSE (0) 00027 00028 #define MIN_COOKING_TIME (0) // secs 00029 #define MAX_COOKING_TIME (180) 00030 #define COOKING_TIME_INCREMENT (60) 00031 #define MAX_TICKER_TIME (60) 00032 #define WDOG_TIME (1) 00033 00034 #define TEMP_INCREMENT (10.0f) // degC 00035 00036 typedef enum 00037 { 00038 STATUS_IDLE = 0, 00039 STATUS_COOKING, 00040 STATUS_DONE 00041 } etSTATUS; 00042 00043 #ifdef DEBUG 00044 #define MAX_LATENCY (10) // msec 00045 #define ERROR_MICROWAVE_SM (1L<<0) 00046 #define ERROR_LATENCY_DOOR (1L<<1) 00047 #define ERROR_LATENCY_STOP (1L<<2) 00048 #endif /* DEBUG */ 00049 00050 // forward declarations 00051 void init_microwave(void); 00052 void press_left(void); 00053 void press_right(void); 00054 void press_start(void); 00055 void press_stop(void); 00056 void press_door(void); 00057 void wdog_update(void); 00058 void update_output(void); 00059 00060 void microwave_sm(void); // microwave state machine 00061 00062 // input peripherals 00063 Keypad keypad( BUTTON_LEFT, press_left, // keypad 00064 BUTTON_RIGHT, press_right, 00065 BUTTON_START, press_start, 00066 BUTTON_STOP, press_stop, 00067 BUTTON_DOOR, press_door ); 00068 LM75B tmp(TEMP_SDA,TEMP_SCL); // temperature sensor 00069 00070 00071 // output peripherals 00072 C12832_LCD lcd; // LCD screen 00073 DigitalOut cooking_status(LED1); // LED for cooking progress 00074 DigitalOut carousel_status(LED2); // LED for carousel 00075 #ifdef DEBUG 00076 DigitalOut debugLED(LED4); // general debug LED 00077 #endif /* DEBUG */ 00078 PwmOut alarm(ALARM); // alarm 00079 00080 // Timers 00081 Ticker wdog; // 1sec watchdog 00082 #ifdef DEBUG 00083 Timer latency_wdog; 00084 #endif /* DEBUG */ 00085 00086 // global status variables 00087 volatile signed short ssCookingTime; 00088 unsigned char ucDoorStatus = DOOR_CLOSED; 00089 float fTemp = 0.0f; 00090 etSTATUS opStatus; 00091 volatile unsigned char start_requested; 00092 volatile unsigned char stop_requested; 00093 volatile unsigned char temp_ticker; 00094 unsigned char reset_wdog; 00095 #ifdef DEBUG 00096 unsigned long ulErrorCode = 0UL; 00097 #endif /* DEBUG */ 00098 00099 /* Name: main() 00100 * Desc: entry point of application. This will also invoke the microwave 00101 * state machine and update output 00102 * Inputs: none 00103 * Outputs: none 00104 */ 00105 int main() 00106 { 00107 unsigned int while_loop_counter = 0; 00108 00109 init_microwave(); 00110 00111 while(1) 00112 { 00113 while_loop_counter++; 00114 00115 microwave_sm(); // execute state machine 00116 00117 // do not need to update LCD as often 00118 if ( while_loop_counter & 0x4000 ) 00119 { 00120 update_output(); 00121 } 00122 } 00123 } 00124 00125 /* Name: init_microwave() 00126 * Desc: initializes the microwave state machine to STATUS_IDLE 00127 * Inputs: none 00128 * Outputs: none 00129 */ 00130 void init_microwave(void) 00131 { 00132 ssCookingTime = 0L; 00133 cooking_status = LED_OFF; 00134 carousel_status = LED_OFF; 00135 opStatus = STATUS_IDLE; 00136 start_requested = FALSE; 00137 stop_requested = FALSE; 00138 reset_wdog = FALSE; 00139 } 00140 00141 /* Name: press_left() 00142 * Desc: ISR callback function for left button. 00143 * Inputs: none 00144 * Outputs: none 00145 */ 00146 void press_left(void) 00147 { 00148 if ( opStatus == STATUS_DONE ) 00149 { 00150 return; 00151 } 00152 ssCookingTime += COOKING_TIME_INCREMENT; 00153 if ( ssCookingTime >= MAX_COOKING_TIME ) 00154 { 00155 ssCookingTime = MAX_COOKING_TIME; 00156 } 00157 } 00158 00159 /* Name: press_right() 00160 * Desc: ISR callback function for right button. 00161 * Inputs: none 00162 * Outputs: none 00163 */ 00164 void press_right(void) 00165 { 00166 if ( opStatus != STATUS_IDLE ) 00167 { 00168 return; 00169 } 00170 ssCookingTime -= COOKING_TIME_INCREMENT; 00171 if ( ssCookingTime <= MIN_COOKING_TIME ) 00172 { 00173 ssCookingTime = MIN_COOKING_TIME; 00174 } 00175 } 00176 00177 /* Name: press_start() 00178 * Desc: ISR callback function for start button. 00179 * Inputs: none 00180 * Outputs: none 00181 */ 00182 void press_start(void) 00183 { 00184 if ( opStatus != STATUS_IDLE ) 00185 { 00186 return; 00187 } 00188 00189 if ( ssCookingTime && (ucDoorStatus == DOOR_CLOSED) ) 00190 { 00191 start_requested = TRUE; 00192 } 00193 } 00194 00195 /* Name: press_stop() 00196 * Desc: ISR callback function for stop button. 00197 * Inputs: none 00198 * Outputs: none 00199 */ 00200 void press_stop(void) 00201 { 00202 if ( opStatus == STATUS_IDLE ) 00203 { 00204 init_microwave(); 00205 return; 00206 } 00207 else 00208 { 00209 #ifdef DEBUG 00210 latency_wdog.start(); 00211 #endif 00212 stop_requested = TRUE; 00213 } 00214 } 00215 00216 /* Name: press_door() 00217 * Desc: ISR callback function for door button. 00218 * Inputs: none 00219 * Outputs: none 00220 */ 00221 void press_door(void) 00222 { 00223 ucDoorStatus = !ucDoorStatus; 00224 if ( opStatus == STATUS_COOKING ) 00225 { 00226 #ifdef DEBUG 00227 latency_wdog.start(); 00228 #endif 00229 } 00230 } 00231 00232 /* Name: wdog_update() 00233 * Desc: callback function for watchdog timer. This watchog updates the 00234 * cooking time when the microwave is running (STATUS_COOKING). 00235 * Inputs: none 00236 * Outputs: none 00237 */ 00238 void wdog_update(void) 00239 { 00240 if ( opStatus == STATUS_COOKING ) 00241 { 00242 ssCookingTime--; 00243 00244 // reset wdog 00245 if ( ssCookingTime ) 00246 { 00247 reset_wdog = TRUE; 00248 } 00249 00250 if ( temp_ticker ) 00251 { 00252 temp_ticker--; 00253 } 00254 } 00255 } 00256 00257 /* Name: microwave_sm() 00258 * Desc: This is the microwave state machine. It processes all input and 00259 * updates all state variables. 00260 * Inputs: none 00261 * Outputs: none 00262 */ 00263 void microwave_sm(void) 00264 { 00265 switch ( opStatus ) 00266 { 00267 case STATUS_IDLE: 00268 if ( ssCookingTime && !ucDoorStatus && start_requested ) 00269 { 00270 fTemp = tmp.read(); 00271 start_requested = FALSE; 00272 wdog.attach(wdog_update, 1); 00273 temp_ticker = (ssCookingTime > MAX_TICKER_TIME) ? MAX_TICKER_TIME : ssCookingTime; 00274 opStatus = STATUS_COOKING; 00275 } 00276 break; 00277 00278 case STATUS_COOKING: 00279 if ( ucDoorStatus == DOOR_OPEN ) 00280 { 00281 #ifdef DEBUG 00282 if (latency_wdog.read_ms() > MAX_LATENCY) 00283 { 00284 ulErrorCode |= ERROR_LATENCY_DOOR; 00285 } 00286 latency_wdog.stop(); 00287 #endif /* DEBUG */ 00288 init_microwave(); 00289 } 00290 else if ( stop_requested ) 00291 { 00292 #ifdef DEBUG 00293 if (latency_wdog.read_ms() > MAX_LATENCY) 00294 { 00295 ulErrorCode |= ERROR_LATENCY_STOP; 00296 } 00297 latency_wdog.stop(); 00298 #endif /* DEBUG */ 00299 init_microwave(); 00300 } 00301 else 00302 { 00303 if ( !ssCookingTime ) 00304 { 00305 opStatus = STATUS_DONE; 00306 } 00307 if ( !temp_ticker ) 00308 { 00309 fTemp += TEMP_INCREMENT; 00310 temp_ticker = (ssCookingTime > MAX_TICKER_TIME) ? MAX_TICKER_TIME : ssCookingTime; 00311 } 00312 if ( reset_wdog ) 00313 { 00314 wdog.attach(wdog_update, 1); 00315 reset_wdog = FALSE; 00316 } 00317 } 00318 break; 00319 00320 case STATUS_DONE: 00321 if ( ucDoorStatus == DOOR_OPEN || stop_requested ) 00322 { 00323 init_microwave(); 00324 } 00325 break; 00326 00327 default: 00328 #ifdef DEBUG 00329 // something is wrong if we got here! 00330 ulErrorCode |= ERROR_MICROWAVE_SM; 00331 #endif /* DEBUG */ 00332 break; 00333 } 00334 } 00335 00336 /* Name: update_output() 00337 * Desc: Updates all output based on status variables. 00338 * Inputs: none 00339 * Outputs: none 00340 */ 00341 void update_output(void) 00342 { 00343 static unsigned char toggle_alarm = 0; 00344 static unsigned char toggle_leds = 0; 00345 static etSTATUS previousState = (etSTATUS) 0xFF; 00346 00347 // clear the screen only when we transition states to prevent flicker 00348 if ( previousState != opStatus ) 00349 { 00350 lcd.cls(); 00351 previousState = opStatus; 00352 } 00353 lcd.locate(0,0); 00354 lcd.printf("Cooking Time: %3d secs\n",ssCookingTime); 00355 00356 switch ( opStatus ) 00357 { 00358 case STATUS_IDLE: 00359 // alarm should be off in this state 00360 toggle_alarm = 0; 00361 alarm = 0.0; 00362 break; 00363 00364 case STATUS_COOKING: 00365 // display temp 00366 lcd.locate(0,10); 00367 lcd.printf("Temp: %.2f degC\n", fTemp); 00368 00369 // update LEDs 00370 toggle_leds++; 00371 if ( toggle_leds & 0x10 ) 00372 { 00373 cooking_status = !cooking_status; 00374 carousel_status = !carousel_status; 00375 } 00376 00377 // alarm should be off in this state 00378 toggle_alarm = 0; 00379 alarm = 0.0; 00380 break; 00381 00382 case STATUS_DONE: 00383 // LEDs off in this state 00384 cooking_status = LED_OFF; 00385 carousel_status = LED_OFF; 00386 00387 // sound alarm 00388 toggle_alarm++; 00389 if ( toggle_alarm & 0x10 ) 00390 { 00391 alarm.period(1.0/5000); 00392 alarm = 0.5; 00393 } 00394 else 00395 { 00396 alarm = 0.0; 00397 } 00398 00399 lcd.locate(0,10); 00400 lcd.printf("ENJOY YOUR MEAL!\n"); 00401 break; 00402 } 00403 lcd.locate(0,23); 00404 lcd.printf("door %s\n", ucDoorStatus ? "open " : "closed"); 00405 #ifdef DEBUG 00406 lcd.locate(95,23); 00407 lcd.printf("0x%04X\n", ulErrorCode); 00408 #endif /* DEBUG */ 00409 }
Generated on Sat Jul 16 2022 20:54:38 by
1.7.2