Project 1 Self-powered Health & Security Monitoring System USB device

Dependencies:   C12832_lcd LM75B MMA7660 USBDevice mbed

main.cpp

Committer:
wane
Date:
2014-03-28
Revision:
2:07c9334e3088
Parent:
1:930838234048

File content as of revision 2:07c9334e3088:

// Project: Self-powered USB Health and Security Monitoring Device 
// Erick Wan
// March 2014
// 
// Note: 
// The codes are written in a rush that they are missing descriptions, not as
// organized or modularized, resource planning, etc. 
// More design, write-up and organizing work are required. 
// If you are learning to write codes in style, this is not a good example 
// to follow. 
//
// Summary: 
// The self-powered system monitors temperature and detect motion when
// attached to the USB host. It is first configured as HID device for
// the sake of driver-free support. Audio alarm (when 
// connected an external buzzer at P21) and led will get turned on if 
// the temperature goes out of monitoring range or motion exceeds
// detecting sensitivity threshold. 
// 
// Two modes: Test mode and Operation mode. In operational mode, 
// user can lock the device enter a passcode through serial debug 
// terminal. Motion alarm will continue to be on until the passcode
// is entered. 
//
// Set-up:
// - An external buzzer is used and connected at P21 and ground. 
// - To be connected to debug serial terminal
// - Connect to a host as device
// 
// Controls: 
//     Joystick DOWN - Switch between Test and Operational mode
//     Joystick LEFT - Turn Temperature monitoring on and off
//     Joystick UP   - Turn Motion monitoring on. Increase sensitivity
//                     level as further push. S1-Low S2-Medium S3-High
//     Joystick RIGHT- Lock and unlock USB device. Enter passcode
//                     at first locking device. 
//     Pot1 - Lower bound temerature (for debugging)
//     Pot2 - Higher bound temperature (for debugging)
//     Fire - Input a simulated air temperature (for debugging)
// 
// Output: 
//     LED1 - USB Connection 
//     LED2 - Lock Status (On-Lock Off-Unlocked)
//     LED3 - Alarm Status - Temperature
//     LED4 - Alarm Status - Motion
//     Buzzer - Temperature alarm beeps in lower frequency
//          Motion alarm beeps in relatively higher frequency
// LCD Key:
//     Now - Current temperature
//     L   - Lower bound temperature
//     U   - Upper bound temperature
//     Mode: T-Test mode  O-Operational mode
//           H-Temperature Monitoring
//           S1 - Security (Low sensitivity)
//           S2 - Security (Mid sensitivity)
//           S3 - Security (High sensitivity)
//     Status: 
//           L - Device in locked (Unlocked if disappeared)
//           A - Alarm on (No alarm if disappeared)
/*
History:
    Version 1.0
    241: Added temp alarm
    251: Added motion alarm, sensitivity level
         Validated alarm status handling
    252: Added lock, passcode control, mode (T-Testing; O-Operational)                 
    261: Added non-blocking serial entry

TO-FIX: 
    1. To set up a standalone device. Currently, device is not in 
       operation until connected to a host
    2. To complete USB connection detection. Currently, system stalls 
       or fails to respond when detached from a USB host. 
   
TO-DO: 
    1. Add menu display with LCD
    2. Add data entry with LCD (without using serial)
    3. Add file system that there can record events and save into files
    4. Add capability to report to user remotely 
    5. Add to record and report sound once security is breached. 
    6. Add to record GPS data and report back
   
*/

#include "mbed.h"
#include "C12832_lcd.h"
#include "LM75B.h"
#include "MMA7660.h"
#include "USBKeyboard.h"

// Configure device as USBKeyboard 
USBKeyboard dev;

#define UP 0x1
#define DOWN 0x2
#define LEFT 0x4
#define RIGHT 0x8
#define ON true
#define OFF false

// System configuration parameters
#define YEAR 2014
#define MONTH 3
#define DATE 26
#define HOUR 17
#define MIN 35
#define DEF_LOWER_TEMP 72               // Lower bound of monitoring temperature
#define DEF_UPPER_TEMP 89               // Upper bound of monitoring temperature
#define LOW_SEN 0.7                     // Low sensitivity
#define MID_SEN 0.5                     // Medium sensitivity
#define HIGH_SEN 0.3                    // High sensitivity
#define BUZZ_POWER 1                    // Buzz power level
#define BUZZ_SPERIOD 0.2                // Security alarm buzz period
#define BUZZ_TPERIOD 1                  // Temperature alarm buzz period

// System I/O
C12832_LCD lcd;
PwmOut alarm(p21);
BusIn joy(p15,p12,p13,p16);
InterruptIn IRQJoyUp(p15);
InterruptIn IRQJoyDown(p12);
InterruptIn IRQJoyLeft(p13);
InterruptIn IRQJoyRight(p16);
InterruptIn IRQFire(p14);

Serial pc(USBTX, USBRX); // tx, rx
LM75B Ctmp(p28,p27);
AnalogIn pot1(p19);
AnalogIn pot2(p20);
MMA7660 MMA(p28, p27);
DigitalOut connectionLed(LED1);
DigitalOut lockLed(LED2);
//BusOut leds(LED3,LED4);
//DigitalOut ledTAlarm(LED3);
//DigitalOut ledSAlarm(LED4);
PwmOut ledTAlarm(LED3);
PwmOut ledSAlarm(LED4);


// Global backend variables
float setUpperTemp;         // Upper bound of temperature monitoring range
float setLowerTemp;         // Lower bound of temperature monitoring range
bool sAlarmOn;              // State of alarm
int statusAlarm;            // Status indicating whether health or/and security alarm is triggered
bool sHealthFeatureActive;          // State indicating temperature monitoring is activated
bool sSecurityFeatureActive;        // State indicating motion monitoring is activated
bool sLockActive;           // State indicating lock is active
char sState;                // security setting state
char gState;                // Global state
int alarmType;              // 0 - Health; 1 - Security
char senLevel;              // Sensitivity level of motion alarm
int mode;                   // Operation mode: 
                            // 0 = Test mode (for testing features)
                            // 1 = Lock mode (lock and unlock device)
int passcode;               // 4-digit passcode for lock and unlock               
bool sPCOK;                 // state indicating a valid passcode is existing
float lowerTempBase;        // Simulated lower bound temperature
float upperTempBase;        // Simulated upper bound temperature
float temp;                 // Current temperature


// Global frontend variables
int buzzPattern; 
float buzzPeriod;
Ticker timer1;              // For LCD display 
Ticker timer3;              // For debouncer
Ticker timer4;              // TBU
Timer timer2;               // For tracking temperature alarm
bool activated;             // for debounce fire
time_t yet;                 // For debounce time tracking
time_t now;                 // For debounce time tracking
bool updateCurTempDisplay;
bool updateJoyDisplay;
bool tempOverride;

bool entryReady;            // For tracking if user input is comlete
unsigned char entryState;   // State tracking input entry
char inBuf[128];            // Input buffer 
char pos;                   // Gobal buffer index
int tol;                    // Tolerance

float timeElapsed;
time_t seconds;
float potBase1; 
float potBase2; 

#ifdef C
#define deg 'C'
#else 
#define deg 'F'
#endif 

typedef struct {
    bool active;
    float factor;
    unsigned char sym[3];
} SENTYPE;

const SENTYPE senParm[4] = { 
    { false, LOW_SEN, "  " },
    { true,  LOW_SEN, "S1" },                 // Low sensitivity
    { true,  MID_SEN, "S2" },                 // Mid sensitivity
    { true,  HIGH_SEN, "S3" },                 // High sensitivity
};

const char modeSym[2] = { 'T', 'O' }; 

/*
enum FUNCTION_KEY {
    KEY_SCROLL_LOCK = 141,    // Scroll lock 
    KEY_CAPS_LOCK,      // caps lock 
    KEY_NUM_LOCK,       // num lock 
};
*/

// Function prototype
void ISRFirePressed();
void ISRJoyUp();
void ISRJoyDown();
void ISRJoyLeft();
void ISRJoyRight();
void debounce();
void buzzOn(int pattern, float period);
void buzzOff();
void buzzTest();
void peepEntry();
void calibratePot();
bool EnterTemp();
bool SetPasscode();
bool UnlockPasscode();
void USBConnCheck();
void SetTime(int year, int month, int date, int hour, int min, int sec);
void TempMonitor();
void ReadTemp();
void MotionMonitor();
void DisplayLCD();
void AlarmCheck();
void FSM(void);


// ISR for fire button
void ISRFirePressed()
{
    now = time(NULL);
    if (!activated && now > yet) {
        
        tempOverride = !tempOverride;
        if (tempOverride)
            gState = 3;             // EnterTemp
        yet = now + 1;
        activated = true;
    }
        
}


// ISR for joystick up direction
// Turn on motion detection feature. Continue to push to increase motion
// detection sensitivity. 
void ISRJoyUp()
{
    now = time(NULL);
    if (!activated && now > yet) {
        //if (mode == 1 && sPCOK == false)
        //    EnterPasscode();
        senLevel = (senLevel + 1) % 4;
        sSecurityFeatureActive = senParm[senLevel].active;
        updateJoyDisplay = true;
        yet = now + 1;
        activated = true;
    }
}

// ISR for joystick down direction
// Switch mode between Test and Operational
void ISRJoyDown()
{
    now = time(NULL);
    if (!activated && now > yet) {
        mode = (mode + 1) % 2;
        updateJoyDisplay = true;
        yet = now + 1;
        activated = true;
    }
}

// ISR for joystick left direction
// Turn temperature monitoring feature on and off
void ISRJoyLeft()
{
    now = time(NULL);
    if (!activated && now > yet) {
        sHealthFeatureActive = !sHealthFeatureActive;
        updateJoyDisplay = true;
        yet = now + 1;
        activated = true;
    }
}

// ISR for joystick right direction
// Lock and unlock device
void ISRJoyRight()
{
    now = time(NULL);
    if (!activated && now > yet) {
        if (mode == 1)
        {
            if (!sLockActive)
                gState = 1;     // SetPasscode
            else
                gState = 2;     // UnlockPasscode
        }
        yet = now + 1;
        activated = true;
    }
}

// Debouncer function  
void debounce()
{
    if (activated)
        activated = false;
}
 
// Turn on buzzer in different patterns
void buzzOn(int pattern, float period) 
{
    switch (pattern) {
        case 0:     // Temperature 
            alarm = BUZZ_POWER;
            wait(0.2);
            alarm = 0;
            wait(period);
            /*
            for(float p=0; p<1.0; p += 0.1) {
                alarm = p;
                wait(period);
            }
            */
            break;
        case 1:     // Security
            alarm = BUZZ_POWER;
            wait(0.2);
            alarm = 0;
            wait(period);
            break;

        }
}

// Turn on LEDs and operate in different frequency
void ledOn(int type, float period) 
{
    switch (type) {
        case 0:
            ledTAlarm = 1;
            wait(0.1);
            ledTAlarm = 0;
            wait(0.05);
            break;
        case 1:
            /*
            for(int p=0; p<10; p += 1) {
                ledSAlarm = 1;
                wait(0.02);
                ledSAlarm = 0;
                wait(0.02);
            }
            */
            ledSAlarm = 1;
            wait(0.1);
            ledSAlarm = 0;
            wait(0.02);
            break;

        }
}

// Turn off alarm 
void buzzOff()
{
    alarm = 0;
}

// For testing buzzer. 
void buzzTest()
{
    int count = 0;
    sAlarmOn = OFF; 

    timer1.attach(&debounce, 1);
    //IRQFire.rise(&ISRFirePressed);
    //IRQFire.fall(&ISRFireRelease);
    //IRQJoyUp.rise(&ISRJoyUp);
    //IRQJoyDown.rise(&ISRJoyDown);    
    
    alarm.period(0.020);          // servo requires a 20ms period
    
    printf("Test starts...\n\r");
    
    while (1)
    {
        if (sAlarmOn) {
            buzzOn(buzzPattern, buzzPeriod);
                printf("%s: pattern: %d period: %.1f count: %d\n\r", sAlarmOn? "ON": "OFF", buzzPattern, buzzPeriod, count);
        } else {
            buzzOff();
                buzzPattern = (buzzPattern + 1) % 2;
                count = 0;
        }
        wait(0.02);
    }    
}   
        

// Set date and time at LCD display
// Input: Year, month, date, hour, minute, second
void SetTime(int year, int month, int date, int hour, int min, int sec)
{
    struct tm Clock;
    Clock.tm_year = year - 1900;
    Clock.tm_mon  = month - 1;
    Clock.tm_mday = date;
    Clock.tm_hour = hour;
    Clock.tm_min  = min;
    Clock.tm_sec  = sec;
    time_t epoch = mktime(&Clock);
    if (epoch == (time_t) -1) {
        error("Error: Invalid clock setting! Please try again.\n");
    }
    set_time(epoch);
}

// Calibrate analog pot to allow tuning each pot for controlling upper and lower bound control temperature
void calibratePot()
{
    potBase1 = pot1.read();
    potBase2 = pot2.read();
    //tempBase = temp;
    lowerTempBase = setLowerTemp;
    upperTempBase = setUpperTemp;

    
    updateJoyDisplay = true;

    wait(0.5);

}         


// Peep uart buffer if serial data is available for read
// Return the entry when hit ENTER button
void peepEntry()
{
    int i;
    char c;
    i = pc.readable();

    if (i > 0) {
        //pc.printf("%d: ", i);
        while (i > 0) {
            c = pc.getc();

            if (c == '\r') {
                pc.printf("\n\r");
                inBuf[pos] = '\0';
                //pc.printf("Return: %s\n\r", inBuf);
                pos = 0;
                entryReady = true;

            } else {
                //pc.printf("%c\n\r", c);
                pc.putc(c);
                inBuf[pos] = c;
                pos++;
            }
            i--;
        }

    }
}

// Non-blockingly set a passcode
// Input: None
bool SetPasscode()
{
    int i;
    bool done = false; 
    
    switch (entryState)
    {
        case 0:
            break;
        case 1: 
            if (statusAlarm & 0x80000000)
            {
                if (!sPCOK)
                    entryState = 2;
                else
                    entryState = 5;
            }
            else
            {
                pc.printf("No USB connection detected. Check USB device being connected.\n\r");
            }
            break;
                    
        case 2:
            pc.printf("\n\rEnter a 4-digit passcode: ");
            entryReady = false;
            entryState = 3;
            break;
        case 3:
            peepEntry();
            if (!entryReady)
                break;
            else
                entryState = 4;
        case 4:
            sscanf(inBuf, "%d", &i);
            if (i < 0000 || i > 9999) {
                pc.printf("\n\rEnter a passcode between 0000 and 9999: ");
                entryReady = false;
                entryState = 3;
                break;
            } else {
                passcode = i;
                pc.printf("\n\rPasscode is set (%d).\n\r", passcode);
                sPCOK = true;
                entryState = 5;
            }
        case 5:
            sLockActive = true;
            lockLed = 1;
            updateJoyDisplay = true;
            pc.printf("USB is now locked. Enter passcode to unlock.\n\r");
            entryState = 1;
            done = true;
            break;
    }
    return done; 
}

// Non-blockingly enter data to unlock passcode
bool UnlockPasscode()
{
    int i = 0;
    bool done = false;
    
    switch (entryState)
    {
        case 0:
            break;
        case 1: 
            pc.printf("\n\rTo unlock, enter a 4-digit passcode: ");
            entryReady = false;
            entryState = 2;
            break;
        case 2:
            peepEntry();
            if (!entryReady)
                break;
            else
                entryState = 3;    
        case 3:
            sscanf(inBuf, "%d", &i);
            if (i < 0000 || i > 9999) {
                pc.printf("\n\rEnter a passcode between 0000 and 9999: ");
                entryReady = false;
                entryState = 3;
            } else {
                if (passcode == i) {
                    pc.printf("\n\r====> Unlock successful. :-) \n\r");
                    sLockActive = false;
                    statusAlarm &= 0xFFFFFFFD;
                    lockLed = 0;
                    updateJoyDisplay = true;
                } else {
                    pc.printf("\n\r====> Incorrect passcode!\n\r");
                }
                done = true;
            entryState = 1;
                
            }
            break;
        
    }
    return done;    
}

// Non-blockingly innput a simulated temperature
// Input: None
bool EnterTemp()
{
    int i;
    bool done = false; 
    
    switch (entryState)
    {
        case 0:
            break;
        case 1: 
            pc.printf("\n\rEnter a simulated temperature: ");
            entryReady = false;
            entryState = 2;
            break;
        case 2: 
            peepEntry();
            if (!entryReady)
                break;
            else
                entryState = 3;
        case 3:
            sscanf(inBuf, "%d", &i);
            if (i < 0 || i >= 100) {
                printf("\n\rEnter a temperature between 0F and 100F: ");            
                entryReady = false;
                entryState = 2;
                break;
            } else {
                temp = i;
                printf("Current temperature is now %dF.\n\r", i);
                updateCurTempDisplay = true;
                entryState = 1;
                done = true;
                calibratePot();
                break;
            }

            
    }
    return done; 

}

// Check if USB is connected   
// To read lock status: bit0=NUM_LOCK bit1=CAP_LOCK bit2=SCROLL_LOCK
// To check, either check if keyCode returns OK or status led is signaled.
// To-Do: Correct the logic as status should return alternate results as
//        CAP LOCK KEY is being hit continuously. 
void USBConnCheck()
{
    char status = 0;
    
    //if (!(statusAlarm & 0x80000000))
    //{
    //    dev.keyCode(KEY_NUM_LOCK);
    
    dev.keyCode(KEY_CAPS_LOCK);
    //if (dev.keyCode(KEY_CAPS_LOCK))
    //        printf("\rSend KEY_CAPS_LOCK OK\n\r");
    
    status = dev.lockStatus();
    if (!(statusAlarm & 0x80000000) && (status & 0x2))
    {
        statusAlarm |= 0x80000000; 
    }
    else if ((statusAlarm & 0x80000000) && !(status & 0x2))
    {
        statusAlarm &= 0x7FFFFFFF;
    }
    //printf("2: lockStatus = 0x%x statusAlarm = 0x%x\n\r", status, statusAlarm);
    
}

// Turn on and off the alarm comparing the current temperature with and the set temperature
// Input: None
void TempMonitor()
{
    // Record current state of relay switch
    int tempAlarm = statusAlarm & 0x1;
    if (((temp < (setLowerTemp - tol)) || (temp > (setUpperTemp + tol))) && sHealthFeatureActive) 
    {
        statusAlarm |= 0x1; 
        alarmType = 0;
    }
    else if (((temp >= setLowerTemp) && (temp <= setUpperTemp)) || !sHealthFeatureActive)
    {
        statusAlarm &= 0xFFFFFFFE;
    }
    // When alarm is turned on or off
    if (tempAlarm != (statusAlarm & 0x1))
    {
        seconds = time(NULL);
        char buffer[32];  
        strftime(buffer, 32, "%T", localtime(&seconds));
        
        if (statusAlarm & 0x1)
        {
            if (timer2.read())
            {
                timer2.stop();
                pc.printf("Temperature Alarm off for %.2f sec.\n\r", timer2.read());
            }
            timer2.reset();
            pc.printf("Temperature Alarm on.... %s\n\r", buffer);
            timer2.start();
        }
        else
        {
            timer2.stop();
            timeElapsed = timer2.read();
            pc.printf("Temperature Alarm off... %s (Duration: %.2f sec)\n\r", buffer, timeElapsed);
            timer2.reset();
            timer2.start();
        }
        updateJoyDisplay = true;
    }
}



// Read temperature sensor
// Input: None
void ReadTemp()
{
    //temp = Ctmp.read();
    temp = Ctmp.read()*1.8+32;
    updateCurTempDisplay = true;
}

// Monitor accelerometer to detect motion and turn on and off the alarm after comparing the motion data with
// preconfigurated motion factor.
void MotionMonitor()
{
    //Xaxis_p = MMA.x() || -MMA.x();
    
    float xpos, ypos, zpos;
    float senNum = senParm[senLevel].factor;
    xpos = MMA.x();
    ypos = MMA.y();
    zpos = MMA.z();
    if ((xpos > senNum || xpos < -(senNum) || ypos > senNum || ypos < -(senNum))  && sSecurityFeatureActive) 
    {
        statusAlarm |= 0x2;
        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);
        //updateJoyDisplay = true;
    } 
    else
    {
        if ((statusAlarm & 0x2) && (mode == 0 || !sLockActive))
        {
            statusAlarm &= 0xFFFFFFFD;
            pc.printf("Security Alarm OFF 0x%x(Xpos: %6.3f Ypos: %6.3f Zpos: %6.3f)\n\r", statusAlarm, xpos, ypos, zpos);
        }
        //else
        //    pc.printf("Security Alarm %s (Xpos: %6.3f Ypos: %6.3f Zpos: %6.3f)\n\r", (statusAlarm & 0x2)? "sON": "sOFF", xpos, ypos, zpos);
        //updateJoyDisplay = true;
    }
}

// Display date, time, heater state, relay state, current and set temperature at LCD
// Input: None
void DisplayLCD()
{
    seconds = time(NULL);
    
    char buffer[32];  
    strftime(buffer, 32, "%F %T", localtime(&seconds));
        
    lcd.locate(0,3);
    lcd.printf("%s\n",buffer);
    if (updateCurTempDisplay || updateJoyDisplay)
    {
        lcd.printf("Now: %.1f%c L:%3.0f%c U: %3.1f%c\n", temp, deg, setLowerTemp, deg, setUpperTemp, deg);
        updateCurTempDisplay = false;
    }

            
    if (updateJoyDisplay)
    {
        lcd.printf("Mode: %c %1s%2s  Status: %s%s\n", modeSym[mode], sHealthFeatureActive? "H": " ", senParm[senLevel].sym, sLockActive? "L":" ", sAlarmOn? "A": " ");
        updateJoyDisplay = false;
    }
        
}

// Check if alarm is to be triggered by either temp or security events
// Do buzz for temperature and security alarm events accordingly
void AlarmCheck()
{
    bool prevState = sAlarmOn;
    if (statusAlarm & 0x1 || statusAlarm & 0x2)
        sAlarmOn = ON;
    else         
        sAlarmOn = OFF;
        
    if (statusAlarm & 0x80000000)
        connectionLed = 1;
    else
        connectionLed = 0;        
        
    if (prevState != sAlarmOn)
        updateJoyDisplay = true;        
    
    //leds = statusAlarm;
    if ((statusAlarm & 0x2) && (statusAlarm & 0x1))
    {
        buzzOn(1, BUZZ_SPERIOD);
        ledOn(1, BUZZ_SPERIOD);
        ledOn(0, BUZZ_TPERIOD);
    } 
    // Security alarm
    else if (statusAlarm & 0x2)
    {
        buzzOn(1, BUZZ_SPERIOD);
        ledOn(1, BUZZ_SPERIOD);
    }
    // Temperature alarm
    else if (statusAlarm & 0x1)
    {
        buzzOn(0, BUZZ_TPERIOD);
        ledOn(0, BUZZ_TPERIOD);
    }
}

    
// Initialize settings 
void Init(void)
{
    SetTime(YEAR, MONTH, DATE, HOUR, MIN, 0);
    
    IRQFire.rise(&ISRFirePressed);
    IRQJoyUp.rise(&ISRJoyUp);
    IRQJoyDown.rise(&ISRJoyDown);
    IRQJoyLeft.rise(&ISRJoyLeft);
    IRQJoyRight.rise(&ISRJoyRight);    
    timer1.attach(&DisplayLCD, 1);
    timer3.attach(&debounce, 1);
    //timer4.attach(&USBConnCheck, 2);  // Cannot use with ticker
    //timer4.attach(&AlarmCheck, 1);    // Cannot use or it won't respond external events
    sHealthFeatureActive = OFF;
    sSecurityFeatureActive = OFF;
    sAlarmOn = OFF;
    statusAlarm = 0;
    sState = 0;
    setLowerTemp = DEF_LOWER_TEMP;
    setUpperTemp = DEF_UPPER_TEMP;
    tempOverride = false;
    senLevel = 0;
    buzzPattern = 0;
    buzzPeriod = 0.2;
    mode = 0;
    timeElapsed = 0;
    entryState = 1; 
    lcd.cls();
    lcd.locate(0,3);
    updateJoyDisplay = true;

    calibratePot();            
    pc.printf("\n\rHealth & Security Monitoring starts...\n\r");
    
}

// Main loop in executing major temperature, motion monitoring tasks and alarm check task
void FSM(void)    
{
    while(1) 
    {
        USBConnCheck();
        
        // Override temperature read for testing. Use pot to control temperature
        if (!tempOverride)
            ReadTemp();
        
        setLowerTemp = lowerTempBase + (pot1.read()-potBase1) * 12;
        setUpperTemp = upperTempBase + (pot2.read()-potBase2) * 12;
        updateCurTempDisplay = true;
 
        switch (gState)
        {
            case 0: 
                    break;
            case 1: 
                    if (SetPasscode())
                        gState = 0;
                    break;
            case 2: 
                    if (UnlockPasscode())
                        gState = 0;
                    break;
            case 3: 
                    if (EnterTemp())
                        gState = 0;
                    break;                    
        }
 
        MotionMonitor();        
        TempMonitor();
        AlarmCheck();
        
        /* Live check
        lockLed = 1;
        wait (0.1);
        lockLed = 0;
        wait(0.1);
        */
    }

}

int main()
{
    //buzzTest();
    Init();
    FSM();    
}