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