microwave simulator
Dependencies: C12832_lcd LM75B mbed
main.cpp
- Committer:
- rabad1
- Date:
- 2013-10-18
- Revision:
- 0:2f825861a3a2
- Child:
- 1:fac01d40d819
File content as of revision 0:2f825861a3a2:
#include "mbed.h" #include "LM75B.h" #include "C12832_lcd.h" #include "keypad.h" // uncomment to allow DEBUG #define DEBUG #define BUTTON_LEFT (p13) #define BUTTON_RIGHT (p16) #define BUTTON_START (p15) #define BUTTON_STOP (p12) #define BUTTON_DOOR (p14) #define DOOR_CLOSED (0) #define DOOR_OPEN (1) #define LED_OFF (0) #define LED_ON (1) #define TRUE (1) #define FALSE (0) #define MIN_COOKING_TIME (0) // secs #define MAX_COOKING_TIME (180) #define COOKING_TIME_INCREMENT (60) #define MAX_TICKER_TIME (60) #define WDOG_TIME (1) #define WHILE_LOOP_INTERVAL_MS (5) // msec #define TEMP_INCREMENT (10.0f) // degC typedef enum { STATUS_IDLE = 0, STATUS_COOKING, STATUS_DONE } etSTATUS; #ifdef DEBUG #define MAX_LATENCY (10) // msec #define ERROR_MICROWAVE_SM (1L<<0) #define ERROR_LATENCY_DOOR (1L<<1) #define ERROR_LATENCY_STOP (1L<<2) #endif /* DEBUG */ // forward declarations void init_microwave(void); void press_left(void); void press_right(void); void press_start(void); void press_stop(void); void press_door(void); void wdog_update(void); void update_output(void); void microwave_sm(void); // microwave state machine // input peripherals Keypad keypad( BUTTON_LEFT, press_left, // keypad BUTTON_RIGHT, press_right, BUTTON_START, press_start, BUTTON_STOP, press_stop, BUTTON_DOOR, press_door ); LM75B tmp(p28,p27); // temperature sensor // output peripherals C12832_LCD lcd; // LCD screen DigitalOut cooking_status(LED1); // LED for cooking progress DigitalOut carousel_status(LED2); // LED for carousel #ifdef DEBUG DigitalOut debugLED(LED4); // general debug LED #endif /* DEBUG */ PwmOut alarm(p26); // Timers Ticker wdog; // 1sec watchdog #ifdef DEBUG Timer latency_wdog; #endif /* DEBUG */ // global status variables volatile signed short ssCookingTime; unsigned char ucDoorStatus = DOOR_CLOSED; float fTemp = 0.0f; etSTATUS opStatus; volatile unsigned char start_requested; volatile unsigned char stop_requested; volatile unsigned char temp_ticker; #ifdef DEBUG unsigned long ulErrorCode = 0UL; #endif /* DEBUG */ int main() { unsigned char while_loop_counter = 0; init_microwave(); while(1) { wait_ms(WHILE_LOOP_INTERVAL_MS); while_loop_counter++; microwave_sm(); // execute state machine // do not need to update LCD as often if ( while_loop_counter & 0x20 ) { update_output(); } } } void init_microwave(void) { ssCookingTime = 0L; cooking_status = LED_OFF; carousel_status = LED_OFF; opStatus = STATUS_IDLE; start_requested = FALSE; stop_requested = FALSE; } void press_left(void) { if ( opStatus == STATUS_DONE ) { return; } ssCookingTime += COOKING_TIME_INCREMENT; if ( ssCookingTime >= MAX_COOKING_TIME ) { ssCookingTime = MAX_COOKING_TIME; } } void press_right(void) { if ( opStatus != STATUS_IDLE ) { return; } ssCookingTime -= COOKING_TIME_INCREMENT; if ( ssCookingTime <= MIN_COOKING_TIME ) { ssCookingTime = MIN_COOKING_TIME; } } void press_start(void) { if ( opStatus != STATUS_IDLE ) { return; } if ( ssCookingTime && (ucDoorStatus == DOOR_CLOSED) ) { start_requested = TRUE; } } void press_stop(void) { if ( opStatus == STATUS_IDLE ) { init_microwave(); return; } else { #ifdef DEBUG latency_wdog.start(); #endif stop_requested = TRUE; } } void press_door(void) { ucDoorStatus = !ucDoorStatus; if ( opStatus == STATUS_COOKING ) { #ifdef DEBUG latency_wdog.start(); #endif } } void wdog_update(void) { if ( opStatus == STATUS_COOKING ) { ssCookingTime--; // reset wdog if ( ssCookingTime ) { wdog.attach(wdog_update, 1); } if ( temp_ticker ) { temp_ticker--; } } } void microwave_sm(void) { switch ( opStatus ) { case STATUS_IDLE: fTemp = tmp.read(); if ( ssCookingTime && !ucDoorStatus && start_requested ) { start_requested = FALSE; wdog.attach(wdog_update, 1); temp_ticker = (ssCookingTime > MAX_TICKER_TIME) ? MAX_TICKER_TIME : ssCookingTime; opStatus = STATUS_COOKING; } break; case STATUS_COOKING: if ( ucDoorStatus == DOOR_OPEN ) { #ifdef DEBUG if (latency_wdog.read_ms() > MAX_LATENCY) { ulErrorCode |= ERROR_LATENCY_DOOR; } latency_wdog.stop(); #endif /* DEBUG */ init_microwave(); } else if ( stop_requested ) { #ifdef DEBUG if (latency_wdog.read_ms() > MAX_LATENCY) { ulErrorCode |= ERROR_LATENCY_STOP; } latency_wdog.stop(); #endif /* DEBUG */ init_microwave(); } else { if ( !ssCookingTime ) { opStatus = STATUS_DONE; } else if ( !temp_ticker ) { fTemp += TEMP_INCREMENT; temp_ticker = (ssCookingTime > MAX_TICKER_TIME) ? MAX_TICKER_TIME : ssCookingTime; } } break; case STATUS_DONE: if ( ucDoorStatus == DOOR_OPEN || stop_requested ) { init_microwave(); } break; default: #ifdef DEBUG // something is wrong if we got here! ulErrorCode |= ERROR_MICROWAVE_SM; #endif /* DEBUG */ break; } } void update_output(void) { static unsigned char toggle_alarm = 0; static etSTATUS previousState = (etSTATUS) 0xFF; // clear the screen only when we transition states to prevent flicker if ( previousState != opStatus ) { lcd.cls(); previousState = opStatus; } lcd.locate(0,0); lcd.printf("Cooking Time: %3d secs\n",ssCookingTime); switch ( opStatus ) { case STATUS_IDLE: // alarm should be off in this state toggle_alarm = 0; alarm = 0.0; break; case STATUS_COOKING: // display temp lcd.locate(0,10); lcd.printf("Temp: %.2f degC\n", fTemp); // update LEDs cooking_status = !cooking_status; carousel_status = !carousel_status; // alarm should be off in this state toggle_alarm = 0; alarm = 0.0; break; case STATUS_DONE: // LEDs off in this state cooking_status = LED_OFF; carousel_status = LED_OFF; // sound alarm toggle_alarm++; if ( toggle_alarm & 8 ) { alarm.period(1.0/5000); alarm = 0.5; } else { alarm = 0.0; } lcd.locate(0,10); lcd.printf("ENJOY YOUR MEAL!\n"); break; } lcd.locate(0,23); lcd.printf("door %s\n", ucDoorStatus ? "open " : "closed"); #ifdef DEBUG lcd.locate(95,23); lcd.printf("0x%04X\n", ulErrorCode); #endif /* DEBUG */ }