MicrowaveSimulation_LPC1768

Dependencies:   C12832_lcd DebounceInterrupts LM75B mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /********************************************************************************
00002 * Program to implement a microwave. A RTOS program to simulate a microwave      *
00003 * which has the following user features:                                        *  
00004 * i) Left and right buttons to raise/lower the cook time in 1 minute increments *
00005 * ii) Top and bottom buttons to start/stop the microwave                        *
00006 * iii) Middle button to open/close the door                                     *
00007 * iv) Temperature sensor to show the inside temperature                         *
00008 * v) LCD output to show:                                                        *
00009 *  (1) Requested cook time                                                      *
00010 *  (2) Elapsed cook time (max 3 minutes)                                        *
00011 *  (3) Temperature (goes up each minute by 10(?) degrees, starting with room)   *
00012 * vi) LED to show:                                                              *
00013 *  (1) One LED blinking to show cooking in progress                             *
00014 * vii) Short audio sound:                                                       *
00015 *  (1) To indicate cooking done                                                 *
00016 * Timing requirements:                                                          *
00017 *  1. Cooking must stop within 1ms of door opening or stop button               *
00018 *  2. Temperature sensor must be polled once every 10 seconds                   *
00019 *  3. Cooking time must have a 3 min max with a default of 2 min                *
00020 *                                                                               *
00021 *  Test cases:                                                                  *
00022 *  The following test cases are done using black box approach.  If DEBUG is     *
00023 *  enabled, some white box testing can be performed                             *
00024 *                                                                               *
00025 *  Test conditon                     Pass/Fail criteria             Pass/Fail   *
00026 *  =============================== ============================     =========   *
00027 * 1)Push Joystick's LEFT Button    Riase set cook time by 1 minute    PASS      *
00028 *                                  (max 3 mins)                                 *
00029 * 2)Push Joystick's RIGHT Button   Lower set cook time by 1 minute    PASS      *
00030 *                                   (min 1 min)                                 *
00031 * 3)Push Joystick's UP Button      Start microwave cooking IFF        PASS      *
00032 *                                   door is closed                              *
00033 * 4)Push Joystick's DOWN Button    Stop microwave cooking if          PASS      *
00034 *                                   cooking was going on.                       *
00035 * 5)Push Joystick's MIDDLE Button  Toggle between open and close      PASS      *
00036 *                                   door positions.                             *
00037 *                                  LED4 turns on if door open         PASS      *
00038 *                                  LED4 turns off if door closed      PASS      *
00039 * 5.1)If door opened while cooking Suspend cooking immediately        PASS      *
00040 *     was on                                                                    *
00041 * (Debounce handled for all joystick buttons)                                   *                                            
00042 * 6)While cooking session on       LED1 blinks                        PASS      *
00043 *   (STARTED State)                LCD 1)shows elapsed cook time      PASS      *
00044 *                                      2)shows set cook time          PASS      *
00045 *                                      3)shows temperature(up by 10   PASS      *
00046 *                                        deg F each minute of cooking)          *
00047 *                                  Elapsed cook time is checked       PASS      *
00048 *                                  against set cook time to check when          *
00049 *                                  cooking will complete.(COMPLETED STATE)      *
00050 * 7)When cooking suspended         Elapsed cook time suspended        PASS      *
00051 *  (SUSPENDED State) either        LED1 stops blinking                PASS      *
00052 *  due to stop button or door                                                   *
00053 *  open button                                                                  *
00054 * 8)Elapsed cook time equals       Cooking session COMPLETED STATE    PASS      *
00055 *   set cook time                  LED1 stops blinking                PASS      *
00056 *                                  speaker sounds                     PASS      *
00057 *                                                                               *
00058 *********************************************************************************/
00059 
00060 #include "mbed.h"
00061 #include "LM75B.h"
00062 #include "C12832_lcd.h"
00063 #include "rtos.h"
00064 #include "DebouncedIn.h"
00065 #include "DebouncedInterrupt.h"
00066 #include "Serial.h"
00067 #include "LM75B.h"
00068 
00069 
00070 /*default set cook time , 2 minutes*/
00071 #define DEFAULTCOOKTIME 120
00072 
00073 /*for door positions*/
00074 #define OPEN 1
00075 #define CLOSE 0
00076 
00077 /*to indicate in what state a cooking session is*/
00078 #define STARTED 1
00079 #define COMPLETED 0
00080 #define SUSPENDED 2
00081 
00082 /*to test proper functioning*/
00083 #define DEBUG
00084 #ifdef DEBUG
00085   Serial pc(USBTX, USBRX);
00086 #endif
00087 
00088 /*function  declarations*/
00089 void open_door();
00090 void time_up();
00091 void time_down();
00092 void LED_blink (void const *args);
00093 void inside_temperatureLED_blink (void const *args);
00094 void sound_speaker (void const *args);
00095 void start_cooking ();
00096 void stop_cooking ();
00097 void update_lcd(void const *args);
00098 void check_ellapsed_cook_time (void const *args);
00099 void suspendCooking(void const *args);
00100 
00101 DebouncedInterrupt increase_time(p13);
00102 DebouncedInterrupt decrease_time(p16);
00103 DebouncedInterrupt start (p12);
00104 DebouncedInterrupt stop(p15);
00105 DebouncedInterrupt door_status(p14);
00106 C12832_LCD lcd;
00107 DigitalOut cook_progress(LED1);
00108 DigitalOut door_signal(LED4);          //This LED will be 1 if door is open
00109 DigitalOut done_cooking(LED2);
00110 PwmOut speaker(p26);
00111 LM75B tmp(p28,p27);
00112 
00113 /*set cook time, time for which the cooking should be done*/
00114 int requested_cook_time = DEFAULTCOOKTIME;
00115 
00116 /*keep track if door is closed or open CLOSE :0 OPEN:1*/
00117 bool door_position = CLOSE;                      
00118 
00119 /*cooking has been suspended or not, either due to opening of door
00120 or stop button pressing while the cooking was going on*/
00121 bool suspended_cooking_flag = false; 
00122 
00123 /*inside temp is room temperature*/
00124 float ctemperature;
00125 float temperature;
00126 int count = 0;
00127 
00128 /*to indicate whether a particular cooking session has been started 
00129   or completed.*/
00130 int a_cooking_session = COMPLETED;
00131 Timer ellapsed_cook_timer;
00132 Ticker LED_Blink_timer;
00133 Ticker get_temperature;
00134 
00135 
00136 /*Open and close door button interrupt service routine*/
00137 void open_door()
00138 {
00139     /*allow interrupt action to take place only if suspend_cooking 
00140       action was completed*/
00141     if (suspended_cooking_flag == false) {
00142         //toggle door_position
00143         door_position = !door_position;
00144         if (door_position == OPEN) {
00145             door_signal = 1;
00146             /*if door was opened while cooking was going on
00147               then suspend cooking immediately*/
00148             if (a_cooking_session == STARTED) {  
00149                 suspended_cooking_flag = true;
00150                 a_cooking_session = SUSPENDED;
00151             }
00152         } else {
00153             door_signal = 0;
00154         }
00155     }
00156 }
00157 
00158 /*Raise cook time button interrupt service routine,
00159   raises the cook time by 1 minute increaments
00160 */
00161 void time_up()
00162 {
00163     if (requested_cook_time < 180)
00164         /*increment cooking time by 1 minute = 60 sec,max = 180 secs.*/
00165         requested_cook_time = requested_cook_time + 60;
00166     else
00167         requested_cook_time = 180;
00168 }
00169 
00170 
00171 /*lower cook time button interrupt service routine,
00172   lowers cook time by 1 minute decreaments
00173 */
00174 void time_down()
00175 {
00176     if (requested_cook_time > 60)
00177         /*decrement cooking time by 1 minute = 60 sec*/
00178         requested_cook_time = requested_cook_time - 60;
00179     else
00180         requested_cook_time = 60;
00181 
00182 }
00183 
00184 /*blink led ticker handler routine.Led blinks at interval
00185   of 0.250ms while cooking is going on.
00186 */
00187 void LED_blink ()
00188 {
00189     cook_progress= !cook_progress;
00190 }
00191 
00192 /*temperature ticker handler routine to read inside temperature every 10 secs.
00193 */
00194 void inside_temperature ()
00195 {
00196     ctemperature = (1.8)*tmp.read()+32;
00197     /*to make the temperature displayed on lcd to go up by 10 deg F every minute*/
00198     if (count < 7) {
00199        count = count +1;
00200        if (count == 6) {
00201             temperature = temperature + 10;
00202             count = 0;
00203        }     
00204     }
00205 }
00206 
00207 /*start cooking button interrupt service routine.
00208 */
00209 void start_cooking ()
00210 {
00211     if (door_position == CLOSE) {
00212         if (a_cooking_session != STARTED) {
00213             if (a_cooking_session == COMPLETED) {
00214                 a_cooking_session = STARTED;//a fresh cooking session has started
00215                 temperature = (1.8)*tmp.read()+32;//starting at room temperature
00216             }
00217             if (a_cooking_session == SUSPENDED)
00218                 a_cooking_session = STARTED;//a suspended session restarted 
00219             ellapsed_cook_timer.start();
00220             get_temperature.attach(&inside_temperature, 10.0); //read temperature every 10sec
00221             LED_Blink_timer.attach(&LED_blink,0.250);
00222         }
00223     }
00224 }
00225 
00226 /*stop cooking button interrupt service routine.
00227 */
00228 void stop_cooking ()
00229 {
00230     if (a_cooking_session == STARTED) {
00231         a_cooking_session = SUSPENDED;
00232         ellapsed_cook_timer.stop();
00233         get_temperature.detach();
00234         LED_Blink_timer.detach();
00235         cook_progress = 0;
00236         
00237     }
00238 }
00239 
00240 
00241 /*function that sounds the speaker once cooking is completed.
00242 */
00243 void start_speaker()
00244 {
00245     speaker.period(1.0/5000);
00246     while(door_position != OPEN && a_cooking_session == COMPLETED) {
00247         speaker = 0.5;
00248         wait(0.1);
00249         speaker = 0.0;
00250         wait(0.1);
00251     }
00252     speaker = 0.0;
00253 }
00254 
00255 
00256 /*Thread that displays/updates the :
00257  (1) Requested cook time
00258  (2) Elapsed cook time (max 3 minutes)
00259  (3) Temperature (goes up each minute by 10 degrees(F), starting with room)
00260 */
00261 void update_lcd(void const *args)
00262 {
00263     lcd.cls();
00264     while(true) {
00265         lcd.locate(0,0);
00266         lcd.printf("Elapsed time : %0.2f sec",ellapsed_cook_timer.read());
00267         lcd.locate(0, 8);
00268         lcd.printf("Set cook time : %d min",requested_cook_time/60);
00269         lcd.locate(0, 16);
00270         lcd.printf("Temperature : %0.2f deg F", temperature);
00271         Thread::wait (1000);
00272     }
00273 }
00274 
00275 /*Thread that keeps track of how much time has elapsed
00276 since cooking is going on(does not includes the time when cooking
00277 suspended)in order to cook for requested amount of cook time
00278 */
00279 void check_ellapsed_cook_time (void const *args)
00280 {
00281     Thread suspend_cooking(suspendCooking, NULL, osPriorityHigh);
00282     #ifdef DEBUG
00283         pc.printf("Created Thread suspend_cooking\r\n");
00284     #endif
00285     while (true) {
00286         if (suspended_cooking_flag == true)
00287           suspend_cooking.signal_set(0x1);//IPC
00288         else {
00289               if (a_cooking_session == STARTED && (ellapsed_cook_timer.read() >= requested_cook_time) ) {
00290                   a_cooking_session = COMPLETED;
00291                   ellapsed_cook_timer.stop();
00292                   ellapsed_cook_timer.reset();
00293                   get_temperature.detach();
00294                   LED_Blink_timer.detach();
00295                   start_speaker();
00296               }
00297         }
00298         Thread::wait(500);
00299     }
00300 }
00301 
00302 /*Thread that wakes up(on a signal,an IPC mechanism) in order to
00303 complete the remaining activities of stop/suspend cooking(action)
00304 when microwave door  was suddenly opened in the middle of cooking.
00305 When the open door interrupt occurs while cooking was on
00306 the corresponding interrupt service routine wakes this thread up
00307 by sneding a signal to it.
00308 */
00309 void suspendCooking (void const *args)
00310 {
00311     while (1) {
00312             #ifdef DEBUG
00313                 pc.printf("suspend_cooking Thread waiting for signal\r\n");  
00314             #endif    
00315             Thread::signal_wait(0x1); //IPC
00316             #ifdef DEBUG
00317                 pc.printf("suspend_cooking Thread awakened by a siganl\r\n");  
00318             #endif
00319             ellapsed_cook_timer.stop();
00320             //cook_status = OFF;
00321             get_temperature.detach();
00322             LED_Blink_timer.detach();
00323             cook_progress = 0;
00324             suspended_cooking_flag = false;
00325     }
00326 }
00327 
00328 int main()
00329 {
00330     increase_time.attach(&time_up);
00331     decrease_time.attach(&time_down);
00332     start.attach(&start_cooking);
00333     stop.attach(&stop_cooking);
00334     door_status.attach(&open_door);
00335     door_signal = door_position;
00336     
00337     #ifdef DEBUG
00338         pc.printf("Attached all interrupt handlers\r\n");
00339     #endif    
00340     Thread lcd_display(update_lcd, NULL, osPriorityAboveNormal);
00341     #ifdef DEBUG
00342         pc.printf("Created Thread lcd_display\r\n");
00343     #endif
00344     Thread track_ellapsed_cook_time(check_ellapsed_cook_time, NULL, osPriorityAboveNormal);
00345     #ifdef DEBUG
00346         pc.printf("Created Thread track_ellapsed_cook_time\r\n");
00347     #endif    
00348           
00349     while (true) {
00350       Thread::wait(1500);
00351     }
00352 }