This is a simplified version of home alarm system for CE323/CE860 (Advanced Embedded Systems Design) in the University of Essex.

Dependencies:   TextLCD mbed

main.cpp

Committer:
liruihao2008
Date:
2017-02-17
Revision:
0:df2226ca976c

File content as of revision 0:df2226ca976c:

/*=============================================================================
Copyright University of Essex 2017
Author: Ruihao Li

FILE - main.c
    mbed LPC1768 application.
    
DESCRIPTION
    alarm 1 laboratory solution.
    hardware: mbed LPC1768, an extension board.
    Use a terminal program such as 'HyperTerminal' to communicate with the application.
    The serial port configuration is shown below.
        9600 Baud 
        8 data bits 
        No parity bits 
        One stop bit 
        No hardware flow control    
==============================================================================*/


/******************************************************************************
Include head files.
******************************************************************************/
#include "mbed.h"
#include "TextLCD.h"

// TextLCD 
TextLCD lcd(p15, p16, p17, p18, p19, p20);//, TextLCD::LCD20x4); // rs, e, d4-d7

// Read from switches and keypad
BusOut rows(p26,p25,p24);
BusIn cols(p14,p13,p12,p11);

// Control external LEDs
SPI sw(p5, p6, p7);
DigitalOut cs(p8); 

// Serial USB
Serial pc(USBTX, USBRX); // tx, rx

// Temperature reading
I2C i2c(p9, p10);              // I2C: SDA, SCL

DigitalOut Sounder(LED1);
DigitalOut led4(LED4);

/******************************************************************************
Declaration of functions.
******************************************************************************/
void alarmConfig(void);
void alarm_state(); 

int  read_switch(void);
int  switchleds(void);
void initleds();
void setleds(int ledall);
void setled(int ledno, int ledstate);
int  readled(int ledno);
int  readleds();

char getKey();
void setKey(void); 
int  testCode(void);

void sounder_blink();
void pattern(void);
void patternoff(void);
void Sounderoff(void);

void system_alarm(void);
void system_set(void);

/******************************************************************************
Global variables.
******************************************************************************/
enum State {unset, exits, set, entry, alarm, report} state;          
char Keytable[] = { 'F', 'E', 'D', 'C',   
                    '3', '6', '9', 'B',   
                    '2', '5', '8', '0',   
                    '1', '4', '7', 'A'    
                   };
char keyCode[] = {'1','2','3','4'};
char code[4];
int  fail = 0; // number of failed attempts
int  success;  // 0~4: number of successful matched keycodes; 5 indicates switch changing; 6 indicates time expired
int  zone;     
int  led_bits = 0;   // global LED status used for readback
bool time_expired ;
Ticker timer;
Timeout t_alarm, t_entry, t_exit;            
            
/*=============================================================================

FILE - main.cpp

DESCRIPTION
    Initiates the Finite State Machine
=============================================================================*/
int main() { 
    alarmConfig(); 

    lcd.cls();
    lcd.locate(2,0);
    lcd.printf("Alarm Lab");
    pc.printf("\n\n\r              ALARM LAB\n\r (c)Copyright University of Essex 2017 \n\r            Author: Ruihao Li\n\r");
    
    setKey();  
    while (1){
        switchleds();
        alarm_state();  // FSM routine
    }
}

/**********************************************************************************
Finite State Machine for Alarm
**********************************************************************************/
void alarm_state(){
    int s;
    
    switch(state){
 /*--------------------------------------------------------------------------------
    UN_SET STATE (STATE 1)
        un_set led enabled
        Internal sounder disabledabled 
        Sensors not monitored.  
---------------------------------------------------------------------------------*/ 
    case unset:
        setled(8,3);  // turn unset led on
        pc.printf("\n\r Unset mode\n\r");
        lcd.cls();
        lcd.printf("Unset mode");
        
        success = testCode();
        if (success == 4) {
            fail = 0;  // failure counter reset
            state = exits;    
        }
        else if (fail == 2) {
            pc.printf("\n\r attemp %d", fail+1);   
            state = alarm;
            zone = 5;    // zone identifier(5 represents an invalid code is entered three times)
            fail = 0;      //failure counter reset   
        }
        else{
            fail++;
            state = unset;
            pc.printf("\n\r attemp %d", fail);    
        }
        break;
/*--------------------------------------------------------------------------------
    EXIT STATE (STATE 2)
        un_set led flashes
        Internal sounder enabled for 250msec every 500msec. 
---------------------------------------------------------------------------------*/  
    case exits:  
        setled(7,3);   // turn exits led on   
        pattern();     // Sounder switches on and then off at 250ms intervals            
        pc.printf("\n\r Exit mode\n\r");
        lcd.cls();
        lcd.printf("Exit mode"); 
        
        // you should program here!       
                
        
            
        break;
 /*--------------------------------------------------------------------------------
    SET STATE (STATE 3) 
        set led enabled
        Internal sounder disabled.
---------------------------------------------------------------------------------*/ 
    case set: 
        setled(6,3);   // turn set led on
        
        pc.printf("\n\r Set mode\n\r");
        lcd.cls();
        lcd.printf("Set mode"); 
         
         
         // you should program here!     
 
        break;
/*--------------------------------------------------------------------------------
    ENTRY STATE (STATE 4) 
        un_set led flashes
        Internal sounder enabled for 250ms every 500ms.
---------------------------------------------------------------------------------*/ 
    case entry:
        setled(5,3);   // turn entry led on
        pattern();     // Sounder switches on and then off at 250ms intervals
        
        pc.printf("\n\r Entry mode\n\r");
        lcd.cls();
        lcd.printf("Entry mode"); 
        
        // you should program here!   
        
        break;
/*--------------------------------------------------------------------------------
    ALARM STATE (STATE 5)
        alarm led enabled
        Internal and External sounders enabled.
---------------------------------------------------------------------------------*/ 
    case alarm:
        setled(4,3);   // turn entry led on
        Sounder = 1;   //Sounder enabled all the time during alarm state
        
        pc.printf("\n\r Alarm mode\n\r");
        lcd.cls();
        lcd.printf("Alarm mode");         
        
        // you should program here!  

        break;      
/*--------------------------------------------------------------------------------
    REPORT (STATE 6)
        un-set and alarm leds enabled
        Internal sounder remains enabled.
        External sounder enabled.
---------------------------------------------------------------------------------*/         
    case report:
        setled(3,3);   // turn entry led on
        
        pc.printf("\n\r Report mode\n\r");
        lcd.cls();
        lcd.printf("Zone numbers:%i",zone);    
        lcd.locate(0,1);
        lcd.printf("C key to clear");  
        
        while (1){
            char b = getKey();  
            if (b == 'C'){
                state = unset;
                break;
            }            
        }     
        break;
    } // end switch(state)

} // end alarm_state()


/**********************************************************************************
Configurations
**********************************************************************************/
void alarmConfig() 
{
    cs=0;
    sw.format(16,0); 
    sw.frequency(1000000);
    
    state = unset;   // Initial state
    
    led_bits  = 0x0000;  // turn off all the external leds
    sw.write(led_bits); 
    cs = 1;
    cs = 0;
}

/**********************************************************************************
External switches 
**********************************************************************************/
int read_switch()
{
    rows = 4;
    int switches = cols;
    rows = 5;
    switches = switches*16 + cols;
    
    return switches;
}

int switchleds()
{
    int switches = read_switch();
        
    for(int i=0;i<=7;i++){
        if ((switches & 0x0001<<i)!=0){                         // 1, then turn on 
            led_bits  = led_bits | (0x0003 << i*2); }
        else {                                                  // 0, then turn off
            led_bits  = led_bits & ((0x0003 << i*2) ^ 0xffff); }
    }
    sw.write(led_bits); 
    cs = 1;
    cs = 0;

    return switches;
}

/**********************************************************************************
External LED functionality
**********************************************************************************/
void initleds() {
    cs = 0;                                        // latch must start low
    sw.format(16,0);                               // SPI 16 bit data, low state, high going clock
    sw.frequency(1000000);                         // 1MHz clock rate
}

void setleds(int ledall) {
    led_bits = ledall;                              // update global LED status
    sw.write((led_bits & 0x03ff) | ((led_bits & 0xa800) >> 1) | ((led_bits & 0x5400) << 1));
    cs = 1;                                        // latch pulse start 
    cs = 0;                                        // latch pulse end
}

void setled(int ledno, int ledstate) {
    ledno = 9 - ledno;
    ledno = ((ledno - 1) & 0x0007) + 1;             // limit led number
    ledno = (8 - ledno) * 2;                        // offset of led state in 'led_bits'
    ledstate = ledstate & 0x0003;                   // limit led state
    ledstate = ledstate << ledno;
    int statemask = ((0x0003 << ledno) ^ 0xffff);   // mask used to clear led state
    led_bits = ((led_bits & statemask) | ledstate); // clear and set led state
    setleds(led_bits);
}

int readled(int ledno) {
    ledno = 9 - ledno;
    ledno = ((ledno - 1) & 0x0007) + 1;             // limit led number
    ledno = (8 - ledno) * 2;                        // offset of led state in 'led_bits'
    int ledstate = led_bits;
    ledstate = ledstate >> ledno;                   // shift selected led state into ls 2 bits
    return (ledstate & 0x0003);                     // mask out and return led state
}

int readleds() {
    return led_bits;                                // return LED status
}

/**********************************************************************************
Keypad functionality
**********************************************************************************/
char getKey()
{
    int i,j;
    char ch=' ';
    
    for (i = 0; i <= 3; i++) {
        rows = i; 
        for (j = 0; j <= 3; j++) {           
            if (((cols ^ 0x00FF)  & (0x0001<<j)) != 0) {
                ch = Keytable[(i * 4) + j];
            }            
        }        
    }
    wait(0.2); //debouncing
    return ch;
}

int testCode(void)
{
    int a, y;
    char b;
    
    lcd.locate(0, 1);   
    lcd.printf("Enter Code: ____");
    y = 0; 
    for(a = 0; a < 4; a++) {
        b = getKey();     
        switch(b) {
            case ' ':
                a--; 
                break;
            case 'C':   // use 'C' to delete input
                if (a > 0){
                    a = a-2;
                    lcd.locate(13+a, 1);    
                    lcd.putc('_'); 
                    if ( code[a+1] == keyCode[a+1]){
                        y--;    
                    }                    
                }
                else if (a == 0){
                    a--;
                }
                break;              
            default:
                code[a] = b; 
                lcd.locate(12+a, 1);    
                lcd.putc('*');
                if(code[a] == keyCode[a]) {
                    y++; 
                }
        }
    }
    lcd.cls();
    lcd.locate(0,1);
    lcd.printf("Press B to set");  
    while (1){
        b = getKey();  
        if (b == 'B')
            break;
    }
    
    return(y); 
} 

void setKey(void) 
{
    int a;
    char b;
    
    lcd.locate(0, 1);   
    lcd.printf("Init  Code: ____");
    for(a = 0; a < 4; a++) {
        b = getKey(); 

        switch(b){
            case ' ':
                a--; 
                break;
            case 'C':
                if (a > 0){
                    a = a-2;
                    lcd.locate(13+a, 1);    
                    lcd.putc('_');                     
                }
                else if (a == 0){
                    a--;
                }
                break; 
            default:
                lcd.locate(12+a, 1);    
                lcd.putc(b);
                keyCode[a] = b; 
        }
    }
    wait(1);
} 

/**********************************************************************************
Simulation of alarm  internal sounder
**********************************************************************************/
void sounder_blink()
{
    Sounder = !Sounder;    
}

void pattern(void)
{
    timer.attach(&sounder_blink, 0.25); 
}

void patternoff(void)
{
    timer.detach();  // turn the Sounder off 
    Sounder = 0;  
}

void Sounderoff(void)
{
    Sounder = 0;    
}

/**********************************************************************************
Set system state
**********************************************************************************/
void system_alarm(void)
{
    state = alarm; 
    time_expired = true;    
}

void system_set(void)
{
    state = set; 
    time_expired = true;   
}