homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 16:35:45 2013 +0000
Revision:
90:d9bb516141f1
Parent:
89:290c96cd027f
Child:
91:b54500888b67
clear start/stop buttons once they've been recognised in FSM.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gatedClock 0:fcca4db7b32a 1 /*----------------------------------------------//------------------------------
gatedClock 0:fcca4db7b32a 2 student : m-moore
gatedClock 0:fcca4db7b32a 3 class : rtos
gatedClock 10:2b0a9fc39109 4 directory : RTOS_HW_07
gatedClock 0:fcca4db7b32a 5 file : main.cpp
gatedClock 0:fcca4db7b32a 6 ----description---------------------------------//------------------------------
gatedClock 70:7c0743c28b11 7 gotchyas
gatedClock 70:7c0743c28b11 8 1. using pc.printf inside a ticker routine will freeze the routine.
gatedClock 71:4a5f256ecf7c 9 2. using queues (get, put) will not work within a ticker routine.
gatedClock 76:74c454c9d75b 10 3. Ticker has a bug. http://mbed.org/questions/1563/Mbed-Tickerfunction-hangs-system-from-re/
gatedClock 80:e3e1a2161435 11
gatedClock 80:e3e1a2161435 12 improvements
gatedClock 80:e3e1a2161435 13 countdown timer needs to be sync'd to start button press.
gatedClock 87:147e2b08fae6 14 this could not be done, use granularity setting instead.
gatedClock 80:e3e1a2161435 15
gatedClock 80:e3e1a2161435 16
gatedClock 0:fcca4db7b32a 17 -----includes-----------------------------------//----------------------------*/
gatedClock 0:fcca4db7b32a 18 #include "mbed.h" // mbed class.
gatedClock 10:2b0a9fc39109 19 #include "rtos.h" // rtos class.
gatedClock 39:4e7e4d935a87 20 #include "LM75B.h" // thermometer class.
gatedClock 10:2b0a9fc39109 21 #include "C12832_lcd.h" // LCD class.
gatedClock 0:fcca4db7b32a 22 //---defines------------------------------------//------------------------------
gatedClock 9:cfdb9aa5857c 23 #define LCD1 lcd.locate(0, 0); // LCD line 1.
gatedClock 9:cfdb9aa5857c 24 #define LCD2 lcd.locate(0,11); // LCD line 2.
gatedClock 9:cfdb9aa5857c 25 #define LCD3 lcd.locate(0,22); // LCD line 3.
gatedClock 9:cfdb9aa5857c 26
gatedClock 10:2b0a9fc39109 27
gatedClock 66:4a0006fa5cc1 28 #define DEBOUNCEmS 16 // debounce wait in mS.
gatedClock 19:92b11e30aaaf 29 #define uS_TIMEOUT 100 // Timer uS timeout.
gatedClock 19:92b11e30aaaf 30 #define LBSIG 1 // left button signal code.
gatedClock 33:34c1bef3c4ff 31 #define PIPEuS 1000 // pipeline clock period.
gatedClock 19:92b11e30aaaf 32 #define SLOWCLOCKuS 500000 // slow-clock period.
gatedClock 39:4e7e4d935a87 33 #define TEMPCLOCKS 1 // temperature-measuring period in S.
gatedClock 26:bff592483cb1 34 #define PIPEDATASIZE 8 // dimension of tPipeData.
gatedClock 44:d16e813e61ef 35 #define THREAD_1_WAITmS 400 // thread 1 wait in mS.
gatedClock 67:1d9c85a4c3c1 36 #define THREAD_2_WAITmS 20 // LCD thread wait.
gatedClock 67:1d9c85a4c3c1 37 #define THREAD_3_WAITmS 80 // thread 3 wait in mS.
gatedClock 66:4a0006fa5cc1 38 #define THREAD_4_WAITmS 1 // thread 4 wait in mS.
gatedClock 78:7df160e0db7b 39 #define THREAD_5_WAITmS 1 // FSM thread wait.
gatedClock 44:d16e813e61ef 40 #define HB_MODULO 1024 // heartbeat modulo divisor.
gatedClock 50:2928c3cbdcc3 41
gatedClock 54:b0e7352d2516 42 #define MSG_INC_TIME 0x01
gatedClock 54:b0e7352d2516 43 #define MSG_DEC_TIME 0x02
gatedClock 58:ec630b6dd9b1 44 #define MSG_START 0x04
gatedClock 58:ec630b6dd9b1 45 #define MSG_STOP 0x08
gatedClock 58:ec630b6dd9b1 46 #define MSG_OPEN 0x10
gatedClock 58:ec630b6dd9b1 47 #define MSG_CLOSED 0x20
gatedClock 57:0432c68ad232 48
gatedClock 78:7df160e0db7b 49 #define FSM_IDLE 0x01 // cook-state state-machine.
gatedClock 78:7df160e0db7b 50 #define FSM_COOK 0x02 // cook-state state-machine.
gatedClock 78:7df160e0db7b 51 #define FSM_PAUSE 0x04 // cook-state state-machine.
gatedClock 78:7df160e0db7b 52 #define FSM_CONTINUE 0x08 // cook-state state-machine.
gatedClock 78:7df160e0db7b 53 #define FSM_DONE 0x10 // cook-state state-machine.
gatedClock 65:e39360da5929 54
gatedClock 71:4a5f256ecf7c 55 #define RT_PRELOAD 0x01 // remaining-time preload.
gatedClock 71:4a5f256ecf7c 56 #define RT_DECREMENT 0x02 // remaining-time decrement.
gatedClock 71:4a5f256ecf7c 57 #define RT_PAUSE 0x03 // remaining-time don't change.
gatedClock 71:4a5f256ecf7c 58 #define RT_CLEAR 0x04 // remaining-time set to zero.
gatedClock 71:4a5f256ecf7c 59
gatedClock 86:388c2b4b7cf5 60 #define GRANULARITY 0x400 // 1-second countdown ticker granularity.
gatedClock 88:0b1b812945eb 61 #define MAXSECONDS 180 // maximum microwave-on time.
gatedClock 89:290c96cd027f 62 #define BEEPTIME 3 // beep duration in S.
gatedClock 86:388c2b4b7cf5 63
gatedClock 65:e39360da5929 64 #define DEBUG1 // debug preprocessor control.
gatedClock 0:fcca4db7b32a 65 //--global_definitions--------------------------//------------------------------
gatedClock 26:bff592483cb1 66 struct tButtons // button ISR updates.
gatedClock 26:bff592483cb1 67 {
gatedClock 26:bff592483cb1 68 char cLeftButton; // cooktime +60S.
gatedClock 26:bff592483cb1 69 char cRightButton; // cooktime -60S.
gatedClock 26:bff592483cb1 70 char cTopButton; // start cook.
gatedClock 26:bff592483cb1 71 char cBottomButton; // stop cook.
gatedClock 58:ec630b6dd9b1 72 char cCenterButton; // center button pressed.
gatedClock 53:8c2baf5623c8 73 char cDoorOpen; // door open.
gatedClock 26:bff592483cb1 74 };
gatedClock 34:b449d2a7c786 75
gatedClock 71:4a5f256ecf7c 76 struct tRemainingTime // remaining time related.
gatedClock 71:4a5f256ecf7c 77 {
gatedClock 71:4a5f256ecf7c 78 char cControl; // countdown control.
gatedClock 71:4a5f256ecf7c 79 int dTotalTime; // initialize to this.
gatedClock 71:4a5f256ecf7c 80 int dRemainingTime; // the countdown value.
gatedClock 71:4a5f256ecf7c 81 };
gatedClock 71:4a5f256ecf7c 82
gatedClock 80:e3e1a2161435 83 struct tLCD // LCD related.
gatedClock 80:e3e1a2161435 84 {
gatedClock 80:e3e1a2161435 85 int dTotalCookTime; // display time in seconds.
gatedClock 80:e3e1a2161435 86 int dRemainingTime; // display time in seconds.
gatedClock 80:e3e1a2161435 87 float fCelsius; // temperature in celsius.
gatedClock 80:e3e1a2161435 88 };
gatedClock 80:e3e1a2161435 89
gatedClock 80:e3e1a2161435 90
gatedClock 80:e3e1a2161435 91
gatedClock 61:8026a9fc0cf1 92 Queue<int, 1> queueModTotalTime; // message to modify total time.
gatedClock 61:8026a9fc0cf1 93 Queue<int, 1> queueUpdateFSM; // message to inform FSM.
gatedClock 61:8026a9fc0cf1 94 Queue<int, 1> queueUpdateRemainingTime; // message to update remaining time.
gatedClock 71:4a5f256ecf7c 95 Queue<int, 1> queueSetRemainingTime; // tell countdown it's start time.
gatedClock 69:55b836e8ced7 96 Queue<int, 1> queueFSMnewState; // latest FSM state.
gatedClock 0:fcca4db7b32a 97 //--global_variables----------------------------//------------------------------
gatedClock 26:bff592483cb1 98 char gcSignalWaitEnable; // 1 to wait on a signal.
gatedClock 26:bff592483cb1 99 char gcSlowClock; // slow-clock signal.
gatedClock 33:34c1bef3c4ff 100 char gcInitializePipeline; // 1 to initialize pipeline state.
gatedClock 39:4e7e4d935a87 101 float gfCelsius; // from thermometer.
gatedClock 84:fee8fb80d190 102
gatedClock 26:bff592483cb1 103 tButtons gtButtons; // ISR button updates.
gatedClock 70:7c0743c28b11 104
gatedClock 71:4a5f256ecf7c 105 tRemainingTime giRemainingTime; // structure instance.
gatedClock 80:e3e1a2161435 106 tLCD giLCD; // structure instance.
gatedClock 71:4a5f256ecf7c 107
gatedClock 70:7c0743c28b11 108 int gdDiagTotalTime;
gatedClock 0:fcca4db7b32a 109 //--global_instances----------------------------//------------------------------
gatedClock 55:17f3354da63a 110 Serial pc(USBTX, USBRX); // PuTTY terminal communication.
gatedClock 39:4e7e4d935a87 111 LM75B temperature(p28,p27); // on-board thermometer.
gatedClock 9:cfdb9aa5857c 112 C12832_LCD lcd; // LCD object.
gatedClock 53:8c2baf5623c8 113 DigitalOut led0(LED4); // magnetron.
gatedClock 39:4e7e4d935a87 114 DigitalOut led1(LED3);
gatedClock 39:4e7e4d935a87 115 DigitalOut led2(LED2);
gatedClock 39:4e7e4d935a87 116 DigitalOut led3(LED1);
gatedClock 0:fcca4db7b32a 117
gatedClock 0:fcca4db7b32a 118 InterruptIn iJoyStickUp (p15); // joystick up rising edge.
gatedClock 0:fcca4db7b32a 119 InterruptIn iJoyStickDown (p12); // joystick down rising edge.
gatedClock 0:fcca4db7b32a 120 InterruptIn iJoyStickLeft (p13); // joystick left rising edge.
gatedClock 0:fcca4db7b32a 121 InterruptIn iJoyStickRight (p16); // joystick right rising edge.
gatedClock 0:fcca4db7b32a 122 InterruptIn iJoyStickCenter(p14); // 1 if joystick middle pressed.
gatedClock 66:4a0006fa5cc1 123
gatedClock 66:4a0006fa5cc1 124 Timer debounceTimer; // button debounce timer.
gatedClock 89:290c96cd027f 125 Timer beepTimer; // beep-duration timer.
gatedClock 0:fcca4db7b32a 126
gatedClock 50:2928c3cbdcc3 127 Ticker tickerButtonStateManager; // manage the button states.
gatedClock 19:92b11e30aaaf 128 Ticker tickerSlowClock; // generate a ~1Hz clock.
gatedClock 77:73e4fd83642f 129 Ticker tickerCookCountdown; // remaining cook time.
gatedClock 63:63f362bcc2ac 130
gatedClock 63:63f362bcc2ac 131 // Timer timerFSMdone; // duration of FSM 'done' state.
gatedClock 40:7afff79f0d8b 132
gatedClock 0:fcca4db7b32a 133 //-------prototypes-----------------------------//------------------------------
gatedClock 49:56f790977983 134
gatedClock 19:92b11e30aaaf 135 void slowClock(); // 1Hz or thereabouts.
gatedClock 49:56f790977983 136
gatedClock 9:cfdb9aa5857c 137 void initialization(); // initialize settings.
gatedClock 13:21f27ba467c2 138
gatedClock 13:21f27ba467c2 139 void ISRleftButtonRising(); // cook-time increase.
gatedClock 13:21f27ba467c2 140 void ISRleftButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 141 void ISRrightButtonRising(); // cook-time decrease.
gatedClock 13:21f27ba467c2 142 void ISRrightButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 143 void ISRtopButtonRising(); // cook start.
gatedClock 13:21f27ba467c2 144 void ISRtopButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 145 void ISRbottomButtonRising(); // cook stop.
gatedClock 13:21f27ba467c2 146 void ISRbottomButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 147 void ISRcenterButtonRising(); // door state toggle.
gatedClock 13:21f27ba467c2 148 void ISRcenterButtonFalling(); // button-release debounce.
gatedClock 16:db7f0b3b2605 149 void disableSignalWaiting(); // break from signal waiting.
gatedClock 39:4e7e4d935a87 150
gatedClock 54:b0e7352d2516 151 void threadButtonStateManager(void const *args);
gatedClock 50:2928c3cbdcc3 152 void threadTotalTimeControl(void const *args);
gatedClock 57:0432c68ad232 153 void threadCookStateFSM(void const *args);
gatedClock 71:4a5f256ecf7c 154 void tickCookRemainingTime(); // remaining time countdown.
gatedClock 50:2928c3cbdcc3 155
gatedClock 40:7afff79f0d8b 156 void temperatureThread(void const *args); // temperature measurement.
gatedClock 42:266d5bbbfd19 157 void LCDthread (void const *args); // LCD display thread.
gatedClock 0:fcca4db7b32a 158 //==============================================//==============================
gatedClock 0:fcca4db7b32a 159 int main(void)
gatedClock 0:fcca4db7b32a 160 {
gatedClock 16:db7f0b3b2605 161 char cLeftButtonState; // 1 means button was pressed.
gatedClock 16:db7f0b3b2605 162
gatedClock 16:db7f0b3b2605 163
gatedClock 16:db7f0b3b2605 164
gatedClock 14:d3bb343cd5b2 165 iJoyStickLeft.rise (&ISRleftButtonRising);
gatedClock 14:d3bb343cd5b2 166 iJoyStickLeft.fall (&ISRleftButtonFalling);
gatedClock 9:cfdb9aa5857c 167
gatedClock 14:d3bb343cd5b2 168 iJoyStickRight.rise(&ISRrightButtonRising);
gatedClock 14:d3bb343cd5b2 169 iJoyStickRight.fall(&ISRrightButtonFalling);
gatedClock 14:d3bb343cd5b2 170
gatedClock 14:d3bb343cd5b2 171 iJoyStickUp.rise (&ISRtopButtonRising);
gatedClock 14:d3bb343cd5b2 172 iJoyStickUp.fall (&ISRtopButtonFalling);
gatedClock 9:cfdb9aa5857c 173
gatedClock 14:d3bb343cd5b2 174 iJoyStickDown.rise (&ISRbottomButtonRising);
gatedClock 14:d3bb343cd5b2 175 iJoyStickDown.fall (&ISRbottomButtonFalling);
gatedClock 7:9fbd1d540863 176
gatedClock 14:d3bb343cd5b2 177 iJoyStickCenter.rise(&ISRcenterButtonRising);
gatedClock 14:d3bb343cd5b2 178 iJoyStickCenter.fall(&ISRcenterButtonFalling);
gatedClock 9:cfdb9aa5857c 179
gatedClock 66:4a0006fa5cc1 180 debounceTimer.start(); // kick-off debounce timer.
gatedClock 66:4a0006fa5cc1 181
gatedClock 33:34c1bef3c4ff 182 gcInitializePipeline = 1; // tell pipeline to initialize.
gatedClock 16:db7f0b3b2605 183
gatedClock 9:cfdb9aa5857c 184 initialization(); // initialize variables.
gatedClock 21:b794d189c36b 185 gcSlowClock = 0;
gatedClock 44:d16e813e61ef 186 led1 = 0;
gatedClock 53:8c2baf5623c8 187 gtButtons.cDoorOpen = 0; // initialize with door closed.
gatedClock 63:63f362bcc2ac 188
gatedClock 63:63f362bcc2ac 189 // timerFSMdone.start(); // start 'done' timer.
gatedClock 49:56f790977983 190
gatedClock 86:388c2b4b7cf5 191 // tickerSlowClock.attach_us(&slowClock ,SLOWCLOCKuS);
gatedClock 64:255295f1d782 192
gatedClock 75:c2894d531f42 193
gatedClock 86:388c2b4b7cf5 194 tickerCookCountdown.attach_us(&tickCookRemainingTime,1000000/GRANULARITY);
gatedClock 54:b0e7352d2516 195
gatedClock 40:7afff79f0d8b 196
gatedClock 70:7c0743c28b11 197 Thread thread_1(temperatureThread ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 70:7c0743c28b11 198 Thread thread_2(LCDthread ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 70:7c0743c28b11 199 Thread thread_3(threadTotalTimeControl ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 70:7c0743c28b11 200 Thread thread_4(threadButtonStateManager,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL); // was osPriorityIdle
gatedClock 70:7c0743c28b11 201 Thread thread_5(threadCookStateFSM ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 70:7c0743c28b11 202
gatedClock 66:4a0006fa5cc1 203 //Thread thread_4(threadButtonStateManager);
gatedClock 52:8ba6a0c91a89 204
gatedClock 40:7afff79f0d8b 205
gatedClock 59:5e45b5e4a874 206 // the message-receiving threads need 'else' for message-receive-timeout.
gatedClock 9:cfdb9aa5857c 207
gatedClock 14:d3bb343cd5b2 208 while(1)
gatedClock 0:fcca4db7b32a 209 {
gatedClock 75:c2894d531f42 210 // pc.printf("\n\r gdDiagTotalTime %d",gdDiagTotalTime);
gatedClock 70:7c0743c28b11 211
gatedClock 70:7c0743c28b11 212 Thread::wait(1000);
gatedClock 16:db7f0b3b2605 213
gatedClock 16:db7f0b3b2605 214
gatedClock 16:db7f0b3b2605 215
gatedClock 14:d3bb343cd5b2 216
gatedClock 0:fcca4db7b32a 217 }
gatedClock 19:92b11e30aaaf 218 }
gatedClock 19:92b11e30aaaf 219 /*----------------------------------------------//----------------------------*/
gatedClock 59:5e45b5e4a874 220
gatedClock 59:5e45b5e4a874 221 // this serves as the bottom-half for all of the button-press IRSs.
gatedClock 59:5e45b5e4a874 222 // it sends button-status messages to other threads, and it also
gatedClock 59:5e45b5e4a874 223 // clears the button-state globals to prepare them for the next
gatedClock 59:5e45b5e4a874 224 // button press.
gatedClock 59:5e45b5e4a874 225
gatedClock 59:5e45b5e4a874 226
gatedClock 54:b0e7352d2516 227 void threadButtonStateManager(void const *args)
gatedClock 50:2928c3cbdcc3 228 {
gatedClock 56:18cff6eb91db 229 int dMessage; // message.
gatedClock 50:2928c3cbdcc3 230
gatedClock 54:b0e7352d2516 231 while(1) // thread loop.
gatedClock 67:1d9c85a4c3c1 232 {
gatedClock 54:b0e7352d2516 233 //--- // TOTAL TIME CONTROL.
gatedClock 56:18cff6eb91db 234
gatedClock 56:18cff6eb91db 235 // encoded integers will be sent,
gatedClock 56:18cff6eb91db 236 // not pointers.
gatedClock 50:2928c3cbdcc3 237
gatedClock 50:2928c3cbdcc3 238 if (gtButtons.cLeftButton) // total time increment button.
gatedClock 50:2928c3cbdcc3 239 {
gatedClock 54:b0e7352d2516 240 dMessage = MSG_INC_TIME; // set message.
gatedClock 69:55b836e8ced7 241 queueModTotalTime.put((int *) dMessage,1);// pretend it's a pointer.
gatedClock 50:2928c3cbdcc3 242 gtButtons.cLeftButton = 0; // clear the button state.
gatedClock 50:2928c3cbdcc3 243 }
gatedClock 67:1d9c85a4c3c1 244
gatedClock 59:5e45b5e4a874 245 if (gtButtons.cRightButton) // total time decrement button.
gatedClock 50:2928c3cbdcc3 246 {
gatedClock 54:b0e7352d2516 247 dMessage = MSG_DEC_TIME; // set message.
gatedClock 69:55b836e8ced7 248 queueModTotalTime.put((int *) dMessage,1);// pretend it's a pointer.
gatedClock 50:2928c3cbdcc3 249 gtButtons.cRightButton = 0; // clear the button state.
gatedClock 50:2928c3cbdcc3 250 }
gatedClock 67:1d9c85a4c3c1 251
gatedClock 59:5e45b5e4a874 252 //--- // COOK-STATE FSM.
gatedClock 59:5e45b5e4a874 253
gatedClock 59:5e45b5e4a874 254 if (gtButtons.cTopButton) // start-cook button.
gatedClock 58:ec630b6dd9b1 255 {
gatedClock 59:5e45b5e4a874 256 dMessage = MSG_START; // set message.
gatedClock 69:55b836e8ced7 257 queueUpdateFSM.put((int *) dMessage,1); // pretend it's a pointer.
gatedClock 59:5e45b5e4a874 258 gtButtons.cTopButton = 0; // clear the button state.
gatedClock 58:ec630b6dd9b1 259 }
gatedClock 67:1d9c85a4c3c1 260
gatedClock 59:5e45b5e4a874 261 if (gtButtons.cBottomButton) // stop-cook button.
gatedClock 58:ec630b6dd9b1 262 {
gatedClock 59:5e45b5e4a874 263 dMessage = MSG_STOP; // set message.
gatedClock 69:55b836e8ced7 264 queueUpdateFSM.put((int *) dMessage,1); // pretend it's a pointer.
gatedClock 59:5e45b5e4a874 265 gtButtons.cBottomButton = 0; // clear the button state.
gatedClock 58:ec630b6dd9b1 266 }
gatedClock 67:1d9c85a4c3c1 267
gatedClock 59:5e45b5e4a874 268 if (gtButtons.cCenterButton) // door-state-toggle.
gatedClock 58:ec630b6dd9b1 269 {
gatedClock 59:5e45b5e4a874 270 dMessage = gtButtons.cDoorOpen; // determined in ISR.
gatedClock 69:55b836e8ced7 271 queueUpdateFSM.put((int *) dMessage,1); // pretend it's a pointer.
gatedClock 59:5e45b5e4a874 272 gtButtons.cCenterButton = 0; // clear the button state.
gatedClock 58:ec630b6dd9b1 273 }
gatedClock 59:5e45b5e4a874 274 //---
gatedClock 58:ec630b6dd9b1 275
gatedClock 54:b0e7352d2516 276 Thread::wait(THREAD_4_WAITmS); // multitasking.
gatedClock 54:b0e7352d2516 277 } // thread loop.
gatedClock 54:b0e7352d2516 278 } // threadButtonStateManager.
gatedClock 50:2928c3cbdcc3 279 /*----------------------------------------------//----------------------------*/
gatedClock 51:e5ec74c49b01 280 // the incoming messages are mutually-exclusive.
gatedClock 51:e5ec74c49b01 281 // total time controller.
gatedClock 51:e5ec74c49b01 282 void threadTotalTimeControl(void const *args)
gatedClock 50:2928c3cbdcc3 283 {
gatedClock 51:e5ec74c49b01 284 static int dTotalTime = 0; // total time variable.
gatedClock 60:e10bf95bbc96 285 int dMessage; // message.
gatedClock 51:e5ec74c49b01 286 osEvent queueEvent; // queue event.
gatedClock 70:7c0743c28b11 287 int dRC;
gatedClock 50:2928c3cbdcc3 288
gatedClock 50:2928c3cbdcc3 289 while(1) // thread loop.
gatedClock 50:2928c3cbdcc3 290 {
gatedClock 50:2928c3cbdcc3 291
gatedClock 55:17f3354da63a 292 queueEvent = queueModTotalTime.get(1); // get message.
gatedClock 51:e5ec74c49b01 293 if (queueEvent.status == osEventMessage)
gatedClock 51:e5ec74c49b01 294 {
gatedClock 56:18cff6eb91db 295 dMessage = (int) queueEvent.value.p; // interpret as integer, not pointer.
gatedClock 54:b0e7352d2516 296
gatedClock 54:b0e7352d2516 297 // increment total time.
gatedClock 56:18cff6eb91db 298 if (dMessage == MSG_INC_TIME) dTotalTime += 60;
gatedClock 54:b0e7352d2516 299
gatedClock 54:b0e7352d2516 300 // decrement total time.
gatedClock 56:18cff6eb91db 301 if (dMessage == MSG_DEC_TIME) dTotalTime -= 60;
gatedClock 65:e39360da5929 302
gatedClock 65:e39360da5929 303 // saturations.
gatedClock 65:e39360da5929 304 if (dTotalTime > 180) dTotalTime = 180;
gatedClock 65:e39360da5929 305 if (dTotalTime < 0) dTotalTime = 0;
gatedClock 65:e39360da5929 306
gatedClock 70:7c0743c28b11 307 dRC = queueSetRemainingTime.put((int *) dTotalTime,1);
gatedClock 75:c2894d531f42 308 giRemainingTime.dTotalTime = dTotalTime;
gatedClock 51:e5ec74c49b01 309 }
gatedClock 81:12bc26973cb8 310
gatedClock 50:2928c3cbdcc3 311 Thread::wait(THREAD_3_WAITmS); // multitasking.
gatedClock 50:2928c3cbdcc3 312 } // thread loop.
gatedClock 50:2928c3cbdcc3 313 } // threadTotalTimeControl.
gatedClock 33:34c1bef3c4ff 314 /*----------------------------------------------//----------------------------*/
gatedClock 81:12bc26973cb8 315
gatedClock 57:0432c68ad232 316 void threadCookStateFSM(void const *args) // cook-cycle FSM.
gatedClock 57:0432c68ad232 317 {
gatedClock 83:2e01f2a799ba 318 int dFSMstate = FSM_IDLE; // state of this FSM.
gatedClock 83:2e01f2a799ba 319 int dFSMstateLast = FSM_IDLE; // previous FSM state.
gatedClock 83:2e01f2a799ba 320 int dButtonState; // received button state.
gatedClock 83:2e01f2a799ba 321 int dRemainingTime = 0; // received remaining time.
gatedClock 62:48e7c196e2a5 322
gatedClock 83:2e01f2a799ba 323 int dButtonStart = 0;
gatedClock 83:2e01f2a799ba 324 int dButtonStop = 0;
gatedClock 83:2e01f2a799ba 325 int dDoorOpen = 0;
gatedClock 81:12bc26973cb8 326
gatedClock 81:12bc26973cb8 327 osEvent queueEvent; // from button state manager.
gatedClock 89:290c96cd027f 328 beepTimer.start(); // run the beep timer.
gatedClock 75:c2894d531f42 329
gatedClock 62:48e7c196e2a5 330
gatedClock 63:63f362bcc2ac 331
gatedClock 57:0432c68ad232 332 while(1) // thread loop.
gatedClock 57:0432c68ad232 333 {
gatedClock 81:12bc26973cb8 334
gatedClock 74:4debb8f2e21d 335 switch (dFSMstate) // cook-mode state machine.
gatedClock 62:48e7c196e2a5 336 {
gatedClock 82:73fa3fe8a217 337 //---
gatedClock 73:44739860198b 338 case FSM_IDLE : // IDLE.
gatedClock 73:44739860198b 339 {
gatedClock 89:290c96cd027f 340 led0 = 0;
gatedClock 75:c2894d531f42 341 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 80:e3e1a2161435 342 {
gatedClock 89:290c96cd027f 343 dButtonStart == 0; // cancel start button.
gatedClock 75:c2894d531f42 344 }
gatedClock 80:e3e1a2161435 345
gatedClock 80:e3e1a2161435 346 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 347 giLCD.dRemainingTime = 0; // suppress remaining time display.
gatedClock 80:e3e1a2161435 348 giLCD.fCelsius = 0;
gatedClock 80:e3e1a2161435 349
gatedClock 78:7df160e0db7b 350 giRemainingTime.cControl = RT_PRELOAD;
gatedClock 76:74c454c9d75b 351 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 75:c2894d531f42 352 if ((dButtonStart == 1) && (dDoorOpen == 0) && (giRemainingTime.dTotalTime > 0)) dFSMstate = FSM_COOK;
gatedClock 73:44739860198b 353 break;
gatedClock 73:44739860198b 354 }
gatedClock 82:73fa3fe8a217 355 //---
gatedClock 73:44739860198b 356 case FSM_COOK : // COOK.
gatedClock 73:44739860198b 357 {
gatedClock 75:c2894d531f42 358 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 75:c2894d531f42 359 {
gatedClock 75:c2894d531f42 360 giRemainingTime.cControl = RT_DECREMENT;
gatedClock 75:c2894d531f42 361 }
gatedClock 80:e3e1a2161435 362
gatedClock 80:e3e1a2161435 363 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 364 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 80:e3e1a2161435 365 giLCD.fCelsius = 0;
gatedClock 80:e3e1a2161435 366
gatedClock 80:e3e1a2161435 367
gatedClock 76:74c454c9d75b 368
gatedClock 76:74c454c9d75b 369 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 78:7df160e0db7b 370 if ((dDoorOpen == 1) && (dRemainingTime > 0)) dFSMstate = FSM_PAUSE;
gatedClock 78:7df160e0db7b 371 else
gatedClock 76:74c454c9d75b 372 if (dButtonStop) dFSMstate = FSM_IDLE;
gatedClock 78:7df160e0db7b 373 else
gatedClock 78:7df160e0db7b 374 if (dRemainingTime <= 0) dFSMstate = FSM_DONE;
gatedClock 73:44739860198b 375 break;
gatedClock 73:44739860198b 376 }
gatedClock 82:73fa3fe8a217 377 //---
gatedClock 73:44739860198b 378 case FSM_PAUSE : // PAUSE.
gatedClock 73:44739860198b 379 {
gatedClock 75:c2894d531f42 380
gatedClock 75:c2894d531f42 381 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 75:c2894d531f42 382 {
gatedClock 75:c2894d531f42 383 }
gatedClock 80:e3e1a2161435 384
gatedClock 80:e3e1a2161435 385
gatedClock 80:e3e1a2161435 386 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 387 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 80:e3e1a2161435 388 giLCD.fCelsius = 0;
gatedClock 80:e3e1a2161435 389
gatedClock 80:e3e1a2161435 390
gatedClock 75:c2894d531f42 391 giRemainingTime.cControl = RT_PAUSE;
gatedClock 75:c2894d531f42 392 // determine next state.
gatedClock 75:c2894d531f42 393 dFSMstateLast = dFSMstate;
gatedClock 78:7df160e0db7b 394 if ((dButtonStart == 1) && (dDoorOpen == 0) && (giRemainingTime.dTotalTime > 0)) dFSMstate = FSM_CONTINUE;
gatedClock 75:c2894d531f42 395 else
gatedClock 78:7df160e0db7b 396 if (dButtonStop) dFSMstate = FSM_IDLE;
gatedClock 73:44739860198b 397 break;
gatedClock 73:44739860198b 398 }
gatedClock 78:7df160e0db7b 399
gatedClock 82:73fa3fe8a217 400 //---
gatedClock 79:4286319e48b4 401 case FSM_CONTINUE : // CONTINUE.
gatedClock 78:7df160e0db7b 402 {
gatedClock 78:7df160e0db7b 403
gatedClock 78:7df160e0db7b 404 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 78:7df160e0db7b 405 {
gatedClock 78:7df160e0db7b 406 }
gatedClock 80:e3e1a2161435 407
gatedClock 80:e3e1a2161435 408
gatedClock 80:e3e1a2161435 409 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 410 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 80:e3e1a2161435 411 giLCD.fCelsius = 0;
gatedClock 80:e3e1a2161435 412
gatedClock 80:e3e1a2161435 413
gatedClock 78:7df160e0db7b 414 giRemainingTime.cControl = RT_DECREMENT;
gatedClock 78:7df160e0db7b 415 // determine next state.
gatedClock 78:7df160e0db7b 416 dFSMstateLast = dFSMstate;
gatedClock 78:7df160e0db7b 417 if (dRemainingTime <= 0) dFSMstate = FSM_DONE;
gatedClock 78:7df160e0db7b 418 else
gatedClock 78:7df160e0db7b 419 if (dButtonStop) dFSMstate = FSM_IDLE;
gatedClock 79:4286319e48b4 420 else
gatedClock 79:4286319e48b4 421 if ((dDoorOpen == 1) && (dRemainingTime > 0)) dFSMstate = FSM_PAUSE;
gatedClock 78:7df160e0db7b 422 break;
gatedClock 78:7df160e0db7b 423 }
gatedClock 78:7df160e0db7b 424
gatedClock 78:7df160e0db7b 425
gatedClock 82:73fa3fe8a217 426 //---
gatedClock 73:44739860198b 427 case FSM_DONE : // DONE.
gatedClock 73:44739860198b 428 {
gatedClock 89:290c96cd027f 429 led0 = 1;
gatedClock 75:c2894d531f42 430 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 75:c2894d531f42 431 {
gatedClock 89:290c96cd027f 432 beepTimer.reset(); // clear the beep timer.
gatedClock 75:c2894d531f42 433 }
gatedClock 80:e3e1a2161435 434
gatedClock 80:e3e1a2161435 435
gatedClock 80:e3e1a2161435 436 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 437 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 80:e3e1a2161435 438 giLCD.fCelsius = 0;
gatedClock 80:e3e1a2161435 439
gatedClock 80:e3e1a2161435 440
gatedClock 80:e3e1a2161435 441
gatedClock 75:c2894d531f42 442 giRemainingTime.cControl = RT_CLEAR;
gatedClock 75:c2894d531f42 443 // determine next state.
gatedClock 75:c2894d531f42 444 dFSMstateLast = dFSMstate;
gatedClock 89:290c96cd027f 445 if (beepTimer.read() >= BEEPTIME) dFSMstate = FSM_IDLE;
gatedClock 89:290c96cd027f 446 else dFSMstate = FSM_DONE;
gatedClock 73:44739860198b 447 break;
gatedClock 73:44739860198b 448 }
gatedClock 82:73fa3fe8a217 449 //---
gatedClock 73:44739860198b 450 default : {dFSMstate = FSM_IDLE; break;}
gatedClock 73:44739860198b 451
gatedClock 62:48e7c196e2a5 452 }
gatedClock 73:44739860198b 453
gatedClock 63:63f362bcc2ac 454
gatedClock 75:c2894d531f42 455
gatedClock 75:c2894d531f42 456 queueEvent = queueUpdateFSM.get(1); // threadButtonStateManager
gatedClock 60:e10bf95bbc96 457 if (queueEvent.status == osEventMessage)// update state variable.
gatedClock 60:e10bf95bbc96 458 {
gatedClock 61:8026a9fc0cf1 459 // interpret as integer, not pointer.
gatedClock 61:8026a9fc0cf1 460 dButtonState = (int) queueEvent.value.p;
gatedClock 63:63f362bcc2ac 461
gatedClock 75:c2894d531f42 462
gatedClock 69:55b836e8ced7 463
gatedClock 63:63f362bcc2ac 464 if (dButtonState == MSG_START)
gatedClock 63:63f362bcc2ac 465 {
gatedClock 63:63f362bcc2ac 466 dButtonStart = 1;
gatedClock 63:63f362bcc2ac 467 dButtonStop = 0;
gatedClock 79:4286319e48b4 468
gatedClock 79:4286319e48b4 469 // if the door is open, ignore
gatedClock 79:4286319e48b4 470 // and cancel 'start' state.
gatedClock 79:4286319e48b4 471 if (dDoorOpen) dButtonStart = 0;
gatedClock 63:63f362bcc2ac 472 }
gatedClock 63:63f362bcc2ac 473 if (dButtonState == MSG_STOP)
gatedClock 63:63f362bcc2ac 474 {
gatedClock 63:63f362bcc2ac 475 dButtonStart = 0;
gatedClock 63:63f362bcc2ac 476 dButtonStop = 1;
gatedClock 63:63f362bcc2ac 477 }
gatedClock 63:63f362bcc2ac 478
gatedClock 63:63f362bcc2ac 479 if (dButtonState == MSG_OPEN)
gatedClock 63:63f362bcc2ac 480 {
gatedClock 79:4286319e48b4 481 // if the door opens, clear current 'start' state.
gatedClock 79:4286319e48b4 482 dDoorOpen = 1;
gatedClock 79:4286319e48b4 483 dButtonStart = 0;
gatedClock 63:63f362bcc2ac 484 }
gatedClock 63:63f362bcc2ac 485
gatedClock 63:63f362bcc2ac 486 if (dButtonState == MSG_CLOSED)
gatedClock 63:63f362bcc2ac 487 {
gatedClock 63:63f362bcc2ac 488 dDoorOpen = 0;
gatedClock 63:63f362bcc2ac 489 }
gatedClock 63:63f362bcc2ac 490
gatedClock 61:8026a9fc0cf1 491 }
gatedClock 90:d9bb516141f1 492 else // no queue update available.
gatedClock 90:d9bb516141f1 493 {
gatedClock 90:d9bb516141f1 494 dButtonStart = 0;
gatedClock 90:d9bb516141f1 495 dButtonStop = 0;
gatedClock 90:d9bb516141f1 496 // dDoorOpen = 0;
gatedClock 90:d9bb516141f1 497
gatedClock 90:d9bb516141f1 498
gatedClock 90:d9bb516141f1 499 }
gatedClock 75:c2894d531f42 500
gatedClock 75:c2894d531f42 501 // fetch from global scope.
gatedClock 75:c2894d531f42 502 dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 69:55b836e8ced7 503
gatedClock 75:c2894d531f42 504 // pipeline variable.
gatedClock 57:0432c68ad232 505 Thread::wait(THREAD_5_WAITmS); // multitasking.
gatedClock 57:0432c68ad232 506 } // thread loop.
gatedClock 57:0432c68ad232 507 } // threadCookStateFSM.
gatedClock 57:0432c68ad232 508 /*----------------------------------------------//----------------------------*/
gatedClock 19:92b11e30aaaf 509 void slowClock(void) // 1Hz or thereabouts.
gatedClock 19:92b11e30aaaf 510 {
gatedClock 24:d39516e077ea 511 gcSlowClock = !gcSlowClock; // toggle clock.
gatedClock 19:92b11e30aaaf 512 }
gatedClock 19:92b11e30aaaf 513 /*----------------------------------------------//----------------------------*/
gatedClock 0:fcca4db7b32a 514 void initialization(void) // program initializations.
gatedClock 0:fcca4db7b32a 515 {
gatedClock 16:db7f0b3b2605 516 gcSignalWaitEnable = 1;
gatedClock 0:fcca4db7b32a 517 }
gatedClock 0:fcca4db7b32a 518 /*----------------------------------------------//----------------------------*/
gatedClock 26:bff592483cb1 519 void ISRleftButtonRising(void) // cooktime plus 60s.
gatedClock 1:9188d4668a88 520 {
gatedClock 66:4a0006fa5cc1 521 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 26:bff592483cb1 522 gtButtons.cLeftButton = 1; // detect left button.
gatedClock 9:cfdb9aa5857c 523
gatedClock 66:4a0006fa5cc1 524 debounceTimer.reset(); // begin debounce period.
gatedClock 11:9cae003da12b 525 }
gatedClock 1:9188d4668a88 526 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 527 void ISRleftButtonFalling(void) // button-release debounce.
gatedClock 1:9188d4668a88 528 {
gatedClock 66:4a0006fa5cc1 529 debounceTimer.reset(); // begin debounce period.
gatedClock 11:9cae003da12b 530 }
gatedClock 2:665ffa57031f 531 /*----------------------------------------------//----------------------------*/
gatedClock 26:bff592483cb1 532 void ISRrightButtonRising(void) // cooktime -60s.
gatedClock 12:e40272e1fd8f 533 {
gatedClock 66:4a0006fa5cc1 534 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 26:bff592483cb1 535 gtButtons.cRightButton = 1; // detect right button.
gatedClock 12:e40272e1fd8f 536
gatedClock 66:4a0006fa5cc1 537 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 538 }
gatedClock 12:e40272e1fd8f 539 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 540 void ISRrightButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 541 {
gatedClock 66:4a0006fa5cc1 542 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 543 }
gatedClock 12:e40272e1fd8f 544 /*----------------------------------------------//----------------------------*/
gatedClock 26:bff592483cb1 545 void ISRtopButtonRising(void) // cook start.
gatedClock 12:e40272e1fd8f 546 {
gatedClock 66:4a0006fa5cc1 547 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 26:bff592483cb1 548 gtButtons.cTopButton = 1; // detect top button.
gatedClock 12:e40272e1fd8f 549
gatedClock 66:4a0006fa5cc1 550 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 551 }
gatedClock 12:e40272e1fd8f 552 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 553 void ISRtopButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 554 {
gatedClock 66:4a0006fa5cc1 555 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 556 }
gatedClock 12:e40272e1fd8f 557 /*----------------------------------------------//----------------------------*/
gatedClock 53:8c2baf5623c8 558 // front-end control of magnetron off.
gatedClock 53:8c2baf5623c8 559 // due to physical danger, the magnetron is turned off immediately
gatedClock 53:8c2baf5623c8 560 // upon off-button press, in the interrupt that it generates.
gatedClock 53:8c2baf5623c8 561
gatedClock 26:bff592483cb1 562 void ISRbottomButtonRising(void) // cook stop.
gatedClock 12:e40272e1fd8f 563 {
gatedClock 66:4a0006fa5cc1 564 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 66:4a0006fa5cc1 565 {
gatedClock 66:4a0006fa5cc1 566 led0 = 0; // magnetron off.
gatedClock 66:4a0006fa5cc1 567 gtButtons.cBottomButton = 1; // detect bottom button.
gatedClock 66:4a0006fa5cc1 568 }
gatedClock 66:4a0006fa5cc1 569 debounceTimer.reset(); // begin debounce period.
gatedClock 66:4a0006fa5cc1 570 }
gatedClock 12:e40272e1fd8f 571 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 572 void ISRbottomButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 573 {
gatedClock 66:4a0006fa5cc1 574 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 575 }
gatedClock 12:e40272e1fd8f 576 /*----------------------------------------------//----------------------------*/
gatedClock 53:8c2baf5623c8 577 // front-end control of magnetron off.
gatedClock 53:8c2baf5623c8 578 // due to physical danger, the magnetron is turned off immediately
gatedClock 53:8c2baf5623c8 579 // upon detection of an open door.
gatedClock 53:8c2baf5623c8 580
gatedClock 26:bff592483cb1 581 void ISRcenterButtonRising(void) // toggle door state.
gatedClock 12:e40272e1fd8f 582 {
gatedClock 66:4a0006fa5cc1 583 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 66:4a0006fa5cc1 584 {
gatedClock 66:4a0006fa5cc1 585 if (gtButtons.cDoorOpen == MSG_OPEN) // calculate door state.
gatedClock 66:4a0006fa5cc1 586 gtButtons.cDoorOpen = MSG_CLOSED;
gatedClock 66:4a0006fa5cc1 587 else
gatedClock 66:4a0006fa5cc1 588 gtButtons.cDoorOpen = MSG_OPEN;
gatedClock 53:8c2baf5623c8 589
gatedClock 59:5e45b5e4a874 590 // magnetron off.
gatedClock 66:4a0006fa5cc1 591 if (gtButtons.cDoorOpen == MSG_OPEN) led0 = 0;
gatedClock 58:ec630b6dd9b1 592
gatedClock 66:4a0006fa5cc1 593 gtButtons.cCenterButton = 1;
gatedClock 66:4a0006fa5cc1 594 }
gatedClock 66:4a0006fa5cc1 595 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 596 }
gatedClock 12:e40272e1fd8f 597 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 598 void ISRcenterButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 599 {
gatedClock 66:4a0006fa5cc1 600 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 601 }
gatedClock 12:e40272e1fd8f 602 /*----------------------------------------------//----------------------------*/
gatedClock 40:7afff79f0d8b 603 void temperatureThread(void const *args) // temperature measurement.
gatedClock 39:4e7e4d935a87 604 {
gatedClock 45:e3207684e841 605 while(1) // thread loop.
gatedClock 45:e3207684e841 606 {
gatedClock 45:e3207684e841 607 gfCelsius = temperature.read(); // physical measurement.
gatedClock 40:7afff79f0d8b 608
gatedClock 45:e3207684e841 609 Thread::wait(THREAD_1_WAITmS); // multitasking.
gatedClock 45:e3207684e841 610 } // thread loop.
gatedClock 45:e3207684e841 611 } // temperatureThread.
gatedClock 42:266d5bbbfd19 612 /*----------------------------------------------//----------------------------*/
gatedClock 42:266d5bbbfd19 613 void LCDthread(void const *args) // LCD display thread.
gatedClock 42:266d5bbbfd19 614 {
gatedClock 67:1d9c85a4c3c1 615
gatedClock 67:1d9c85a4c3c1 616 static int dLCDtotalCookTimeSec = 0; // sample current values.
gatedClock 67:1d9c85a4c3c1 617 static int dCookTimeRemainingSec = 0;
gatedClock 67:1d9c85a4c3c1 618 static float fLCDcelsius = 0.0;
gatedClock 67:1d9c85a4c3c1 619
gatedClock 67:1d9c85a4c3c1 620 // remember previous values.
gatedClock 67:1d9c85a4c3c1 621 static int dLCDtotalCookTimeSecLast = 0;
gatedClock 67:1d9c85a4c3c1 622 static int dCookTimeRemainingSecLast = 0;
gatedClock 67:1d9c85a4c3c1 623 static float fLCDcelsiusLast = 0.0;
gatedClock 67:1d9c85a4c3c1 624
gatedClock 44:d16e813e61ef 625 while(1) // thread loop.
gatedClock 44:d16e813e61ef 626 {
gatedClock 67:1d9c85a4c3c1 627 // don't allow the values to
gatedClock 67:1d9c85a4c3c1 628 // change in the middle of the
gatedClock 67:1d9c85a4c3c1 629 // below else the anti-blink
gatedClock 67:1d9c85a4c3c1 630 // code won't work.
gatedClock 80:e3e1a2161435 631 dLCDtotalCookTimeSec = giLCD.dTotalCookTime;
gatedClock 80:e3e1a2161435 632 dCookTimeRemainingSec = giLCD.dRemainingTime;
gatedClock 80:e3e1a2161435 633 fLCDcelsius = giLCD.fCelsius;
gatedClock 80:e3e1a2161435 634
gatedClock 80:e3e1a2161435 635
gatedClock 67:1d9c85a4c3c1 636
gatedClock 67:1d9c85a4c3c1 637
gatedClock 67:1d9c85a4c3c1 638 // clear display only when
gatedClock 67:1d9c85a4c3c1 639 // necessary, in order to avoid
gatedClock 67:1d9c85a4c3c1 640 // 'blinkieness'.
gatedClock 67:1d9c85a4c3c1 641 if (dLCDtotalCookTimeSec != dLCDtotalCookTimeSecLast ||
gatedClock 67:1d9c85a4c3c1 642 dCookTimeRemainingSec != dCookTimeRemainingSecLast ||
gatedClock 67:1d9c85a4c3c1 643 fLCDcelsius != fLCDcelsiusLast)
gatedClock 67:1d9c85a4c3c1 644 lcd.cls();
gatedClock 42:266d5bbbfd19 645
gatedClock 44:d16e813e61ef 646 LCD1; // line 1.
gatedClock 67:1d9c85a4c3c1 647 lcd.printf(" total cook time: %d",dLCDtotalCookTimeSec);
gatedClock 42:266d5bbbfd19 648
gatedClock 44:d16e813e61ef 649 LCD2; // line 2.
gatedClock 67:1d9c85a4c3c1 650 lcd.printf(" remaing cook time: %d",dCookTimeRemainingSec);
gatedClock 42:266d5bbbfd19 651
gatedClock 44:d16e813e61ef 652 LCD3; // line 3.
gatedClock 67:1d9c85a4c3c1 653 lcd.printf(" temperature : %5.3f",fLCDcelsius);
gatedClock 67:1d9c85a4c3c1 654
gatedClock 67:1d9c85a4c3c1 655 // pipeline variables.
gatedClock 67:1d9c85a4c3c1 656 dLCDtotalCookTimeSecLast = dLCDtotalCookTimeSec;
gatedClock 67:1d9c85a4c3c1 657 dCookTimeRemainingSecLast = dCookTimeRemainingSec;
gatedClock 67:1d9c85a4c3c1 658 fLCDcelsiusLast = fLCDcelsius;
gatedClock 42:266d5bbbfd19 659
gatedClock 44:d16e813e61ef 660 Thread::wait(THREAD_2_WAITmS); // multitasking.
gatedClock 44:d16e813e61ef 661 } // thread loop.
gatedClock 44:d16e813e61ef 662 } // LCDthread.
gatedClock 42:266d5bbbfd19 663 /*----------------------------------------------//----------------------------*/
gatedClock 71:4a5f256ecf7c 664
gatedClock 88:0b1b812945eb 665 // cook remaining time countdown counter.
gatedClock 88:0b1b812945eb 666 // possibly due to a bug in Ticker
gatedClock 88:0b1b812945eb 667 // http://mbed.org/questions/1563/Mbed-Tickerfunction-hangs-system-from-re/
gatedClock 88:0b1b812945eb 668 // I've been unable to detach/attach this routine in order to reset its phase
gatedClock 88:0b1b812945eb 669 // when I tried it at a 1s resolution. In order to provide the human perception
gatedClock 88:0b1b812945eb 670 // of an immediate restart, I've increased the ticker frequency by the factor
gatedClock 88:0b1b812945eb 671 // 'GRANULARITY' and likewise divide that factor out when this routine
gatedClock 88:0b1b812945eb 672 // promotes the remaining time to the global variable.
gatedClock 88:0b1b812945eb 673
gatedClock 71:4a5f256ecf7c 674 void tickCookRemainingTime(void) // cook-cycle countdown.
gatedClock 71:4a5f256ecf7c 675 {
gatedClock 71:4a5f256ecf7c 676 static int dRemainingTime = 0; // remaining time in seconds.
gatedClock 88:0b1b812945eb 677 int dMaximum; // MAXSECONDS * GRANULARITY.
gatedClock 88:0b1b812945eb 678
gatedClock 88:0b1b812945eb 679 dMaximum = MAXSECONDS * GRANULARITY; // precalculate.
gatedClock 75:c2894d531f42 680
gatedClock 75:c2894d531f42 681 switch (giRemainingTime.cControl) // control processing.
gatedClock 71:4a5f256ecf7c 682 {
gatedClock 88:0b1b812945eb 683
gatedClock 72:b4d0c0aa3c26 684 case RT_PRELOAD : // preload with total time.
gatedClock 71:4a5f256ecf7c 685 {
gatedClock 88:0b1b812945eb 686 // the 'GRANULARITY - 1' factor
gatedClock 88:0b1b812945eb 687 // compensates for integer division
gatedClock 88:0b1b812945eb 688 // dropping the right-of-decimal result,
gatedClock 88:0b1b812945eb 689 // that occuring at the bottom of this
gatedClock 88:0b1b812945eb 690 // routine.
gatedClock 88:0b1b812945eb 691 dRemainingTime = (giRemainingTime.dTotalTime * GRANULARITY) + (GRANULARITY - 1);
gatedClock 71:4a5f256ecf7c 692 break;
gatedClock 71:4a5f256ecf7c 693 }
gatedClock 88:0b1b812945eb 694
gatedClock 72:b4d0c0aa3c26 695 case RT_DECREMENT : // count-down.
gatedClock 71:4a5f256ecf7c 696 {
gatedClock 72:b4d0c0aa3c26 697 dRemainingTime--;
gatedClock 71:4a5f256ecf7c 698 break;
gatedClock 71:4a5f256ecf7c 699 }
gatedClock 71:4a5f256ecf7c 700
gatedClock 72:b4d0c0aa3c26 701 case RT_PAUSE : // suspend countdown.
gatedClock 69:55b836e8ced7 702 {
gatedClock 72:b4d0c0aa3c26 703 dRemainingTime = dRemainingTime;
gatedClock 71:4a5f256ecf7c 704 break;
gatedClock 71:4a5f256ecf7c 705 }
gatedClock 71:4a5f256ecf7c 706
gatedClock 72:b4d0c0aa3c26 707 case RT_CLEAR : // clear countdown.
gatedClock 71:4a5f256ecf7c 708 {
gatedClock 76:74c454c9d75b 709 dRemainingTime = 0;
gatedClock 76:74c454c9d75b 710 led3 = 1;
gatedClock 71:4a5f256ecf7c 711 break;
gatedClock 71:4a5f256ecf7c 712 }
gatedClock 69:55b836e8ced7 713
gatedClock 72:b4d0c0aa3c26 714 default : // saturate, just in case.
gatedClock 72:b4d0c0aa3c26 715 {
gatedClock 72:b4d0c0aa3c26 716 }
gatedClock 75:c2894d531f42 717 } // control processing.
gatedClock 71:4a5f256ecf7c 718
gatedClock 88:0b1b812945eb 719 // saturate value.
gatedClock 88:0b1b812945eb 720 if (dRemainingTime > dMaximum) dRemainingTime = dMaximum;
gatedClock 88:0b1b812945eb 721 if (dRemainingTime < 0) dRemainingTime = 0;
gatedClock 88:0b1b812945eb 722
gatedClock 75:c2894d531f42 723 // promote to global scope.
gatedClock 86:388c2b4b7cf5 724 giRemainingTime.dRemainingTime = dRemainingTime/GRANULARITY;
gatedClock 70:7c0743c28b11 725
gatedClock 70:7c0743c28b11 726 } // cookRemainingTime.
gatedClock 69:55b836e8ced7 727 /*----------------------------------------------//----------------------------*/
gatedClock 69:55b836e8ced7 728
gatedClock 69:55b836e8ced7 729
gatedClock 69:55b836e8ced7 730
gatedClock 69:55b836e8ced7 731
gatedClock 69:55b836e8ced7 732
gatedClock 69:55b836e8ced7 733
gatedClock 69:55b836e8ced7 734
gatedClock 69:55b836e8ced7 735
gatedClock 69:55b836e8ced7 736
gatedClock 69:55b836e8ced7 737
gatedClock 69:55b836e8ced7 738