Project 1 Self-powered Health & Security Monitoring System USB device
Dependencies: C12832_lcd LM75B MMA7660 USBDevice mbed
main.cpp@1:930838234048, 2014-03-28 (annotated)
- Committer:
- wane
- Date:
- Fri Mar 28 18:19:54 2014 +0000
- Revision:
- 1:930838234048
- Parent:
- 0:88dc49222b35
- Child:
- 2:07c9334e3088
Updated comments in main.cpp.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wane | 1:930838234048 | 1 | // Project: Self-powered USB Health and Security Monitoring Device |
wane | 1:930838234048 | 2 | // Erick Wan |
wane | 1:930838234048 | 3 | // March 2014 |
wane | 1:930838234048 | 4 | // |
wane | 1:930838234048 | 5 | // Note: |
wane | 1:930838234048 | 6 | // The codes are written in a rush that they are missing descriptions, not as |
wane | 1:930838234048 | 7 | // organized or modularized, resource planning, etc. |
wane | 1:930838234048 | 8 | // More design, write-up and organizing work are required. |
wane | 1:930838234048 | 9 | // If you are learning to write codes in style, this is not a good example |
wane | 1:930838234048 | 10 | // to follow. |
wane | 1:930838234048 | 11 | // |
wane | 1:930838234048 | 12 | // Summary: |
wane | 1:930838234048 | 13 | // The self-powered system monitors temperature and detect motion when |
wane | 1:930838234048 | 14 | // attached to the USB host. It is first configured as HID device for |
wane | 1:930838234048 | 15 | // the sake of driver-free support. Audio alarm (when |
wane | 1:930838234048 | 16 | // connected an external buzzer at P21) and led will get turned on if |
wane | 1:930838234048 | 17 | // the temperature goes out of monitoring range or motion exceeds |
wane | 1:930838234048 | 18 | // detecting sensitivity threshold. |
wane | 1:930838234048 | 19 | // |
wane | 1:930838234048 | 20 | // Two modes: Test mode and Operation mode. In operational mode, |
wane | 1:930838234048 | 21 | // user can lock the device enter a passcode through serial debug |
wane | 1:930838234048 | 22 | // terminal. Motion alarm will continue to be on until the passcode |
wane | 1:930838234048 | 23 | // is entered. |
wane | 1:930838234048 | 24 | // |
wane | 1:930838234048 | 25 | // An external buzzer is used and connected at P21 and ground. |
wane | 1:930838234048 | 26 | // |
wane | 1:930838234048 | 27 | // Controls: |
wane | 1:930838234048 | 28 | // Joystick DOWN - Switch between Test and Operational mode |
wane | 1:930838234048 | 29 | // Joystick LEFT - Turn Temperature monitoring on and off |
wane | 1:930838234048 | 30 | // Joystick UP - Turn Motion monitoring on. Increase sensitivity |
wane | 1:930838234048 | 31 | // level as further push. S1-Low S2-Medium S3-High |
wane | 1:930838234048 | 32 | // Joystick RIGHT- Lock and unlock USB device. Enter passcode |
wane | 1:930838234048 | 33 | // at first locking device. |
wane | 1:930838234048 | 34 | // Pot1 - Lower bound temerature (for debugging) |
wane | 1:930838234048 | 35 | // Pot2 - Higher bound temperature (for debugging) |
wane | 1:930838234048 | 36 | // Fire - Input a simulated air temperature (for debugging) |
wane | 1:930838234048 | 37 | // |
wane | 1:930838234048 | 38 | // Output: |
wane | 1:930838234048 | 39 | // LED1 - USB Connection |
wane | 1:930838234048 | 40 | // LED2 - Lock Status (On-Lock Off-Unlocked) |
wane | 1:930838234048 | 41 | // LED3 - Alarm Status - Temperature |
wane | 1:930838234048 | 42 | // LED4 - Alarm Status - Motion |
wane | 1:930838234048 | 43 | // Buzzer - Temperature alarm beeps in lower frequency |
wane | 1:930838234048 | 44 | // Motion alarm beeps in relatively higher frequency |
wane | 1:930838234048 | 45 | // |
wane | 1:930838234048 | 46 | // History |
wane | 0:88dc49222b35 | 47 | /* 241: Added temp alarm |
wane | 0:88dc49222b35 | 48 | 251: Added motion alarm, sensitivity level |
wane | 0:88dc49222b35 | 49 | Validated alarm status handling |
wane | 0:88dc49222b35 | 50 | 252: Added lock, passcode control, mode (T-Testing; O-Operational) |
wane | 0:88dc49222b35 | 51 | 261: Added non-blocking serial entry |
wane | 0:88dc49222b35 | 52 | |
wane | 1:930838234048 | 53 | TO-FIX: |
wane | 1:930838234048 | 54 | 1. To complete USB connection detection. Currently, system stalls |
wane | 1:930838234048 | 55 | or fails to respond when detached from a USB host. |
wane | 0:88dc49222b35 | 56 | |
wane | 1:930838234048 | 57 | TO-DO: |
wane | 1:930838234048 | 58 | 1. Add menu display with LCD |
wane | 1:930838234048 | 59 | 2. Add data entry with LCD (without using serial) |
wane | 1:930838234048 | 60 | 3. Add file system that there can record events and save into files |
wane | 1:930838234048 | 61 | 4. Add capability to report to user remotely |
wane | 1:930838234048 | 62 | 5. Add to record and report sound once security is breached. |
wane | 1:930838234048 | 63 | 6. Add to record GPS data and report back |
wane | 0:88dc49222b35 | 64 | |
wane | 0:88dc49222b35 | 65 | */ |
wane | 0:88dc49222b35 | 66 | |
wane | 0:88dc49222b35 | 67 | #include "mbed.h" |
wane | 0:88dc49222b35 | 68 | #include "C12832_lcd.h" |
wane | 0:88dc49222b35 | 69 | #include "LM75B.h" |
wane | 0:88dc49222b35 | 70 | #include "MMA7660.h" |
wane | 0:88dc49222b35 | 71 | #include "USBKeyboard.h" |
wane | 0:88dc49222b35 | 72 | |
wane | 0:88dc49222b35 | 73 | // Configure device as USBKeyboard |
wane | 0:88dc49222b35 | 74 | USBKeyboard dev; |
wane | 0:88dc49222b35 | 75 | |
wane | 0:88dc49222b35 | 76 | #define UP 0x1 |
wane | 0:88dc49222b35 | 77 | #define DOWN 0x2 |
wane | 0:88dc49222b35 | 78 | #define LEFT 0x4 |
wane | 0:88dc49222b35 | 79 | #define RIGHT 0x8 |
wane | 0:88dc49222b35 | 80 | #define ON true |
wane | 0:88dc49222b35 | 81 | #define OFF false |
wane | 0:88dc49222b35 | 82 | |
wane | 0:88dc49222b35 | 83 | // System configuration parameters |
wane | 0:88dc49222b35 | 84 | #define YEAR 2014 |
wane | 0:88dc49222b35 | 85 | #define MONTH 3 |
wane | 0:88dc49222b35 | 86 | #define DATE 26 |
wane | 0:88dc49222b35 | 87 | #define HOUR 17 |
wane | 0:88dc49222b35 | 88 | #define MIN 35 |
wane | 0:88dc49222b35 | 89 | #define DEF_LOWER_TEMP 72 // Lower bound of monitoring temperature |
wane | 0:88dc49222b35 | 90 | #define DEF_UPPER_TEMP 89 // Upper bound of monitoring temperature |
wane | 0:88dc49222b35 | 91 | #define LOW_SEN 0.7 // Low sensitivity |
wane | 0:88dc49222b35 | 92 | #define MID_SEN 0.5 // Medium sensitivity |
wane | 0:88dc49222b35 | 93 | #define HIGH_SEN 0.3 // High sensitivity |
wane | 1:930838234048 | 94 | #define BUZZ_POWER 1 // Buzz power level |
wane | 0:88dc49222b35 | 95 | #define BUZZ_SPERIOD 0.2 // Security alarm buzz period |
wane | 1:930838234048 | 96 | #define BUZZ_TPERIOD 1 // Temperature alarm buzz period |
wane | 0:88dc49222b35 | 97 | |
wane | 0:88dc49222b35 | 98 | // System I/O |
wane | 0:88dc49222b35 | 99 | C12832_LCD lcd; |
wane | 0:88dc49222b35 | 100 | PwmOut alarm(p21); |
wane | 0:88dc49222b35 | 101 | BusIn joy(p15,p12,p13,p16); |
wane | 0:88dc49222b35 | 102 | InterruptIn IRQJoyUp(p15); |
wane | 0:88dc49222b35 | 103 | InterruptIn IRQJoyDown(p12); |
wane | 0:88dc49222b35 | 104 | InterruptIn IRQJoyLeft(p13); |
wane | 0:88dc49222b35 | 105 | InterruptIn IRQJoyRight(p16); |
wane | 0:88dc49222b35 | 106 | //DigitalIn fire(p14); |
wane | 0:88dc49222b35 | 107 | InterruptIn IRQFire(p14); |
wane | 0:88dc49222b35 | 108 | |
wane | 0:88dc49222b35 | 109 | Serial pc(USBTX, USBRX); // tx, rx |
wane | 0:88dc49222b35 | 110 | LM75B Ctmp(p28,p27); |
wane | 0:88dc49222b35 | 111 | AnalogIn pot1(p19); |
wane | 0:88dc49222b35 | 112 | AnalogIn pot2(p20); |
wane | 0:88dc49222b35 | 113 | MMA7660 MMA(p28, p27); |
wane | 0:88dc49222b35 | 114 | DigitalOut connectionLed(LED1); |
wane | 0:88dc49222b35 | 115 | DigitalOut lockLed(LED2); |
wane | 0:88dc49222b35 | 116 | //PwmOut Xaxis_p(LED2); |
wane | 0:88dc49222b35 | 117 | //BusOut leds(LED3,LED4); |
wane | 0:88dc49222b35 | 118 | //DigitalOut ledTAlarm(LED3); |
wane | 0:88dc49222b35 | 119 | //DigitalOut ledSAlarm(LED4); |
wane | 0:88dc49222b35 | 120 | PwmOut ledSAlarm(LED4); |
wane | 0:88dc49222b35 | 121 | PwmOut ledTAlarm(LED3); |
wane | 0:88dc49222b35 | 122 | |
wane | 0:88dc49222b35 | 123 | // Gobal parameters |
wane | 0:88dc49222b35 | 124 | float setUpperTemp; // Upper bound of temperature monitoring range |
wane | 0:88dc49222b35 | 125 | float setLowerTemp; // Lower bound of temperature monitoring range |
wane | 0:88dc49222b35 | 126 | bool sAlarmOn; // State of alarm |
wane | 0:88dc49222b35 | 127 | int statusAlarm; // Status indicating whether health or/and security alarm is triggered |
wane | 0:88dc49222b35 | 128 | bool sHealthFeatureActive; // State indicating temperature monitoring is activated |
wane | 0:88dc49222b35 | 129 | bool sSecurityFeatureActive; // State indicating motion monitoring is activated |
wane | 0:88dc49222b35 | 130 | bool sLockActive; // State indicating lock is active |
wane | 0:88dc49222b35 | 131 | char sState; // security setting state |
wane | 0:88dc49222b35 | 132 | char gState; // Global state |
wane | 0:88dc49222b35 | 133 | int buzzPattern; |
wane | 0:88dc49222b35 | 134 | float buzzPeriod; |
wane | 0:88dc49222b35 | 135 | Ticker timer1; |
wane | 0:88dc49222b35 | 136 | Ticker timer3; |
wane | 0:88dc49222b35 | 137 | Ticker timer4; |
wane | 0:88dc49222b35 | 138 | Timer timer2; |
wane | 0:88dc49222b35 | 139 | Ticker ticAlarm; |
wane | 0:88dc49222b35 | 140 | bool first; |
wane | 0:88dc49222b35 | 141 | int count; |
wane | 0:88dc49222b35 | 142 | bool activated; // for debounce fire |
wane | 0:88dc49222b35 | 143 | time_t yet; |
wane | 0:88dc49222b35 | 144 | time_t now; |
wane | 0:88dc49222b35 | 145 | int alarmType; // 0 - Health; 1 - Security |
wane | 0:88dc49222b35 | 146 | char senLevel; // Sensitivity level of motion alarm |
wane | 0:88dc49222b35 | 147 | int mode; // Operation mode: |
wane | 0:88dc49222b35 | 148 | // 0 = Test mode (for testing features) |
wane | 0:88dc49222b35 | 149 | // 1 = Lock mode (lock and unlock device) |
wane | 0:88dc49222b35 | 150 | int passcode; // 4-digit passcode for lock and unlock |
wane | 0:88dc49222b35 | 151 | bool sPCOK; // state indicating a valid passcode is existing |
wane | 0:88dc49222b35 | 152 | |
wane | 0:88dc49222b35 | 153 | bool updateCurTempDisplay; |
wane | 0:88dc49222b35 | 154 | bool updateJoyDisplay; |
wane | 0:88dc49222b35 | 155 | bool tempOverride; |
wane | 0:88dc49222b35 | 156 | float lowerTempBase; // For simulated lower bound temperature |
wane | 0:88dc49222b35 | 157 | float upperTempBase; // For simulated upper bound temperature |
wane | 0:88dc49222b35 | 158 | float temp; |
wane | 0:88dc49222b35 | 159 | |
wane | 0:88dc49222b35 | 160 | bool entryReady; // For tracking if user input is comlete |
wane | 0:88dc49222b35 | 161 | unsigned char entryState; // State tracking input entry |
wane | 0:88dc49222b35 | 162 | char inBuf[128]; // Input buffer |
wane | 0:88dc49222b35 | 163 | char pos; // Gobal buffer index |
wane | 0:88dc49222b35 | 164 | |
wane | 0:88dc49222b35 | 165 | |
wane | 0:88dc49222b35 | 166 | float timeElapsed; |
wane | 0:88dc49222b35 | 167 | time_t seconds; |
wane | 0:88dc49222b35 | 168 | |
wane | 0:88dc49222b35 | 169 | float potBase1; |
wane | 0:88dc49222b35 | 170 | float potBase2; |
wane | 0:88dc49222b35 | 171 | |
wane | 0:88dc49222b35 | 172 | |
wane | 0:88dc49222b35 | 173 | typedef struct { |
wane | 0:88dc49222b35 | 174 | bool active; |
wane | 0:88dc49222b35 | 175 | float factor; |
wane | 0:88dc49222b35 | 176 | unsigned char sym[3]; |
wane | 0:88dc49222b35 | 177 | } SENTYPE; |
wane | 0:88dc49222b35 | 178 | |
wane | 0:88dc49222b35 | 179 | const SENTYPE senParm[4] = { |
wane | 0:88dc49222b35 | 180 | { false, LOW_SEN, " " }, |
wane | 0:88dc49222b35 | 181 | { true, LOW_SEN, "S1" }, // Low sensitivity |
wane | 0:88dc49222b35 | 182 | { true, MID_SEN, "S2" }, // Mid sensitivity |
wane | 0:88dc49222b35 | 183 | { true, HIGH_SEN, "S3" }, // High sensitivity |
wane | 0:88dc49222b35 | 184 | }; |
wane | 0:88dc49222b35 | 185 | |
wane | 0:88dc49222b35 | 186 | const char modeSym[2] = { 'T', 'O' }; |
wane | 0:88dc49222b35 | 187 | |
wane | 0:88dc49222b35 | 188 | /* |
wane | 0:88dc49222b35 | 189 | enum FUNCTION_KEY { |
wane | 0:88dc49222b35 | 190 | KEY_SCROLL_LOCK = 141, // Scroll lock |
wane | 0:88dc49222b35 | 191 | KEY_CAPS_LOCK, // caps lock |
wane | 0:88dc49222b35 | 192 | KEY_NUM_LOCK, // num lock |
wane | 0:88dc49222b35 | 193 | }; |
wane | 0:88dc49222b35 | 194 | */ |
wane | 0:88dc49222b35 | 195 | |
wane | 0:88dc49222b35 | 196 | // Function prototype |
wane | 0:88dc49222b35 | 197 | void ISRFirePressed(); |
wane | 0:88dc49222b35 | 198 | void ISRJoyUp(); |
wane | 0:88dc49222b35 | 199 | void ISRJoyDown(); |
wane | 0:88dc49222b35 | 200 | void ISRJoyLeft(); |
wane | 0:88dc49222b35 | 201 | void ISRJoyRight(); |
wane | 0:88dc49222b35 | 202 | void debounce(); |
wane | 0:88dc49222b35 | 203 | void buzzOn(int pattern, float period); |
wane | 0:88dc49222b35 | 204 | void buzzOff(); |
wane | 0:88dc49222b35 | 205 | void buzzTest(); |
wane | 0:88dc49222b35 | 206 | void peepEntry(); |
wane | 0:88dc49222b35 | 207 | void calibratePot(); |
wane | 0:88dc49222b35 | 208 | bool EnterTemp(); |
wane | 0:88dc49222b35 | 209 | bool SetPasscode(); |
wane | 0:88dc49222b35 | 210 | bool UnlockPasscode(); |
wane | 0:88dc49222b35 | 211 | void USBConnCheck(); |
wane | 0:88dc49222b35 | 212 | void SetTime(int year, int month, int date, int hour, int min, int sec); |
wane | 0:88dc49222b35 | 213 | void TempMonitor(); |
wane | 0:88dc49222b35 | 214 | void ReadTemp(); |
wane | 0:88dc49222b35 | 215 | void MotionMonitor(); |
wane | 0:88dc49222b35 | 216 | void DisplayLCD(); |
wane | 0:88dc49222b35 | 217 | void AlarmCheck(); |
wane | 0:88dc49222b35 | 218 | void FSM(void); |
wane | 0:88dc49222b35 | 219 | |
wane | 0:88dc49222b35 | 220 | |
wane | 0:88dc49222b35 | 221 | // ISR for fire button |
wane | 0:88dc49222b35 | 222 | void ISRFirePressed() |
wane | 0:88dc49222b35 | 223 | { |
wane | 0:88dc49222b35 | 224 | now = time(NULL); |
wane | 0:88dc49222b35 | 225 | if (!activated && now > yet) { |
wane | 0:88dc49222b35 | 226 | |
wane | 0:88dc49222b35 | 227 | tempOverride = !tempOverride; |
wane | 0:88dc49222b35 | 228 | //EnterTemp(); |
wane | 0:88dc49222b35 | 229 | if (tempOverride) |
wane | 0:88dc49222b35 | 230 | gState = 3; |
wane | 0:88dc49222b35 | 231 | yet = now + 1; |
wane | 0:88dc49222b35 | 232 | activated = true; |
wane | 0:88dc49222b35 | 233 | } |
wane | 0:88dc49222b35 | 234 | |
wane | 0:88dc49222b35 | 235 | } |
wane | 0:88dc49222b35 | 236 | |
wane | 0:88dc49222b35 | 237 | |
wane | 0:88dc49222b35 | 238 | // ISR for joystick up direction |
wane | 0:88dc49222b35 | 239 | void ISRJoyUp() |
wane | 0:88dc49222b35 | 240 | { |
wane | 0:88dc49222b35 | 241 | now = time(NULL); |
wane | 0:88dc49222b35 | 242 | if (!activated && now > yet) { |
wane | 0:88dc49222b35 | 243 | //if (mode == 1 && sPCOK == false) |
wane | 0:88dc49222b35 | 244 | // EnterPasscode(); |
wane | 0:88dc49222b35 | 245 | senLevel = (senLevel + 1) % 4; |
wane | 0:88dc49222b35 | 246 | sSecurityFeatureActive = senParm[senLevel].active; |
wane | 0:88dc49222b35 | 247 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 248 | yet = now + 1; |
wane | 0:88dc49222b35 | 249 | activated = true; |
wane | 0:88dc49222b35 | 250 | } |
wane | 0:88dc49222b35 | 251 | } |
wane | 0:88dc49222b35 | 252 | |
wane | 0:88dc49222b35 | 253 | // ISR for joystick down direction |
wane | 0:88dc49222b35 | 254 | void ISRJoyDown() |
wane | 0:88dc49222b35 | 255 | { |
wane | 0:88dc49222b35 | 256 | now = time(NULL); |
wane | 0:88dc49222b35 | 257 | if (!activated && now > yet) { |
wane | 0:88dc49222b35 | 258 | mode = (mode + 1) % 2; |
wane | 0:88dc49222b35 | 259 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 260 | yet = now + 1; |
wane | 0:88dc49222b35 | 261 | activated = true; |
wane | 0:88dc49222b35 | 262 | } |
wane | 0:88dc49222b35 | 263 | } |
wane | 0:88dc49222b35 | 264 | |
wane | 0:88dc49222b35 | 265 | // ISR for joystick left direction |
wane | 0:88dc49222b35 | 266 | void ISRJoyLeft() |
wane | 0:88dc49222b35 | 267 | { |
wane | 0:88dc49222b35 | 268 | now = time(NULL); |
wane | 0:88dc49222b35 | 269 | if (!activated && now > yet) { |
wane | 0:88dc49222b35 | 270 | sHealthFeatureActive = !sHealthFeatureActive; |
wane | 0:88dc49222b35 | 271 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 272 | yet = now + 1; |
wane | 0:88dc49222b35 | 273 | activated = true; |
wane | 0:88dc49222b35 | 274 | } |
wane | 0:88dc49222b35 | 275 | } |
wane | 0:88dc49222b35 | 276 | |
wane | 0:88dc49222b35 | 277 | // ISR for joystick right direction |
wane | 0:88dc49222b35 | 278 | void ISRJoyRight() |
wane | 0:88dc49222b35 | 279 | { |
wane | 0:88dc49222b35 | 280 | now = time(NULL); |
wane | 0:88dc49222b35 | 281 | if (!activated && now > yet) { |
wane | 0:88dc49222b35 | 282 | if (mode == 1) |
wane | 0:88dc49222b35 | 283 | { |
wane | 0:88dc49222b35 | 284 | if (!sLockActive) |
wane | 0:88dc49222b35 | 285 | gState = 1; |
wane | 0:88dc49222b35 | 286 | else |
wane | 0:88dc49222b35 | 287 | gState = 2; |
wane | 0:88dc49222b35 | 288 | } |
wane | 0:88dc49222b35 | 289 | yet = now + 1; |
wane | 0:88dc49222b35 | 290 | activated = true; |
wane | 0:88dc49222b35 | 291 | } |
wane | 0:88dc49222b35 | 292 | } |
wane | 0:88dc49222b35 | 293 | |
wane | 0:88dc49222b35 | 294 | // Debouncer function |
wane | 0:88dc49222b35 | 295 | void debounce() |
wane | 0:88dc49222b35 | 296 | { |
wane | 0:88dc49222b35 | 297 | if (activated) |
wane | 0:88dc49222b35 | 298 | activated = false; |
wane | 0:88dc49222b35 | 299 | } |
wane | 0:88dc49222b35 | 300 | |
wane | 1:930838234048 | 301 | // Turn on buzzer in different patterns |
wane | 0:88dc49222b35 | 302 | void buzzOn(int pattern, float period) |
wane | 0:88dc49222b35 | 303 | { |
wane | 0:88dc49222b35 | 304 | switch (pattern) { |
wane | 0:88dc49222b35 | 305 | case 0: // Temperature |
wane | 0:88dc49222b35 | 306 | alarm = BUZZ_POWER; |
wane | 0:88dc49222b35 | 307 | wait(0.2); |
wane | 0:88dc49222b35 | 308 | alarm = 0; |
wane | 0:88dc49222b35 | 309 | wait(period); |
wane | 0:88dc49222b35 | 310 | /* |
wane | 0:88dc49222b35 | 311 | for(float p=0; p<1.0; p += 0.1) { |
wane | 0:88dc49222b35 | 312 | alarm = p; |
wane | 0:88dc49222b35 | 313 | wait(period); |
wane | 0:88dc49222b35 | 314 | } |
wane | 0:88dc49222b35 | 315 | */ |
wane | 0:88dc49222b35 | 316 | break; |
wane | 0:88dc49222b35 | 317 | case 1: // Security |
wane | 0:88dc49222b35 | 318 | alarm = BUZZ_POWER; |
wane | 0:88dc49222b35 | 319 | wait(0.2); |
wane | 0:88dc49222b35 | 320 | alarm = 0; |
wane | 0:88dc49222b35 | 321 | wait(period); |
wane | 0:88dc49222b35 | 322 | break; |
wane | 0:88dc49222b35 | 323 | |
wane | 0:88dc49222b35 | 324 | } |
wane | 0:88dc49222b35 | 325 | } |
wane | 0:88dc49222b35 | 326 | |
wane | 0:88dc49222b35 | 327 | // Turn on led in different patterns |
wane | 0:88dc49222b35 | 328 | void ledOn(int type, float period) |
wane | 0:88dc49222b35 | 329 | { |
wane | 0:88dc49222b35 | 330 | switch (type) { |
wane | 0:88dc49222b35 | 331 | case 0: |
wane | 0:88dc49222b35 | 332 | ledTAlarm = 1; |
wane | 0:88dc49222b35 | 333 | wait(0.1); |
wane | 0:88dc49222b35 | 334 | ledTAlarm = 0; |
wane | 0:88dc49222b35 | 335 | wait(0.05); |
wane | 0:88dc49222b35 | 336 | break; |
wane | 0:88dc49222b35 | 337 | case 1: |
wane | 1:930838234048 | 338 | /* |
wane | 0:88dc49222b35 | 339 | for(int p=0; p<10; p += 1) { |
wane | 0:88dc49222b35 | 340 | ledSAlarm = 1; |
wane | 0:88dc49222b35 | 341 | wait(0.02); |
wane | 0:88dc49222b35 | 342 | ledSAlarm = 0; |
wane | 0:88dc49222b35 | 343 | wait(0.02); |
wane | 0:88dc49222b35 | 344 | } |
wane | 1:930838234048 | 345 | */ |
wane | 0:88dc49222b35 | 346 | ledSAlarm = 1; |
wane | 0:88dc49222b35 | 347 | wait(0.1); |
wane | 0:88dc49222b35 | 348 | ledSAlarm = 0; |
wane | 0:88dc49222b35 | 349 | wait(0.02); |
wane | 0:88dc49222b35 | 350 | break; |
wane | 0:88dc49222b35 | 351 | |
wane | 0:88dc49222b35 | 352 | } |
wane | 0:88dc49222b35 | 353 | } |
wane | 0:88dc49222b35 | 354 | |
wane | 0:88dc49222b35 | 355 | // Turn off alarm |
wane | 0:88dc49222b35 | 356 | void buzzOff() |
wane | 0:88dc49222b35 | 357 | { |
wane | 0:88dc49222b35 | 358 | alarm = 0; |
wane | 0:88dc49222b35 | 359 | } |
wane | 0:88dc49222b35 | 360 | |
wane | 1:930838234048 | 361 | // For testing buzzer. |
wane | 0:88dc49222b35 | 362 | void buzzTest() |
wane | 0:88dc49222b35 | 363 | { |
wane | 0:88dc49222b35 | 364 | sAlarmOn = OFF; |
wane | 0:88dc49222b35 | 365 | |
wane | 0:88dc49222b35 | 366 | timer1.attach(&debounce, 1); |
wane | 0:88dc49222b35 | 367 | //IRQFire.rise(&ISRFirePressed); |
wane | 0:88dc49222b35 | 368 | //IRQFire.fall(&ISRFireRelease); |
wane | 0:88dc49222b35 | 369 | //IRQJoyUp.rise(&ISRJoyUp); |
wane | 0:88dc49222b35 | 370 | //IRQJoyDown.rise(&ISRJoyDown); |
wane | 0:88dc49222b35 | 371 | |
wane | 0:88dc49222b35 | 372 | alarm.period(0.020); // servo requires a 20ms period |
wane | 0:88dc49222b35 | 373 | |
wane | 0:88dc49222b35 | 374 | printf("Test starts...\n\r"); |
wane | 0:88dc49222b35 | 375 | |
wane | 0:88dc49222b35 | 376 | while (1) |
wane | 0:88dc49222b35 | 377 | { |
wane | 0:88dc49222b35 | 378 | if (sAlarmOn) { |
wane | 0:88dc49222b35 | 379 | buzzOn(buzzPattern, buzzPeriod); |
wane | 0:88dc49222b35 | 380 | printf("%s: pattern: %d period: %.1f count: %d\n\r", sAlarmOn? "ON": "OFF", buzzPattern, buzzPeriod, count); |
wane | 0:88dc49222b35 | 381 | } else { |
wane | 0:88dc49222b35 | 382 | buzzOff(); |
wane | 0:88dc49222b35 | 383 | buzzPattern = (buzzPattern + 1) % 2; |
wane | 0:88dc49222b35 | 384 | count = 0; |
wane | 0:88dc49222b35 | 385 | } |
wane | 0:88dc49222b35 | 386 | wait(0.02); |
wane | 0:88dc49222b35 | 387 | } |
wane | 0:88dc49222b35 | 388 | } |
wane | 0:88dc49222b35 | 389 | |
wane | 0:88dc49222b35 | 390 | |
wane | 0:88dc49222b35 | 391 | // Set date and time |
wane | 0:88dc49222b35 | 392 | // Input: Year, month, date, hour, minute, second |
wane | 0:88dc49222b35 | 393 | void SetTime(int year, int month, int date, int hour, int min, int sec) |
wane | 0:88dc49222b35 | 394 | { |
wane | 0:88dc49222b35 | 395 | struct tm Clock; |
wane | 0:88dc49222b35 | 396 | Clock.tm_year = year - 1900; |
wane | 0:88dc49222b35 | 397 | Clock.tm_mon = month - 1; |
wane | 0:88dc49222b35 | 398 | Clock.tm_mday = date; |
wane | 0:88dc49222b35 | 399 | Clock.tm_hour = hour; |
wane | 0:88dc49222b35 | 400 | Clock.tm_min = min; |
wane | 0:88dc49222b35 | 401 | Clock.tm_sec = sec; |
wane | 0:88dc49222b35 | 402 | time_t epoch = mktime(&Clock); |
wane | 0:88dc49222b35 | 403 | if (epoch == (time_t) -1) { |
wane | 0:88dc49222b35 | 404 | error("Error: Invalid clock setting! Please try again.\n"); |
wane | 0:88dc49222b35 | 405 | } |
wane | 0:88dc49222b35 | 406 | set_time(epoch); |
wane | 0:88dc49222b35 | 407 | } |
wane | 0:88dc49222b35 | 408 | |
wane | 0:88dc49222b35 | 409 | // Calibrate analog pot to allow tuning each pot for controlling upper and lower bound control temperature |
wane | 0:88dc49222b35 | 410 | void calibratePot() |
wane | 0:88dc49222b35 | 411 | { |
wane | 0:88dc49222b35 | 412 | potBase1 = pot1.read(); |
wane | 0:88dc49222b35 | 413 | potBase2 = pot2.read(); |
wane | 0:88dc49222b35 | 414 | //tempBase = temp; |
wane | 0:88dc49222b35 | 415 | lowerTempBase = setLowerTemp; |
wane | 0:88dc49222b35 | 416 | upperTempBase = setUpperTemp; |
wane | 0:88dc49222b35 | 417 | |
wane | 0:88dc49222b35 | 418 | |
wane | 0:88dc49222b35 | 419 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 420 | |
wane | 0:88dc49222b35 | 421 | wait(0.5); |
wane | 0:88dc49222b35 | 422 | |
wane | 0:88dc49222b35 | 423 | } |
wane | 0:88dc49222b35 | 424 | |
wane | 0:88dc49222b35 | 425 | // Non-blockingly innput a simulated temperature |
wane | 0:88dc49222b35 | 426 | // Input: None |
wane | 0:88dc49222b35 | 427 | bool EnterTemp() |
wane | 0:88dc49222b35 | 428 | { |
wane | 0:88dc49222b35 | 429 | int i; |
wane | 0:88dc49222b35 | 430 | bool done = false; |
wane | 0:88dc49222b35 | 431 | |
wane | 0:88dc49222b35 | 432 | switch (entryState) |
wane | 0:88dc49222b35 | 433 | { |
wane | 0:88dc49222b35 | 434 | case 0: |
wane | 0:88dc49222b35 | 435 | break; |
wane | 0:88dc49222b35 | 436 | case 1: |
wane | 0:88dc49222b35 | 437 | pc.printf("\n\rEnter a simulated temperature: "); |
wane | 0:88dc49222b35 | 438 | entryReady = false; |
wane | 0:88dc49222b35 | 439 | entryState = 2; |
wane | 0:88dc49222b35 | 440 | break; |
wane | 0:88dc49222b35 | 441 | case 2: |
wane | 0:88dc49222b35 | 442 | peepEntry(); |
wane | 0:88dc49222b35 | 443 | if (!entryReady) |
wane | 0:88dc49222b35 | 444 | break; |
wane | 0:88dc49222b35 | 445 | else |
wane | 0:88dc49222b35 | 446 | entryState = 3; |
wane | 0:88dc49222b35 | 447 | case 3: |
wane | 0:88dc49222b35 | 448 | sscanf(inBuf, "%d", &i); |
wane | 0:88dc49222b35 | 449 | if (i < 0 || i >= 100) { |
wane | 0:88dc49222b35 | 450 | printf("\n\rEnter a temperature between 0F and 100F: "); |
wane | 0:88dc49222b35 | 451 | entryReady = false; |
wane | 0:88dc49222b35 | 452 | entryState = 2; |
wane | 0:88dc49222b35 | 453 | break; |
wane | 0:88dc49222b35 | 454 | } else { |
wane | 0:88dc49222b35 | 455 | temp = i; |
wane | 0:88dc49222b35 | 456 | printf("Current temperature is now %dF.\n\r", i); |
wane | 0:88dc49222b35 | 457 | updateCurTempDisplay = true; |
wane | 0:88dc49222b35 | 458 | entryState = 1; |
wane | 0:88dc49222b35 | 459 | done = true; |
wane | 0:88dc49222b35 | 460 | calibratePot(); |
wane | 0:88dc49222b35 | 461 | break; |
wane | 0:88dc49222b35 | 462 | } |
wane | 0:88dc49222b35 | 463 | |
wane | 0:88dc49222b35 | 464 | |
wane | 0:88dc49222b35 | 465 | } |
wane | 0:88dc49222b35 | 466 | return done; |
wane | 0:88dc49222b35 | 467 | |
wane | 0:88dc49222b35 | 468 | } |
wane | 0:88dc49222b35 | 469 | |
wane | 1:930838234048 | 470 | // Peep uart buffer if serial data is available for read |
wane | 1:930838234048 | 471 | // Return the entry when hit ENTER button |
wane | 0:88dc49222b35 | 472 | void peepEntry() |
wane | 0:88dc49222b35 | 473 | { |
wane | 0:88dc49222b35 | 474 | int i; |
wane | 0:88dc49222b35 | 475 | char c; |
wane | 0:88dc49222b35 | 476 | i = pc.readable(); |
wane | 0:88dc49222b35 | 477 | |
wane | 0:88dc49222b35 | 478 | if (i > 0) { |
wane | 0:88dc49222b35 | 479 | //pc.printf("%d: ", i); |
wane | 0:88dc49222b35 | 480 | while (i > 0) { |
wane | 0:88dc49222b35 | 481 | c = pc.getc(); |
wane | 0:88dc49222b35 | 482 | |
wane | 0:88dc49222b35 | 483 | if (c == '\r') { |
wane | 0:88dc49222b35 | 484 | pc.printf("\n\r"); |
wane | 0:88dc49222b35 | 485 | inBuf[pos] = '\0'; |
wane | 0:88dc49222b35 | 486 | //pc.printf("Return: %s\n\r", inBuf); |
wane | 0:88dc49222b35 | 487 | pos = 0; |
wane | 0:88dc49222b35 | 488 | entryReady = true; |
wane | 0:88dc49222b35 | 489 | |
wane | 0:88dc49222b35 | 490 | } else { |
wane | 0:88dc49222b35 | 491 | //pc.printf("%c\n\r", c); |
wane | 0:88dc49222b35 | 492 | pc.putc(c); |
wane | 0:88dc49222b35 | 493 | inBuf[pos] = c; |
wane | 0:88dc49222b35 | 494 | pos++; |
wane | 0:88dc49222b35 | 495 | } |
wane | 0:88dc49222b35 | 496 | i--; |
wane | 0:88dc49222b35 | 497 | } |
wane | 0:88dc49222b35 | 498 | |
wane | 0:88dc49222b35 | 499 | } |
wane | 0:88dc49222b35 | 500 | } |
wane | 0:88dc49222b35 | 501 | |
wane | 0:88dc49222b35 | 502 | // Non-blockingly set a passcode |
wane | 0:88dc49222b35 | 503 | // Input: None |
wane | 0:88dc49222b35 | 504 | bool SetPasscode() |
wane | 0:88dc49222b35 | 505 | { |
wane | 0:88dc49222b35 | 506 | int i; |
wane | 0:88dc49222b35 | 507 | bool done = false; |
wane | 0:88dc49222b35 | 508 | |
wane | 0:88dc49222b35 | 509 | switch (entryState) |
wane | 0:88dc49222b35 | 510 | { |
wane | 0:88dc49222b35 | 511 | case 0: |
wane | 0:88dc49222b35 | 512 | break; |
wane | 0:88dc49222b35 | 513 | case 1: |
wane | 0:88dc49222b35 | 514 | if (statusAlarm & 0x80000000) |
wane | 0:88dc49222b35 | 515 | { |
wane | 0:88dc49222b35 | 516 | if (!sPCOK) |
wane | 0:88dc49222b35 | 517 | entryState = 2; |
wane | 0:88dc49222b35 | 518 | else |
wane | 0:88dc49222b35 | 519 | entryState = 5; |
wane | 0:88dc49222b35 | 520 | } |
wane | 0:88dc49222b35 | 521 | else |
wane | 0:88dc49222b35 | 522 | { |
wane | 0:88dc49222b35 | 523 | pc.printf("No USB connection detected. Check USB device being connected.\n\r"); |
wane | 0:88dc49222b35 | 524 | } |
wane | 0:88dc49222b35 | 525 | break; |
wane | 0:88dc49222b35 | 526 | |
wane | 0:88dc49222b35 | 527 | case 2: |
wane | 0:88dc49222b35 | 528 | pc.printf("\n\rEnter a 4-digit passcode: "); |
wane | 0:88dc49222b35 | 529 | entryReady = false; |
wane | 0:88dc49222b35 | 530 | entryState = 3; |
wane | 0:88dc49222b35 | 531 | break; |
wane | 0:88dc49222b35 | 532 | case 3: |
wane | 0:88dc49222b35 | 533 | peepEntry(); |
wane | 0:88dc49222b35 | 534 | if (!entryReady) |
wane | 0:88dc49222b35 | 535 | break; |
wane | 0:88dc49222b35 | 536 | else |
wane | 0:88dc49222b35 | 537 | entryState = 4; |
wane | 0:88dc49222b35 | 538 | case 4: |
wane | 0:88dc49222b35 | 539 | sscanf(inBuf, "%d", &i); |
wane | 0:88dc49222b35 | 540 | if (i < 0000 || i > 9999) { |
wane | 0:88dc49222b35 | 541 | pc.printf("\n\rEnter a passcode between 0000 and 9999: "); |
wane | 0:88dc49222b35 | 542 | entryReady = false; |
wane | 0:88dc49222b35 | 543 | entryState = 3; |
wane | 0:88dc49222b35 | 544 | break; |
wane | 0:88dc49222b35 | 545 | } else { |
wane | 0:88dc49222b35 | 546 | passcode = i; |
wane | 0:88dc49222b35 | 547 | pc.printf("\n\rPasscode is set (%d).\n\r", passcode); |
wane | 0:88dc49222b35 | 548 | sPCOK = true; |
wane | 0:88dc49222b35 | 549 | entryState = 5; |
wane | 0:88dc49222b35 | 550 | } |
wane | 0:88dc49222b35 | 551 | case 5: |
wane | 0:88dc49222b35 | 552 | sLockActive = true; |
wane | 0:88dc49222b35 | 553 | lockLed = 1; |
wane | 0:88dc49222b35 | 554 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 555 | pc.printf("USB is now locked. Enter passcode to unlock.\n\r"); |
wane | 0:88dc49222b35 | 556 | entryState = 1; |
wane | 0:88dc49222b35 | 557 | done = true; |
wane | 0:88dc49222b35 | 558 | break; |
wane | 0:88dc49222b35 | 559 | } |
wane | 0:88dc49222b35 | 560 | return done; |
wane | 0:88dc49222b35 | 561 | } |
wane | 0:88dc49222b35 | 562 | |
wane | 0:88dc49222b35 | 563 | // Non-blockingly enter data to unlock passcode |
wane | 0:88dc49222b35 | 564 | bool UnlockPasscode() |
wane | 0:88dc49222b35 | 565 | { |
wane | 0:88dc49222b35 | 566 | int i = 0; |
wane | 0:88dc49222b35 | 567 | bool done = false; |
wane | 0:88dc49222b35 | 568 | |
wane | 0:88dc49222b35 | 569 | switch (entryState) |
wane | 0:88dc49222b35 | 570 | { |
wane | 0:88dc49222b35 | 571 | case 0: |
wane | 0:88dc49222b35 | 572 | break; |
wane | 0:88dc49222b35 | 573 | case 1: |
wane | 0:88dc49222b35 | 574 | pc.printf("\n\rTo unlock, enter a 4-digit passcode: "); |
wane | 0:88dc49222b35 | 575 | entryReady = false; |
wane | 0:88dc49222b35 | 576 | entryState = 2; |
wane | 0:88dc49222b35 | 577 | break; |
wane | 0:88dc49222b35 | 578 | case 2: |
wane | 0:88dc49222b35 | 579 | peepEntry(); |
wane | 0:88dc49222b35 | 580 | if (!entryReady) |
wane | 0:88dc49222b35 | 581 | break; |
wane | 0:88dc49222b35 | 582 | else |
wane | 0:88dc49222b35 | 583 | entryState = 3; |
wane | 0:88dc49222b35 | 584 | case 3: |
wane | 0:88dc49222b35 | 585 | sscanf(inBuf, "%d", &i); |
wane | 0:88dc49222b35 | 586 | if (i < 0000 || i > 9999) { |
wane | 0:88dc49222b35 | 587 | pc.printf("\n\rEnter a passcode between 0000 and 9999: "); |
wane | 0:88dc49222b35 | 588 | entryReady = false; |
wane | 0:88dc49222b35 | 589 | entryState = 3; |
wane | 0:88dc49222b35 | 590 | } else { |
wane | 0:88dc49222b35 | 591 | if (passcode == i) { |
wane | 0:88dc49222b35 | 592 | pc.printf("\n\r====> Unlock successful. :-) \n\r"); |
wane | 0:88dc49222b35 | 593 | sLockActive = false; |
wane | 0:88dc49222b35 | 594 | statusAlarm &= 0xFFFFFFFD; |
wane | 0:88dc49222b35 | 595 | lockLed = 0; |
wane | 0:88dc49222b35 | 596 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 597 | } else { |
wane | 0:88dc49222b35 | 598 | pc.printf("\n\r====> Incorrect passcode!\n\r"); |
wane | 0:88dc49222b35 | 599 | } |
wane | 0:88dc49222b35 | 600 | done = true; |
wane | 0:88dc49222b35 | 601 | entryState = 1; |
wane | 0:88dc49222b35 | 602 | |
wane | 0:88dc49222b35 | 603 | } |
wane | 0:88dc49222b35 | 604 | break; |
wane | 0:88dc49222b35 | 605 | |
wane | 0:88dc49222b35 | 606 | } |
wane | 0:88dc49222b35 | 607 | return done; |
wane | 0:88dc49222b35 | 608 | } |
wane | 0:88dc49222b35 | 609 | |
wane | 0:88dc49222b35 | 610 | // Check if USB is connected |
wane | 0:88dc49222b35 | 611 | // To read lock status: bit0=NUM_LOCK bit1=CAP_LOCK bit2=SCROLL_LOCK |
wane | 1:930838234048 | 612 | // To check, either check if keyCode returns OK or status led is signaled. |
wane | 1:930838234048 | 613 | // To-Do: Correct the logic as status should return alternate results as |
wane | 1:930838234048 | 614 | // CAP LOCK KEY is being hit continuously. |
wane | 0:88dc49222b35 | 615 | void USBConnCheck() |
wane | 0:88dc49222b35 | 616 | { |
wane | 0:88dc49222b35 | 617 | char status = 0; |
wane | 0:88dc49222b35 | 618 | char result; |
wane | 0:88dc49222b35 | 619 | |
wane | 0:88dc49222b35 | 620 | //if (!(statusAlarm & 0x80000000)) |
wane | 0:88dc49222b35 | 621 | //{ |
wane | 0:88dc49222b35 | 622 | // dev.keyCode(KEY_NUM_LOCK); |
wane | 0:88dc49222b35 | 623 | |
wane | 1:930838234048 | 624 | dev.keyCode(KEY_CAPS_LOCK); |
wane | 1:930838234048 | 625 | //if (dev.keyCode(KEY_CAPS_LOCK)) |
wane | 1:930838234048 | 626 | // printf("\rSend KEY_CAPS_LOCK OK\n\r"); |
wane | 0:88dc49222b35 | 627 | |
wane | 0:88dc49222b35 | 628 | status = dev.lockStatus(); |
wane | 0:88dc49222b35 | 629 | if (!(statusAlarm & 0x80000000) && (status & 0x2)) |
wane | 0:88dc49222b35 | 630 | { |
wane | 0:88dc49222b35 | 631 | statusAlarm |= 0x80000000; |
wane | 0:88dc49222b35 | 632 | result = true; |
wane | 0:88dc49222b35 | 633 | } |
wane | 0:88dc49222b35 | 634 | else if ((statusAlarm & 0x80000000) && !(status & 0x2)) |
wane | 0:88dc49222b35 | 635 | { |
wane | 0:88dc49222b35 | 636 | statusAlarm &= 0x7FFFFFFF; |
wane | 0:88dc49222b35 | 637 | result = false; |
wane | 0:88dc49222b35 | 638 | } |
wane | 0:88dc49222b35 | 639 | //printf("2: lockStatus = 0x%x statusAlarm = 0x%x\n\r", status, statusAlarm); |
wane | 0:88dc49222b35 | 640 | //return result; |
wane | 0:88dc49222b35 | 641 | |
wane | 0:88dc49222b35 | 642 | } |
wane | 0:88dc49222b35 | 643 | |
wane | 0:88dc49222b35 | 644 | // Turn on and off the alarm comparing the current temperature with and the set temperature |
wane | 0:88dc49222b35 | 645 | // Input: None |
wane | 0:88dc49222b35 | 646 | void TempMonitor() |
wane | 0:88dc49222b35 | 647 | { |
wane | 0:88dc49222b35 | 648 | // Record current state of relay switch |
wane | 0:88dc49222b35 | 649 | int tempAlarm = statusAlarm & 0x1; |
wane | 0:88dc49222b35 | 650 | if (((temp < (setLowerTemp - tol)) || (temp > (setUpperTemp + tol))) && sHealthFeatureActive) |
wane | 0:88dc49222b35 | 651 | { |
wane | 0:88dc49222b35 | 652 | statusAlarm |= 0x1; |
wane | 0:88dc49222b35 | 653 | alarmType = 0; |
wane | 0:88dc49222b35 | 654 | } |
wane | 0:88dc49222b35 | 655 | else if (((temp >= setLowerTemp) && (temp <= setUpperTemp)) || !sHealthFeatureActive) |
wane | 0:88dc49222b35 | 656 | { |
wane | 0:88dc49222b35 | 657 | statusAlarm &= 0xFFFFFFFE; |
wane | 0:88dc49222b35 | 658 | } |
wane | 0:88dc49222b35 | 659 | // When alarm is turned on or off |
wane | 0:88dc49222b35 | 660 | if (tempAlarm != (statusAlarm & 0x1)) |
wane | 0:88dc49222b35 | 661 | { |
wane | 0:88dc49222b35 | 662 | seconds = time(NULL); |
wane | 0:88dc49222b35 | 663 | char buffer[32]; |
wane | 0:88dc49222b35 | 664 | strftime(buffer, 32, "%T", localtime(&seconds)); |
wane | 0:88dc49222b35 | 665 | |
wane | 0:88dc49222b35 | 666 | if (statusAlarm & 0x1) |
wane | 0:88dc49222b35 | 667 | { |
wane | 0:88dc49222b35 | 668 | if (timer2.read()) |
wane | 0:88dc49222b35 | 669 | { |
wane | 0:88dc49222b35 | 670 | timer2.stop(); |
wane | 0:88dc49222b35 | 671 | pc.printf("Temperature Alarm off for %.2f sec.\n\r", timer2.read()); |
wane | 0:88dc49222b35 | 672 | } |
wane | 0:88dc49222b35 | 673 | timer2.reset(); |
wane | 0:88dc49222b35 | 674 | pc.printf("Temperature Alarm on.... %s\n\r", buffer); |
wane | 0:88dc49222b35 | 675 | timer2.start(); |
wane | 0:88dc49222b35 | 676 | } |
wane | 0:88dc49222b35 | 677 | else |
wane | 0:88dc49222b35 | 678 | { |
wane | 0:88dc49222b35 | 679 | timer2.stop(); |
wane | 0:88dc49222b35 | 680 | timeElapsed = timer2.read(); |
wane | 0:88dc49222b35 | 681 | pc.printf("Temperature Alarm off... %s (Duration: %.2f sec)\n\r", buffer, timeElapsed); |
wane | 0:88dc49222b35 | 682 | timer2.reset(); |
wane | 0:88dc49222b35 | 683 | timer2.start(); |
wane | 0:88dc49222b35 | 684 | } |
wane | 0:88dc49222b35 | 685 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 686 | } |
wane | 0:88dc49222b35 | 687 | } |
wane | 0:88dc49222b35 | 688 | |
wane | 0:88dc49222b35 | 689 | |
wane | 0:88dc49222b35 | 690 | |
wane | 0:88dc49222b35 | 691 | // Read temperature sensor |
wane | 0:88dc49222b35 | 692 | // Input: None |
wane | 0:88dc49222b35 | 693 | void ReadTemp() |
wane | 0:88dc49222b35 | 694 | { |
wane | 0:88dc49222b35 | 695 | //temp = Ctmp.read(); |
wane | 0:88dc49222b35 | 696 | temp = Ctmp.read()*1.8+32; |
wane | 0:88dc49222b35 | 697 | updateCurTempDisplay = true; |
wane | 0:88dc49222b35 | 698 | } |
wane | 0:88dc49222b35 | 699 | |
wane | 0:88dc49222b35 | 700 | // Monitor accelerometer to detect motion and turn on and off the alarm after comparing the motion data with |
wane | 0:88dc49222b35 | 701 | // preconfigurated motion factor. |
wane | 0:88dc49222b35 | 702 | void MotionMonitor() |
wane | 0:88dc49222b35 | 703 | { |
wane | 0:88dc49222b35 | 704 | //Xaxis_p = MMA.x() || -MMA.x(); |
wane | 0:88dc49222b35 | 705 | |
wane | 0:88dc49222b35 | 706 | float xpos, ypos, zpos; |
wane | 0:88dc49222b35 | 707 | float senNum = senParm[senLevel].factor; |
wane | 0:88dc49222b35 | 708 | xpos = MMA.x(); |
wane | 0:88dc49222b35 | 709 | ypos = MMA.y(); |
wane | 0:88dc49222b35 | 710 | zpos = MMA.z(); |
wane | 0:88dc49222b35 | 711 | if ((xpos > senNum || xpos < -(senNum) || ypos > senNum || ypos < -(senNum)) && sSecurityFeatureActive) |
wane | 0:88dc49222b35 | 712 | { |
wane | 0:88dc49222b35 | 713 | statusAlarm |= 0x2; |
wane | 0:88dc49222b35 | 714 | pc.printf("Security Alarm ON 0x%x(senNum: %f Xpos: %6.3f Ypos: %6.3f Zpos: %6.3f)\n\r", statusAlarm, senNum, xpos, ypos, zpos); |
wane | 0:88dc49222b35 | 715 | //updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 716 | } |
wane | 0:88dc49222b35 | 717 | else |
wane | 0:88dc49222b35 | 718 | { |
wane | 0:88dc49222b35 | 719 | if ((statusAlarm & 0x2) && (mode == 0 || !sLockActive)) |
wane | 0:88dc49222b35 | 720 | { |
wane | 0:88dc49222b35 | 721 | statusAlarm &= 0xFFFFFFFD; |
wane | 0:88dc49222b35 | 722 | pc.printf("Security Alarm OFF 0x%x(Xpos: %6.3f Ypos: %6.3f Zpos: %6.3f)\n\r", statusAlarm, xpos, ypos, zpos); |
wane | 0:88dc49222b35 | 723 | } |
wane | 0:88dc49222b35 | 724 | //else |
wane | 0:88dc49222b35 | 725 | // pc.printf("Security Alarm %s (Xpos: %6.3f Ypos: %6.3f Zpos: %6.3f)\n\r", (statusAlarm & 0x2)? "sON": "sOFF", xpos, ypos, zpos); |
wane | 0:88dc49222b35 | 726 | //updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 727 | } |
wane | 0:88dc49222b35 | 728 | } |
wane | 0:88dc49222b35 | 729 | |
wane | 0:88dc49222b35 | 730 | // Display date, time, heater state, relay state, current and set temperature at LCD |
wane | 0:88dc49222b35 | 731 | // Input: None |
wane | 0:88dc49222b35 | 732 | void DisplayLCD() |
wane | 0:88dc49222b35 | 733 | { |
wane | 0:88dc49222b35 | 734 | seconds = time(NULL); |
wane | 0:88dc49222b35 | 735 | |
wane | 0:88dc49222b35 | 736 | char buffer[32]; |
wane | 0:88dc49222b35 | 737 | strftime(buffer, 32, "%F %T", localtime(&seconds)); |
wane | 0:88dc49222b35 | 738 | |
wane | 0:88dc49222b35 | 739 | lcd.locate(0,3); |
wane | 0:88dc49222b35 | 740 | lcd.printf("%s\n",buffer); |
wane | 0:88dc49222b35 | 741 | if (updateCurTempDisplay || updateJoyDisplay) |
wane | 0:88dc49222b35 | 742 | { |
wane | 0:88dc49222b35 | 743 | lcd.printf("Now: %.1f%c L:%3.0f%c U: %3.1f%c\n", temp, deg, setLowerTemp, deg, setUpperTemp, deg); |
wane | 0:88dc49222b35 | 744 | updateCurTempDisplay = false; |
wane | 0:88dc49222b35 | 745 | } |
wane | 0:88dc49222b35 | 746 | |
wane | 0:88dc49222b35 | 747 | |
wane | 0:88dc49222b35 | 748 | if (updateJoyDisplay) |
wane | 0:88dc49222b35 | 749 | { |
wane | 0:88dc49222b35 | 750 | lcd.printf("Mode: %c %1s%2s Status: %s%s\n", modeSym[mode], sHealthFeatureActive? "H": " ", senParm[senLevel].sym, sLockActive? "L":" ", sAlarmOn? "A": " "); |
wane | 0:88dc49222b35 | 751 | updateJoyDisplay = false; |
wane | 0:88dc49222b35 | 752 | } |
wane | 0:88dc49222b35 | 753 | |
wane | 0:88dc49222b35 | 754 | } |
wane | 0:88dc49222b35 | 755 | |
wane | 0:88dc49222b35 | 756 | // Check if alarm is to be triggered by either temp or security events |
wane | 0:88dc49222b35 | 757 | // Do buzz for temperature and security alarm events accordingly |
wane | 0:88dc49222b35 | 758 | void AlarmCheck() |
wane | 0:88dc49222b35 | 759 | { |
wane | 0:88dc49222b35 | 760 | bool prevState = sAlarmOn; |
wane | 0:88dc49222b35 | 761 | if (statusAlarm & 0x1 || statusAlarm & 0x2) |
wane | 0:88dc49222b35 | 762 | sAlarmOn = ON; |
wane | 0:88dc49222b35 | 763 | else |
wane | 0:88dc49222b35 | 764 | sAlarmOn = OFF; |
wane | 0:88dc49222b35 | 765 | |
wane | 0:88dc49222b35 | 766 | if (statusAlarm & 0x80000000) |
wane | 0:88dc49222b35 | 767 | connectionLed = 1; |
wane | 0:88dc49222b35 | 768 | else |
wane | 0:88dc49222b35 | 769 | connectionLed = 0; |
wane | 0:88dc49222b35 | 770 | |
wane | 0:88dc49222b35 | 771 | if (prevState != sAlarmOn) |
wane | 0:88dc49222b35 | 772 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 773 | |
wane | 0:88dc49222b35 | 774 | //leds = statusAlarm; |
wane | 0:88dc49222b35 | 775 | if ((statusAlarm & 0x2) && (statusAlarm & 0x1)) |
wane | 0:88dc49222b35 | 776 | { |
wane | 0:88dc49222b35 | 777 | buzzOn(1, BUZZ_SPERIOD); |
wane | 0:88dc49222b35 | 778 | ledOn(1, BUZZ_SPERIOD); |
wane | 0:88dc49222b35 | 779 | ledOn(0, BUZZ_TPERIOD); |
wane | 0:88dc49222b35 | 780 | } |
wane | 0:88dc49222b35 | 781 | // Security alarm |
wane | 0:88dc49222b35 | 782 | else if (statusAlarm & 0x2) |
wane | 0:88dc49222b35 | 783 | { |
wane | 0:88dc49222b35 | 784 | buzzOn(1, BUZZ_SPERIOD); |
wane | 0:88dc49222b35 | 785 | ledOn(1, BUZZ_SPERIOD); |
wane | 0:88dc49222b35 | 786 | } |
wane | 0:88dc49222b35 | 787 | // Temperature alarm |
wane | 0:88dc49222b35 | 788 | else if (statusAlarm & 0x1) |
wane | 0:88dc49222b35 | 789 | { |
wane | 0:88dc49222b35 | 790 | buzzOn(0, BUZZ_TPERIOD); |
wane | 0:88dc49222b35 | 791 | ledOn(0, BUZZ_TPERIOD); |
wane | 0:88dc49222b35 | 792 | } |
wane | 0:88dc49222b35 | 793 | } |
wane | 0:88dc49222b35 | 794 | |
wane | 0:88dc49222b35 | 795 | |
wane | 0:88dc49222b35 | 796 | // Initialize settings |
wane | 0:88dc49222b35 | 797 | void Init(void) |
wane | 0:88dc49222b35 | 798 | { |
wane | 0:88dc49222b35 | 799 | SetTime(YEAR, MONTH, DATE, HOUR, MIN, 0); |
wane | 0:88dc49222b35 | 800 | |
wane | 0:88dc49222b35 | 801 | IRQFire.rise(&ISRFirePressed); |
wane | 0:88dc49222b35 | 802 | IRQJoyUp.rise(&ISRJoyUp); |
wane | 0:88dc49222b35 | 803 | IRQJoyDown.rise(&ISRJoyDown); |
wane | 0:88dc49222b35 | 804 | IRQJoyLeft.rise(&ISRJoyLeft); |
wane | 0:88dc49222b35 | 805 | IRQJoyRight.rise(&ISRJoyRight); |
wane | 0:88dc49222b35 | 806 | timer1.attach(&DisplayLCD, 1); |
wane | 0:88dc49222b35 | 807 | timer3.attach(&debounce, 1); |
wane | 1:930838234048 | 808 | //timer4.attach(&USBConnCheck, 2); // Cannot use with ticker |
wane | 1:930838234048 | 809 | //timer4.attach(&AlarmCheck, 1); // Cannot use or it won't respond external events |
wane | 0:88dc49222b35 | 810 | sHealthFeatureActive = OFF; |
wane | 0:88dc49222b35 | 811 | sSecurityFeatureActive = OFF; |
wane | 0:88dc49222b35 | 812 | sAlarmOn = OFF; |
wane | 0:88dc49222b35 | 813 | statusAlarm = 0; |
wane | 0:88dc49222b35 | 814 | sState = 0; |
wane | 0:88dc49222b35 | 815 | setLowerTemp = DEF_LOWER_TEMP; |
wane | 0:88dc49222b35 | 816 | setUpperTemp = DEF_UPPER_TEMP; |
wane | 0:88dc49222b35 | 817 | tempOverride = false; |
wane | 0:88dc49222b35 | 818 | senLevel = 0; |
wane | 0:88dc49222b35 | 819 | buzzPattern = 0; |
wane | 0:88dc49222b35 | 820 | buzzPeriod = 0.2; |
wane | 0:88dc49222b35 | 821 | mode = 0; |
wane | 0:88dc49222b35 | 822 | timeElapsed = 0; |
wane | 0:88dc49222b35 | 823 | entryState = 1; |
wane | 0:88dc49222b35 | 824 | lcd.cls(); |
wane | 0:88dc49222b35 | 825 | lcd.locate(0,3); |
wane | 0:88dc49222b35 | 826 | updateJoyDisplay = true; |
wane | 0:88dc49222b35 | 827 | |
wane | 0:88dc49222b35 | 828 | calibratePot(); |
wane | 0:88dc49222b35 | 829 | pc.printf("\n\rHealth & Security Monitoring starts...\n\r"); |
wane | 0:88dc49222b35 | 830 | |
wane | 0:88dc49222b35 | 831 | } |
wane | 0:88dc49222b35 | 832 | |
wane | 0:88dc49222b35 | 833 | // Main loop in executing major temperature, motion monitoring tasks and alarm check task |
wane | 0:88dc49222b35 | 834 | void FSM(void) |
wane | 0:88dc49222b35 | 835 | { |
wane | 0:88dc49222b35 | 836 | while(1) |
wane | 0:88dc49222b35 | 837 | { |
wane | 1:930838234048 | 838 | USBConnCheck(); |
wane | 0:88dc49222b35 | 839 | |
wane | 0:88dc49222b35 | 840 | // Override temperature read for testing. Use pot to control temperature |
wane | 0:88dc49222b35 | 841 | if (!tempOverride) |
wane | 0:88dc49222b35 | 842 | ReadTemp(); |
wane | 0:88dc49222b35 | 843 | |
wane | 0:88dc49222b35 | 844 | setLowerTemp = lowerTempBase + (pot1.read()-potBase1) * 12; |
wane | 0:88dc49222b35 | 845 | setUpperTemp = upperTempBase + (pot2.read()-potBase2) * 12; |
wane | 0:88dc49222b35 | 846 | updateCurTempDisplay = true; |
wane | 0:88dc49222b35 | 847 | |
wane | 0:88dc49222b35 | 848 | switch (gState) |
wane | 0:88dc49222b35 | 849 | { |
wane | 0:88dc49222b35 | 850 | case 0: |
wane | 0:88dc49222b35 | 851 | break; |
wane | 0:88dc49222b35 | 852 | case 1: |
wane | 0:88dc49222b35 | 853 | if (SetPasscode()) |
wane | 0:88dc49222b35 | 854 | gState = 0; |
wane | 0:88dc49222b35 | 855 | break; |
wane | 0:88dc49222b35 | 856 | case 2: |
wane | 0:88dc49222b35 | 857 | if (UnlockPasscode()) |
wane | 0:88dc49222b35 | 858 | gState = 0; |
wane | 0:88dc49222b35 | 859 | break; |
wane | 0:88dc49222b35 | 860 | case 3: |
wane | 0:88dc49222b35 | 861 | if (EnterTemp()) |
wane | 0:88dc49222b35 | 862 | gState = 0; |
wane | 0:88dc49222b35 | 863 | break; |
wane | 0:88dc49222b35 | 864 | } |
wane | 0:88dc49222b35 | 865 | |
wane | 0:88dc49222b35 | 866 | MotionMonitor(); |
wane | 0:88dc49222b35 | 867 | TempMonitor(); |
wane | 1:930838234048 | 868 | AlarmCheck(); |
wane | 0:88dc49222b35 | 869 | |
wane | 0:88dc49222b35 | 870 | /* Live check |
wane | 0:88dc49222b35 | 871 | lockLed = 1; |
wane | 0:88dc49222b35 | 872 | wait (0.1); |
wane | 0:88dc49222b35 | 873 | lockLed = 0; |
wane | 0:88dc49222b35 | 874 | wait(0.1); |
wane | 0:88dc49222b35 | 875 | */ |
wane | 0:88dc49222b35 | 876 | } |
wane | 0:88dc49222b35 | 877 | |
wane | 0:88dc49222b35 | 878 | } |
wane | 0:88dc49222b35 | 879 | |
wane | 0:88dc49222b35 | 880 | int main() |
wane | 0:88dc49222b35 | 881 | { |
wane | 0:88dc49222b35 | 882 | //buzzTest(); |
wane | 0:88dc49222b35 | 883 | Init(); |
wane | 0:88dc49222b35 | 884 | FSM(); |
wane | 0:88dc49222b35 | 885 | } |