MicrowaveSimulation_LPC1768

Dependencies:   C12832_lcd DebounceInterrupts LM75B mbed-rtos mbed

main.cpp

Committer:
joinamruta
Date:
2014-03-17
Revision:
0:ca76ec016be0

File content as of revision 0:ca76ec016be0:

/********************************************************************************
* Program to implement a microwave. A RTOS program to simulate a microwave      *
* which has the following user features:                                        *  
* i) Left and right buttons to raise/lower the cook time in 1 minute increments *
* ii) Top and bottom buttons to start/stop the microwave                        *
* iii) Middle button to open/close the door                                     *
* iv) Temperature sensor to show the inside temperature                         *
* v) LCD output to show:                                                        *
*  (1) Requested cook time                                                      *
*  (2) Elapsed cook time (max 3 minutes)                                        *
*  (3) Temperature (goes up each minute by 10(?) degrees, starting with room)   *
* vi) LED to show:                                                              *
*  (1) One LED blinking to show cooking in progress                             *
* vii) Short audio sound:                                                       *
*  (1) To indicate cooking done                                                 *
* Timing requirements:                                                          *
*  1. Cooking must stop within 1ms of door opening or stop button               *
*  2. Temperature sensor must be polled once every 10 seconds                   *
*  3. Cooking time must have a 3 min max with a default of 2 min                *
*                                                                               *
*  Test cases:                                                                  *
*  The following test cases are done using black box approach.  If DEBUG is     *
*  enabled, some white box testing can be performed                             *
*                                                                               *
*  Test conditon                     Pass/Fail criteria             Pass/Fail   *
*  =============================== ============================     =========   *
* 1)Push Joystick's LEFT Button    Riase set cook time by 1 minute    PASS      *
*                                  (max 3 mins)                                 *
* 2)Push Joystick's RIGHT Button   Lower set cook time by 1 minute    PASS      *
*                                   (min 1 min)                                 *
* 3)Push Joystick's UP Button      Start microwave cooking IFF        PASS      *
*                                   door is closed                              *
* 4)Push Joystick's DOWN Button    Stop microwave cooking if          PASS      *
*                                   cooking was going on.                       *
* 5)Push Joystick's MIDDLE Button  Toggle between open and close      PASS      *
*                                   door positions.                             *
*                                  LED4 turns on if door open         PASS      *
*                                  LED4 turns off if door closed      PASS      *
* 5.1)If door opened while cooking Suspend cooking immediately        PASS      *
*     was on                                                                    *
* (Debounce handled for all joystick buttons)                                   *                                            
* 6)While cooking session on       LED1 blinks                        PASS      *
*   (STARTED State)                LCD 1)shows elapsed cook time      PASS      *
*                                      2)shows set cook time          PASS      *
*                                      3)shows temperature(up by 10   PASS      *
*                                        deg F each minute of cooking)          *
*                                  Elapsed cook time is checked       PASS      *
*                                  against set cook time to check when          *
*                                  cooking will complete.(COMPLETED STATE)      *
* 7)When cooking suspended         Elapsed cook time suspended        PASS      *
*  (SUSPENDED State) either        LED1 stops blinking                PASS      *
*  due to stop button or door                                                   *
*  open button                                                                  *
* 8)Elapsed cook time equals       Cooking session COMPLETED STATE    PASS      *
*   set cook time                  LED1 stops blinking                PASS      *
*                                  speaker sounds                     PASS      *
*                                                                               *
*********************************************************************************/

#include "mbed.h"
#include "LM75B.h"
#include "C12832_lcd.h"
#include "rtos.h"
#include "DebouncedIn.h"
#include "DebouncedInterrupt.h"
#include "Serial.h"
#include "LM75B.h"


/*default set cook time , 2 minutes*/
#define DEFAULTCOOKTIME 120

/*for door positions*/
#define OPEN 1
#define CLOSE 0

/*to indicate in what state a cooking session is*/
#define STARTED 1
#define COMPLETED 0
#define SUSPENDED 2

/*to test proper functioning*/
#define DEBUG
#ifdef DEBUG
  Serial pc(USBTX, USBRX);
#endif

/*function  declarations*/
void open_door();
void time_up();
void time_down();
void LED_blink (void const *args);
void inside_temperatureLED_blink (void const *args);
void sound_speaker (void const *args);
void start_cooking ();
void stop_cooking ();
void update_lcd(void const *args);
void check_ellapsed_cook_time (void const *args);
void suspendCooking(void const *args);

DebouncedInterrupt increase_time(p13);
DebouncedInterrupt decrease_time(p16);
DebouncedInterrupt start (p12);
DebouncedInterrupt stop(p15);
DebouncedInterrupt door_status(p14);
C12832_LCD lcd;
DigitalOut cook_progress(LED1);
DigitalOut door_signal(LED4);          //This LED will be 1 if door is open
DigitalOut done_cooking(LED2);
PwmOut speaker(p26);
LM75B tmp(p28,p27);

/*set cook time, time for which the cooking should be done*/
int requested_cook_time = DEFAULTCOOKTIME;

/*keep track if door is closed or open CLOSE :0 OPEN:1*/
bool door_position = CLOSE;                      

/*cooking has been suspended or not, either due to opening of door
or stop button pressing while the cooking was going on*/
bool suspended_cooking_flag = false; 

/*inside temp is room temperature*/
float ctemperature;
float temperature;
int count = 0;

/*to indicate whether a particular cooking session has been started 
  or completed.*/
int a_cooking_session = COMPLETED;
Timer ellapsed_cook_timer;
Ticker LED_Blink_timer;
Ticker get_temperature;


/*Open and close door button interrupt service routine*/
void open_door()
{
    /*allow interrupt action to take place only if suspend_cooking 
      action was completed*/
    if (suspended_cooking_flag == false) {
        //toggle door_position
        door_position = !door_position;
        if (door_position == OPEN) {
            door_signal = 1;
            /*if door was opened while cooking was going on
              then suspend cooking immediately*/
            if (a_cooking_session == STARTED) {  
                suspended_cooking_flag = true;
                a_cooking_session = SUSPENDED;
            }
        } else {
            door_signal = 0;
        }
    }
}

/*Raise cook time button interrupt service routine,
  raises the cook time by 1 minute increaments
*/
void time_up()
{
    if (requested_cook_time < 180)
        /*increment cooking time by 1 minute = 60 sec,max = 180 secs.*/
        requested_cook_time = requested_cook_time + 60;
    else
        requested_cook_time = 180;
}


/*lower cook time button interrupt service routine,
  lowers cook time by 1 minute decreaments
*/
void time_down()
{
    if (requested_cook_time > 60)
        /*decrement cooking time by 1 minute = 60 sec*/
        requested_cook_time = requested_cook_time - 60;
    else
        requested_cook_time = 60;

}

/*blink led ticker handler routine.Led blinks at interval
  of 0.250ms while cooking is going on.
*/
void LED_blink ()
{
    cook_progress= !cook_progress;
}

/*temperature ticker handler routine to read inside temperature every 10 secs.
*/
void inside_temperature ()
{
    ctemperature = (1.8)*tmp.read()+32;
    /*to make the temperature displayed on lcd to go up by 10 deg F every minute*/
    if (count < 7) {
       count = count +1;
       if (count == 6) {
            temperature = temperature + 10;
            count = 0;
       }     
    }
}

/*start cooking button interrupt service routine.
*/
void start_cooking ()
{
    if (door_position == CLOSE) {
        if (a_cooking_session != STARTED) {
            if (a_cooking_session == COMPLETED) {
                a_cooking_session = STARTED;//a fresh cooking session has started
                temperature = (1.8)*tmp.read()+32;//starting at room temperature
            }
            if (a_cooking_session == SUSPENDED)
                a_cooking_session = STARTED;//a suspended session restarted 
            ellapsed_cook_timer.start();
            get_temperature.attach(&inside_temperature, 10.0); //read temperature every 10sec
            LED_Blink_timer.attach(&LED_blink,0.250);
        }
    }
}

/*stop cooking button interrupt service routine.
*/
void stop_cooking ()
{
    if (a_cooking_session == STARTED) {
        a_cooking_session = SUSPENDED;
        ellapsed_cook_timer.stop();
        get_temperature.detach();
        LED_Blink_timer.detach();
        cook_progress = 0;
        
    }
}


/*function that sounds the speaker once cooking is completed.
*/
void start_speaker()
{
    speaker.period(1.0/5000);
    while(door_position != OPEN && a_cooking_session == COMPLETED) {
        speaker = 0.5;
        wait(0.1);
        speaker = 0.0;
        wait(0.1);
    }
    speaker = 0.0;
}


/*Thread that displays/updates the :
 (1) Requested cook time
 (2) Elapsed cook time (max 3 minutes)
 (3) Temperature (goes up each minute by 10 degrees(F), starting with room)
*/
void update_lcd(void const *args)
{
    lcd.cls();
    while(true) {
        lcd.locate(0,0);
        lcd.printf("Elapsed time : %0.2f sec",ellapsed_cook_timer.read());
        lcd.locate(0, 8);
        lcd.printf("Set cook time : %d min",requested_cook_time/60);
        lcd.locate(0, 16);
        lcd.printf("Temperature : %0.2f deg F", temperature);
        Thread::wait (1000);
    }
}

/*Thread that keeps track of how much time has elapsed
since cooking is going on(does not includes the time when cooking
suspended)in order to cook for requested amount of cook time
*/
void check_ellapsed_cook_time (void const *args)
{
    Thread suspend_cooking(suspendCooking, NULL, osPriorityHigh);
    #ifdef DEBUG
        pc.printf("Created Thread suspend_cooking\r\n");
    #endif
    while (true) {
        if (suspended_cooking_flag == true)
          suspend_cooking.signal_set(0x1);//IPC
        else {
              if (a_cooking_session == STARTED && (ellapsed_cook_timer.read() >= requested_cook_time) ) {
                  a_cooking_session = COMPLETED;
                  ellapsed_cook_timer.stop();
                  ellapsed_cook_timer.reset();
                  get_temperature.detach();
                  LED_Blink_timer.detach();
                  start_speaker();
              }
        }
        Thread::wait(500);
    }
}

/*Thread that wakes up(on a signal,an IPC mechanism) in order to
complete the remaining activities of stop/suspend cooking(action)
when microwave door  was suddenly opened in the middle of cooking.
When the open door interrupt occurs while cooking was on
the corresponding interrupt service routine wakes this thread up
by sneding a signal to it.
*/
void suspendCooking (void const *args)
{
    while (1) {
            #ifdef DEBUG
                pc.printf("suspend_cooking Thread waiting for signal\r\n");  
            #endif    
            Thread::signal_wait(0x1); //IPC
            #ifdef DEBUG
                pc.printf("suspend_cooking Thread awakened by a siganl\r\n");  
            #endif
            ellapsed_cook_timer.stop();
            //cook_status = OFF;
            get_temperature.detach();
            LED_Blink_timer.detach();
            cook_progress = 0;
            suspended_cooking_flag = false;
    }
}

int main()
{
    increase_time.attach(&time_up);
    decrease_time.attach(&time_down);
    start.attach(&start_cooking);
    stop.attach(&stop_cooking);
    door_status.attach(&open_door);
    door_signal = door_position;
    
    #ifdef DEBUG
        pc.printf("Attached all interrupt handlers\r\n");
    #endif    
    Thread lcd_display(update_lcd, NULL, osPriorityAboveNormal);
    #ifdef DEBUG
        pc.printf("Created Thread lcd_display\r\n");
    #endif
    Thread track_ellapsed_cook_time(check_ellapsed_cook_time, NULL, osPriorityAboveNormal);
    #ifdef DEBUG
        pc.printf("Created Thread track_ellapsed_cook_time\r\n");
    #endif    
          
    while (true) {
      Thread::wait(1500);
    }
}