A simple microwave demo

Dependencies:   C12832_lcd LM75B mbed-rtos mbed

Committer:
joeroop
Date:
Sat Mar 15 20:33:52 2014 +0000
Revision:
1:896789dcc911
Parent:
0:3a19dcea1a01
Child:
2:324dc8b89365
lots of changes have lots of signals may need to rework

Who changed what in which revision?

UserRevisionLine numberNew contents of line
joeroop 0:3a19dcea1a01 1
joeroop 0:3a19dcea1a01 2
joeroop 0:3a19dcea1a01 3
joeroop 0:3a19dcea1a01 4 #include "mbed.h"
joeroop 0:3a19dcea1a01 5 #include "rtos.h"
joeroop 0:3a19dcea1a01 6 #include "C12832_lcd.h" //LCD interface
joeroop 0:3a19dcea1a01 7 #include "LM75B.h" //temperature interface
joeroop 0:3a19dcea1a01 8
joeroop 1:896789dcc911 9
joeroop 1:896789dcc911 10 #define DEBOUNCE_TIME_MS 10
joeroop 1:896789dcc911 11 #define MAX_COOK_TIME_S 180 //3min
joeroop 1:896789dcc911 12 #define INIT_COOK_TIME_S 5
joeroop 1:896789dcc911 13
joeroop 1:896789dcc911 14
joeroop 0:3a19dcea1a01 15 //globals and types
joeroop 0:3a19dcea1a01 16 DigitalOut led1(LED1);
joeroop 0:3a19dcea1a01 17 DigitalOut led2(LED2);
joeroop 1:896789dcc911 18 DigitalOut led3(LED3);
joeroop 1:896789dcc911 19 DigitalOut led4(LED4);
joeroop 0:3a19dcea1a01 20 C12832_LCD lcd;
joeroop 1:896789dcc911 21 Timer debounceTimer;
joeroop 1:896789dcc911 22 InterruptIn irptTimeDn(p16); //cook down
joeroop 1:896789dcc911 23 InterruptIn irptTimeUp(p13); //cook up
joeroop 1:896789dcc911 24 InterruptIn irptStart(p15); //start cooking
joeroop 1:896789dcc911 25 InterruptIn irptStop(p12); //stop cooking
joeroop 1:896789dcc911 26 InterruptIn irptDoor(p14); //door interrupt
joeroop 1:896789dcc911 27 Thread *proxy_lcd;
joeroop 1:896789dcc911 28 Thread *proxy_temp;
joeroop 1:896789dcc911 29 Thread *proxy_sound;
joeroop 1:896789dcc911 30 Thread *proxy_state;
joeroop 1:896789dcc911 31 Thread *proxy_led;
joeroop 1:896789dcc911 32 Thread *proxy_timer;
joeroop 1:896789dcc911 33 Thread *proxies[] = {
joeroop 1:896789dcc911 34 proxy_lcd,
joeroop 1:896789dcc911 35 proxy_temp,
joeroop 1:896789dcc911 36 proxy_sound,
joeroop 1:896789dcc911 37 proxy_state,
joeroop 1:896789dcc911 38 proxy_led,
joeroop 1:896789dcc911 39 proxy_timer,
joeroop 1:896789dcc911 40 };
joeroop 1:896789dcc911 41 int PROXIES_SIZE = sizeof(proxies)/sizeof(Thread*);
joeroop 1:896789dcc911 42
joeroop 1:896789dcc911 43
joeroop 1:896789dcc911 44 typedef enum { //start at one as we are using this as signals
joeroop 1:896789dcc911 45 //states
joeroop 1:896789dcc911 46 WAITING = 1,
joeroop 1:896789dcc911 47 COOKING,
joeroop 1:896789dcc911 48 DONE,
joeroop 1:896789dcc911 49 //interrupts signals
joeroop 1:896789dcc911 50 TIMEUP,
joeroop 1:896789dcc911 51 TIMEDN,
joeroop 1:896789dcc911 52 START,
joeroop 1:896789dcc911 53 STOP,
joeroop 1:896789dcc911 54 DOOR
joeroop 1:896789dcc911 55 } state_t;
joeroop 1:896789dcc911 56
joeroop 1:896789dcc911 57 char *stateStr[] = {"NULL","WAIT","COOK","DONE"};
joeroop 1:896789dcc911 58
joeroop 0:3a19dcea1a01 59
joeroop 1:896789dcc911 60 typedef enum {TEMP_VAL, TIME_ELPS, TIME_RQST} type_t;
joeroop 1:896789dcc911 61 typedef enum {STATE, TEMP, SOUND, LCD, LED, TIMER, ALL} thread_t;
joeroop 1:896789dcc911 62 char *threadStr[] = {"STATE", "TEMP", "SOUND", "LCD", "LED", "TIMER", "ALL"};
joeroop 1:896789dcc911 63
joeroop 1:896789dcc911 64 typedef struct {
joeroop 1:896789dcc911 65 state_t state;
joeroop 1:896789dcc911 66 type_t type;
joeroop 1:896789dcc911 67 union {
joeroop 1:896789dcc911 68 float temp;
joeroop 1:896789dcc911 69 int time_elapsed; //seconds of cooking
joeroop 1:896789dcc911 70 int time_request; //seconds
joeroop 1:896789dcc911 71 } value;
joeroop 1:896789dcc911 72 } data_t;
joeroop 1:896789dcc911 73
joeroop 1:896789dcc911 74
joeroop 1:896789dcc911 75
joeroop 1:896789dcc911 76
joeroop 1:896789dcc911 77 MemoryPool<data_t,10> mpool; //used to hold all messages
joeroop 1:896789dcc911 78 Queue<data_t,10> queue; //used to hold the messages
joeroop 0:3a19dcea1a01 79
joeroop 1:896789dcc911 80 bool debounce(void);
joeroop 1:896789dcc911 81 void blink_led(void const *args);
joeroop 1:896789dcc911 82 void send_time(const void *args);
joeroop 1:896789dcc911 83 //void send_state(const void *args);
joeroop 1:896789dcc911 84
joeroop 1:896789dcc911 85 void send_state(state_t state, thread_t pthr);
joeroop 1:896789dcc911 86 //Threads
joeroop 1:896789dcc911 87 void thread_state(void const *args);
joeroop 1:896789dcc911 88 void thread_lcd(void const *args);
joeroop 1:896789dcc911 89 void thread_temp(void const *args);
joeroop 1:896789dcc911 90 void thread_sound(void const *args);
joeroop 1:896789dcc911 91 void thread_led(void const *args);
joeroop 1:896789dcc911 92 void thread_timer(void const *args);
joeroop 1:896789dcc911 93
joeroop 1:896789dcc911 94
joeroop 1:896789dcc911 95
joeroop 1:896789dcc911 96 //ISRs
joeroop 1:896789dcc911 97 void isrTimeUp(void);
joeroop 1:896789dcc911 98 void isrTimeDn(void);
joeroop 1:896789dcc911 99 void isrStart(void);
joeroop 1:896789dcc911 100 void isrStop(void);
joeroop 1:896789dcc911 101 void isrDoor(void);
joeroop 1:896789dcc911 102
joeroop 1:896789dcc911 103
joeroop 0:3a19dcea1a01 104
joeroop 0:3a19dcea1a01 105 int main(void){
joeroop 1:896789dcc911 106 debounceTimer.start();
joeroop 1:896789dcc911 107 //interrupts
joeroop 1:896789dcc911 108 irptTimeUp.rise(&isrTimeUp);
joeroop 1:896789dcc911 109 irptTimeDn.rise(&isrTimeDn);
joeroop 1:896789dcc911 110 irptStart.rise(&isrStart);
joeroop 1:896789dcc911 111 irptStop.rise(&isrStop);
joeroop 1:896789dcc911 112 irptDoor.rise(&isrDoor); //debounce everything except for the door
joeroop 1:896789dcc911 113
joeroop 1:896789dcc911 114 Thread t1(thread_state);
joeroop 1:896789dcc911 115 Thread t2(thread_temp);
joeroop 1:896789dcc911 116 Thread t3(thread_sound);
joeroop 1:896789dcc911 117 Thread t4(thread_lcd);
joeroop 1:896789dcc911 118 Thread t5(thread_led);
joeroop 1:896789dcc911 119 Thread t6(thread_timer);
joeroop 1:896789dcc911 120
joeroop 1:896789dcc911 121 proxy_state = &t1;
joeroop 1:896789dcc911 122 proxy_temp = &t2;
joeroop 1:896789dcc911 123 proxy_sound = &t3;
joeroop 1:896789dcc911 124 proxy_lcd = &t4;
joeroop 1:896789dcc911 125 proxy_led = &t5;
joeroop 1:896789dcc911 126 proxy_timer = &t6;
joeroop 0:3a19dcea1a01 127
joeroop 1:896789dcc911 128
joeroop 1:896789dcc911 129
joeroop 1:896789dcc911 130 t4.set_priority(osPriorityRealtime);
joeroop 1:896789dcc911 131
joeroop 0:3a19dcea1a01 132 while(1){
joeroop 0:3a19dcea1a01 133 Thread::wait(250);
joeroop 0:3a19dcea1a01 134 }
joeroop 0:3a19dcea1a01 135 }
joeroop 0:3a19dcea1a01 136
joeroop 1:896789dcc911 137 //function for a global debounce on the isrstick
joeroop 1:896789dcc911 138 bool debounce(void){
joeroop 1:896789dcc911 139 if(debounceTimer.read_ms() > DEBOUNCE_TIME_MS){
joeroop 1:896789dcc911 140 debounceTimer.reset();
joeroop 1:896789dcc911 141 return true;
joeroop 1:896789dcc911 142 }else{
joeroop 1:896789dcc911 143 return false;
joeroop 1:896789dcc911 144 }
joeroop 1:896789dcc911 145 }
joeroop 1:896789dcc911 146 //ISRs
joeroop 1:896789dcc911 147 void isrTimeUp(void){
joeroop 1:896789dcc911 148 if(debounce()){
joeroop 1:896789dcc911 149 proxy_state->signal_set(TIMEUP); //left
joeroop 1:896789dcc911 150 }
joeroop 1:896789dcc911 151 }
joeroop 1:896789dcc911 152 void isrTimeDn(void){
joeroop 1:896789dcc911 153 if(debounce()){
joeroop 1:896789dcc911 154 proxy_state->signal_set(TIMEDN); //right
joeroop 1:896789dcc911 155 }
joeroop 1:896789dcc911 156 }
joeroop 1:896789dcc911 157 void isrStart(void){
joeroop 1:896789dcc911 158 if(debounce()){
joeroop 1:896789dcc911 159 proxy_state->signal_set(START); //up
joeroop 1:896789dcc911 160 }
joeroop 1:896789dcc911 161 }
joeroop 1:896789dcc911 162 void isrStop(void){
joeroop 1:896789dcc911 163 if(debounce()){
joeroop 1:896789dcc911 164 proxy_state->signal_set(STOP); //down
joeroop 1:896789dcc911 165 }
joeroop 1:896789dcc911 166 }
joeroop 1:896789dcc911 167 void isrDoor(void){
joeroop 1:896789dcc911 168 //no debounce this is most important function!
joeroop 1:896789dcc911 169 proxy_state->signal_set(DOOR);
joeroop 1:896789dcc911 170 }
joeroop 1:896789dcc911 171
joeroop 1:896789dcc911 172 //Threads
joeroop 1:896789dcc911 173 void thread_lcd(void const *args){
joeroop 1:896789dcc911 174 osEvent evt;
joeroop 1:896789dcc911 175 int32_t sig;
joeroop 1:896789dcc911 176 state_t state;
joeroop 0:3a19dcea1a01 177 while(1){
joeroop 1:896789dcc911 178 evt = Thread::signal_wait(0);
joeroop 1:896789dcc911 179 sig = evt.value.signals;
joeroop 1:896789dcc911 180 switch(sig){
joeroop 1:896789dcc911 181 case WAITING:
joeroop 1:896789dcc911 182 state = WAITING;
joeroop 1:896789dcc911 183 break;
joeroop 1:896789dcc911 184 case COOKING:
joeroop 1:896789dcc911 185 state = COOKING;
joeroop 1:896789dcc911 186 break;
joeroop 1:896789dcc911 187 case DONE:
joeroop 1:896789dcc911 188 state = DONE;
joeroop 1:896789dcc911 189 break;
joeroop 1:896789dcc911 190
joeroop 1:896789dcc911 191 }
joeroop 1:896789dcc911 192 //print the state
joeroop 1:896789dcc911 193 lcd.locate(70,0);
joeroop 1:896789dcc911 194 lcd.printf("State: %s ",stateStr[state]);
joeroop 1:896789dcc911 195 //call the queue
joeroop 1:896789dcc911 196 }
joeroop 1:896789dcc911 197 }
joeroop 1:896789dcc911 198 void thread_temp(void const *args){
joeroop 1:896789dcc911 199 while(1){
joeroop 1:896789dcc911 200 Thread::wait(100);
joeroop 1:896789dcc911 201 }
joeroop 1:896789dcc911 202 }
joeroop 1:896789dcc911 203 void thread_sound(void const *args){
joeroop 1:896789dcc911 204 while(1){
joeroop 1:896789dcc911 205 Thread::wait(100);
joeroop 1:896789dcc911 206 }
joeroop 1:896789dcc911 207 }
joeroop 1:896789dcc911 208 //helper function to send all the threads the current state except for thread* passed in
joeroop 1:896789dcc911 209 void send_state(state_t state, thread_t pthr){
joeroop 1:896789dcc911 210 short i;
joeroop 1:896789dcc911 211 for(i=0; i<PROXIES_SIZE;i++){
joeroop 1:896789dcc911 212 if(i != pthr){ //if you don't match the Thread* then send a signal to that thread
joeroop 1:896789dcc911 213 proxies[pthr]->signal_set(state);
joeroop 1:896789dcc911 214 }else{
joeroop 1:896789dcc911 215 lcd.locate(0,20);
joeroop 1:896789dcc911 216 lcd.printf("send: %s, %s",stateStr[state],threadStr[i]);
joeroop 1:896789dcc911 217 }
joeroop 0:3a19dcea1a01 218 }
joeroop 0:3a19dcea1a01 219 }
joeroop 1:896789dcc911 220 //State thread to do most of the main state machine logic
joeroop 1:896789dcc911 221 void thread_state(void const *args){
joeroop 1:896789dcc911 222 osEvent evt;
joeroop 1:896789dcc911 223 int32_t mask;
joeroop 1:896789dcc911 224 bool openDoor = false; //start with door closed
joeroop 1:896789dcc911 225 state_t state = WAITING; //WAITING, COOKING, DONE
joeroop 1:896789dcc911 226 while(1){
joeroop 1:896789dcc911 227 evt = Thread::signal_wait(0);
joeroop 1:896789dcc911 228 mask = evt.value.signals;
joeroop 1:896789dcc911 229 switch(mask){
joeroop 1:896789dcc911 230 case WAITING:
joeroop 1:896789dcc911 231 state = WAITING;
joeroop 1:896789dcc911 232 //send_state((void*)WAITING); //send state to all threads
joeroop 1:896789dcc911 233 send_state(state,STATE);
joeroop 1:896789dcc911 234 break;
joeroop 1:896789dcc911 235 case COOKING:
joeroop 1:896789dcc911 236 state = COOKING;
joeroop 1:896789dcc911 237 send_state(state,STATE);
joeroop 1:896789dcc911 238 break;
joeroop 1:896789dcc911 239 case DONE: //timer can signal this
joeroop 1:896789dcc911 240 state = WAITING;
joeroop 1:896789dcc911 241 send_state(state,STATE);
joeroop 1:896789dcc911 242 //send signal to timer, led and pwm
joeroop 1:896789dcc911 243 break;
joeroop 1:896789dcc911 244 case TIMEUP: //change the timer up
joeroop 1:896789dcc911 245 if(state == WAITING) proxy_timer->signal_set(TIMEUP);
joeroop 1:896789dcc911 246 break;
joeroop 1:896789dcc911 247 case TIMEDN: //change the timer down
joeroop 1:896789dcc911 248 if(state == WAITING) proxy_timer->signal_set(TIMEDN);
joeroop 1:896789dcc911 249 break;
joeroop 1:896789dcc911 250 case START:
joeroop 1:896789dcc911 251 if(state == WAITING) proxy_state->signal_set(COOKING);
joeroop 1:896789dcc911 252 break;
joeroop 1:896789dcc911 253 case STOP:
joeroop 1:896789dcc911 254 if(state == COOKING) proxy_state->signal_set(DONE);
joeroop 1:896789dcc911 255 break;
joeroop 1:896789dcc911 256 case DOOR: //door changed state
joeroop 1:896789dcc911 257 openDoor = !openDoor;
joeroop 1:896789dcc911 258 state = (openDoor == true) ? DONE : WAITING; //open door then done else state back to waiting
joeroop 1:896789dcc911 259 led1 = led2 = led3 =led4 = openDoor;
joeroop 1:896789dcc911 260 send_state(state,ALL); //signal back to state thread
joeroop 1:896789dcc911 261 //proxy_lcd->signal_set(openDoor);
joeroop 1:896789dcc911 262 break;
joeroop 1:896789dcc911 263 }
joeroop 1:896789dcc911 264 }
joeroop 1:896789dcc911 265 }
joeroop 1:896789dcc911 266 //helper function to thread_led used to blink led
joeroop 1:896789dcc911 267 void blink_led(void const *args){
joeroop 1:896789dcc911 268 led1 = !led1;
joeroop 1:896789dcc911 269 }
joeroop 1:896789dcc911 270 //Thread led to blink the light when cooking and stop when done
joeroop 1:896789dcc911 271 void thread_led(void const *args){
joeroop 1:896789dcc911 272 RtosTimer timer(blink_led, osTimerPeriodic);
joeroop 1:896789dcc911 273 osEvent evt;
joeroop 1:896789dcc911 274 int32_t sig;
joeroop 0:3a19dcea1a01 275 while(1){
joeroop 1:896789dcc911 276 //may need to sleep somewhere to give up thread check to see if signal_wait equiv of wait
joeroop 1:896789dcc911 277 evt = Thread::signal_wait(0); //will time out then loop not needed
joeroop 1:896789dcc911 278 sig = evt.value.signals;
joeroop 1:896789dcc911 279 switch(sig){
joeroop 1:896789dcc911 280 case COOKING:
joeroop 1:896789dcc911 281 timer.start(250);
joeroop 1:896789dcc911 282 break;
joeroop 1:896789dcc911 283 case DONE:
joeroop 1:896789dcc911 284 timer.stop();
joeroop 1:896789dcc911 285 led1 = 0;
joeroop 1:896789dcc911 286 break;
joeroop 1:896789dcc911 287 default:
joeroop 1:896789dcc911 288 //Thread::wait(2000); if wait can miss signal
joeroop 1:896789dcc911 289 break;
joeroop 1:896789dcc911 290 }
joeroop 1:896789dcc911 291 }
joeroop 1:896789dcc911 292 }
joeroop 1:896789dcc911 293 //helper function for the timer thread
joeroop 1:896789dcc911 294 void send_time(const void *args){
joeroop 1:896789dcc911 295 int time = (*((int*)args))--; //have the time in seconds send to lcd now
joeroop 1:896789dcc911 296 //lcd.locate(0,10);
joeroop 1:896789dcc911 297 //lcd.printf("ELPS %d",time);
joeroop 1:896789dcc911 298 if(time == 0) send_state(DONE,TIMER); //tell all threads cooking time up
joeroop 1:896789dcc911 299 }
joeroop 1:896789dcc911 300 void thread_timer(void const *args){
joeroop 1:896789dcc911 301 int time;
joeroop 1:896789dcc911 302 int *ptime = &time;
joeroop 1:896789dcc911 303 RtosTimer timer(send_time, osTimerPeriodic,(void*)ptime);
joeroop 1:896789dcc911 304 osEvent evt;
joeroop 1:896789dcc911 305 int32_t sig;
joeroop 1:896789dcc911 306 state_t state;
joeroop 1:896789dcc911 307 while(1){
joeroop 1:896789dcc911 308 evt = Thread::signal_wait(0); //will time out then loop not needed
joeroop 1:896789dcc911 309 sig = evt.value.signals;
joeroop 1:896789dcc911 310 switch(sig){
joeroop 1:896789dcc911 311 case WAITING:
joeroop 1:896789dcc911 312 state = WAITING;
joeroop 1:896789dcc911 313 break;
joeroop 1:896789dcc911 314 case COOKING:
joeroop 1:896789dcc911 315 state = COOKING;
joeroop 1:896789dcc911 316 timer.start(1000); //this is the increments of the timer 1s
joeroop 1:896789dcc911 317 break;
joeroop 1:896789dcc911 318 case DONE:
joeroop 1:896789dcc911 319 state = DONE;
joeroop 1:896789dcc911 320 time = INIT_COOK_TIME_S;
joeroop 1:896789dcc911 321 //default time
joeroop 1:896789dcc911 322 //send request time to lcd queue reset
joeroop 1:896789dcc911 323 //lcd.locate(0,0);
joeroop 1:896789dcc911 324 //lcd.printf("RQST %d",time);
joeroop 1:896789dcc911 325 timer.stop();
joeroop 1:896789dcc911 326 break;
joeroop 1:896789dcc911 327 case TIMEUP:
joeroop 1:896789dcc911 328 if(state == WAITING){
joeroop 1:896789dcc911 329 time = (++time) > MAX_COOK_TIME_S ? MAX_COOK_TIME_S : time; //check limits
joeroop 1:896789dcc911 330 //send request time to lcd queue
joeroop 1:896789dcc911 331 //lcd.locate(0,0);
joeroop 1:896789dcc911 332 //lcd.printf("RQST %d",time);
joeroop 1:896789dcc911 333 }
joeroop 1:896789dcc911 334 break;
joeroop 1:896789dcc911 335 case TIMEDN:
joeroop 1:896789dcc911 336 if(state == WAITING){
joeroop 1:896789dcc911 337 time = (--time) < 0 ? 0 : time; //check limits
joeroop 1:896789dcc911 338 //send request time to lcd
joeroop 1:896789dcc911 339 //lcd.locate(0,0);
joeroop 1:896789dcc911 340 //lcd.printf("RQST %d",time);
joeroop 1:896789dcc911 341 }
joeroop 1:896789dcc911 342 break;
joeroop 1:896789dcc911 343 default:
joeroop 1:896789dcc911 344 //Thread::wait(2000); if wait can miss signal
joeroop 1:896789dcc911 345 break;
joeroop 1:896789dcc911 346 }
joeroop 0:3a19dcea1a01 347 }
joeroop 1:896789dcc911 348 }