Mobile Security System - Revision 1.0
Dependencies: FXOS8700Q N5110 SDFileSystem SRF02 mbed
main.cpp
- Committer:
- el14dg
- Date:
- 2016-05-04
- Revision:
- 9:a5614f53d435
- Parent:
- 8:8a3d1c07bdec
File content as of revision 9:a5614f53d435:
/* ELEC2645 Project */ #include "main.h" int main() { init_serial(); // set up UART connection with PC for debugging init_K64F(); // set up K64F on board LEDs and switches init_buttons(); // set up the three external buttons init_variables(); // initialise all variables to 0 lcd.init(); // initialise the Nokia 5110 LCD read_pin(); // read current pin from the SD card to the set_pin array buzzer.period(1.0/500.0); // set the buzzer period - 500 Hz buzzer.write(0.5); // duty cycle = 0.5 ----> Square Wave wait(2); // wait two seconds to allow LCD to initialise screen_selection(); // initial screen wait(4); g_next_state = 1; screen_selection(); // menu screen g_current_state = 1; while (1) { if (g_button_0_flag) { // if button_0 is pressed pc.printf("g_button_0_flag = %d \n", g_button_0_flag); g_button_0_flag = 0; button_0_protocol(); } if (g_button_1_flag) { // if button_1 is pressed pc.printf("g_button_1_flag = %d \n", g_button_1_flag); g_button_1_flag = 0; button_1_protocol(); } if (g_button_c_flag) { // if button_c is pressed pc.printf("g_button_c_flag = %d \n", g_button_c_flag); g_button_c_flag = 0; button_c_protocol(); } if (g_setting_distance_flag) { // state 4 - initial setting distance g_setting_distance_flag = 0; get_setting_distance(); } if (g_intruder_distance_flag) { // state 5 - current distance compared to initial setting distance if (g_current_state == 5) { g_setting_distance_flag = 0; get_intruder_distance(); } } if (g_setting_screen_flag) { // state 4 loading bar and percentage animation g_setting_screen_flag = 0; setting_animation(); } if (g_led_buzzer_flag) { // toggles LED and buzzer g_led_buzzer_flag = 0; led_alarm = !led_alarm; if (buzzer == 0) { buzzer = 0.5; } else { buzzer = 0; } } if (g_acc_flag) { g_acc_flag = 0; if (g_current_state == 4) { compare_axis_data(); } } if (g_pin_timeout_flag) { // state 7 - 20 second timeout g_pin_timeout_flag = 0; timeout_protocol(); } if (g_next_state != g_current_state) { pc.printf("TRANSITION \n"); screen_selection(); // the screen is determined by the value of g_next_state g_current_state = g_next_state; pc.printf("Current State = %d \n",g_current_state); } sleep(); } } // Initialisation Functions void init_serial() { // Ensure terminal software matches pc.baud(115200); } void init_K64F() { // on-board LEDs are active-low, so they are set high to turn them off. r_led = 1; g_led = 1; b_led = 1; // since the on-board switches have external pull-ups, we should disable the internal pull-down // resistors that are enabled by default using InterruptIn sw2.mode(PullNone); sw3.mode(PullNone); } void init_buttons() { // all external buttons trigger the relevant ISR when the voltage at the K64F pin falls button_0.fall(&button_0_isr); button_1.fall(&button_1_isr); button_c.fall(&button_c_isr); // enable the internal pull-down resistors button_0.mode(PullDown); button_1.mode(PullDown); button_c.mode(PullDown); } void init_variables() { one_second_distance = 0; one_second_avg_distance = 0; initial_setting_distance = 0; pin_counter = 0; incorrect_pin_flag = 0; setting_distance_counter = 0; intruder_distance_counter = 0; g_button_0_flag = 0; g_button_1_flag = 0; g_button_c_flag = 0; g_setting_distance_flag = 0; g_intruder_distance_flag = 0; g_pin_timeout_flag = 0; g_current_state = 0; reset_entered_pin(); acc.enable(); } // Interrupt Service Routines (ISRs) void setting_distance_isr() { g_setting_distance_flag = 1; } void intruder_distance_isr() { g_intruder_distance_flag = 1; } void button_0_isr() { g_button_0_flag = 1; } void button_1_isr() { g_button_1_flag = 1; } void button_c_isr() { g_button_c_flag = 1; } void led_buzzer_isr() { g_led_buzzer_flag = 1; } void acc_isr() { g_acc_flag = 1; } void pin_timeout_isr() { g_pin_timeout_flag = 1; } void setting_screen_isr() { g_setting_screen_flag = 1; } // Button Functions void button_0_protocol() { // states 2, 3, 6 and 7 require a pin to be entered if (g_current_state == 2) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 0; pin_counter++; } enter_pin(); // enter_pin() prints '*' to the LCD } else if (g_current_state == 3) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 0; pin_counter++; } enter_pin(); // Prints '*' to the LCD } else if (g_current_state == 6) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 0; pin_counter++; } enter_pin(); // Prints '*' to the LCD } else if (g_current_state == 7) { // entered_pin has four elements if (pin_counter < 4) { entered_pin[pin_counter] = 0; pin_counter++; } enter_pin(); // Prints '*' to the LCD } else { g_next_state = fsm[g_current_state].nextState[0]; // Filters through fsm to find the next state } } void button_1_protocol() { // States 2, 3, 6 and 7 require a pin to be entered if (g_current_state == 2) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 1; pin_counter++; } enter_pin(); // enter_pin() prints '*' to the LCD } else if (g_current_state == 3) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 1; pin_counter++; } enter_pin(); // Prints '*' to the LCD } else if (g_current_state == 6) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 1; pin_counter++; } enter_pin(); // Prints '*' to the LCD } else if (g_current_state == 7) { if (pin_counter < 4) { // entered_pin has four elements entered_pin[pin_counter] = 1; pin_counter++; } enter_pin(); // Prints '*' to the LCD } else { g_next_state = fsm[g_current_state].nextState[1]; // Filters through fsm to find the next state } } void button_c_protocol() { // States 2, 3, 6 and 7 require a pin to be entered // The screen only progresses if the correct pin is entered if (g_current_state == 2) { screen_progression(); } else if (g_current_state == 3) { screen_progression(); } else if (g_current_state == 6) { screen_progression(); } else if (g_current_state == 7) { screen_progression(); } else { g_next_state = fsm[g_current_state].nextState[2]; // filters through fsm to find the next state } } // State Functions void state_0_screen() { lcd.clear(); // print the screen lcd.printString("Mobile",27,1); lcd.printString("Security",18,2); lcd.printString("System",27,3); lcd_border(); // set LED and buzzer led_alarm = 0; buzzer.write(0.0); lcd.refresh(); } void state_1_screen() { lcd.clear(); // print the screen lcd.printString("Set Alarm",15,1); lcd.printString("Set New Pin",9,4); lcd_border(); for (int i = 0; i < WIDTH; i++) { lcd.setPixel(i,24); } // detach tickers pin_timeout.detach(); accelerometer.detach(); intruder_distance.detach(); alerts.detach(); // set LED and buzzer led_alarm = 0; buzzer.write(0.0); // reset counter pin_timeout_counter = 0; lcd.refresh(); } void state_2_screen() { lcd.clear(); // print the screen lcd.printString("Enter 4 Digit",3,1); lcd.printString("Pin Below",15,2); pin_text_box(); lcd_border(); // set the LED and buzzer led_alarm = 0; buzzer.write(0.0); lcd.refresh(); } void state_3_screen() { lcd.clear(); // print the screen lcd.printString("Enter New 4",9,1); lcd.printString("Digit Pin",15,2); pin_text_box(); lcd_border(); // set the LED and buzzer led_alarm = 0; buzzer.write(0.0); lcd.refresh(); } void state_4_screen() { lcd.clear(); // print the screen lcd.printString("Setting",21,1); lcd_border(); lcd.drawRect(0,20,84,5,0); // blank setting bar lcd.printString("0%",41,4); // 0% of setting complete // reset counter setting_alarm_counter = 0; // set LED and buzzer led_alarm = 0; buzzer.write(0.0); // attach tickers alerts.attach(&led_buzzer_isr,0.5); setting_distance.attach(&setting_distance_isr,0.1); accelerometer.attach(&acc_isr,0.1); setting_screen.attach(&setting_screen_isr,0.28); // get setting accelerometer data get_axis_data(); pc.printf("Printing setting accelerometer data....\n"); setting_acc_X = acc_X; setting_acc_Y = acc_Y; setting_acc_Z = acc_Z; pc.printf("X = %.4f \nY = %.4f \nZ = %.4f \n",setting_acc_X,setting_acc_Y,setting_acc_Z); lcd.refresh(); } void state_5_screen() { lcd.clear(); // print the screen lcd.printString("Alarm Set",15,1); lcd.printString("DEACTIVATE?",9,4); lcd_border(); for (int i = 0; i < WIDTH; i++) { lcd.setPixel(i,20); } // detach tickers alerts.detach(); accelerometer.detach(); setting_screen.detach(); // attach ticker intruder_distance.attach(&intruder_distance_isr,0.1); // set LED and buzzer led_alarm = 1; buzzer.write(0.5); // turn off buzzer after 1 second buzz.attach(&alarm_setting_buzz,1); lcd.refresh(); } void state_6_screen() { lcd.clear(); // print the screen lcd.printString("DEACTIVATE",12,1); lcd.printString("Enter Pin",15,2); lcd_border(); pin_text_box(); // set the LED and buzzer led_alarm = 0; buzzer.write(0.0); // attach ticker alerts.attach(&led_buzzer_isr,0.5); // detach ticker intruder_distance.detach(); lcd.refresh(); } void state_7_screen() { lcd.clear(); // print the screen lcd.printString("INTRUDER",18,1); lcd.printString("Enter Pin",15,2); lcd_border(); pin_text_box(); // set the LED and buzzer led_alarm = 0; buzzer.write(0.0); // attach tickers alerts.attach(&led_buzzer_isr,0.5); pin_timeout.attach(&pin_timeout_isr,1); // detach ticker intruder_distance.detach(); lcd.refresh(); } void state_8_screen() { lcd.clear(); // print the screen lcd.printString("ALARM",27,1); lcd.printString("TRIGGERED",15,2); lcd.printString("Menu?",27,4); lcd_border(); // set the LED and buzzer led_alarm = 0; buzzer.write(0.0); // detach tickers alerts.detach(); pin_timeout.detach(); // attach ticker alerts.attach(&led_buzzer_isr,0.2); lcd.refresh(); } void lcd_border() { lcd.drawRect(0,0,83,47,0); lcd.drawRect(1,1,81,45,0); } void pin_text_box() { if (g_current_state == 7) { lcd.drawRect(1,30,15,10,0); // transparent box lcd.drawRect(15,30,15,10,0); // transparent box lcd.drawRect(29,30,15,10,0); // transparent box lcd.drawRect(43,30,15,10,0); // transparent box lcd.drawRect(57,30,15,10,0); // transparent box lcd.drawRect(71,30,15,10,1); // filled box } else { lcd.drawRect(1,30,15,10,1); // filled box lcd.drawRect(15,30,15,10,0); // transparent box lcd.drawRect(29,30,15,10,0); // transparent box lcd.drawRect(43,30,15,10,0); // transparent box lcd.drawRect(57,30,15,10,0); // transparent box lcd.drawRect(71,30,15,10,1); // filled box } } void screen_progression() { if (g_current_state == 3) { // set new pin state if (pin_counter > 3) { // if a four digit pin has been entered change_pin(); // save entered_pin to the SD card read_pin(); // read the pin from the SD card to the set_pin array g_next_state = fsm[g_current_state].nextState[2]; } else { g_next_state = fsm[g_current_state].nextState[3]; } } else { // if the current state is either 2, 6 or 7 check_pin(); // sets incorrect_pin_flag to 1 if entered pin doesn't match set_pin if (incorrect_pin_flag == 1) { incorrect_pin_flag = 0; g_next_state = fsm[g_current_state].nextState[3]; // go to previous state or alarm triggered state pc.printf("g_next_state = %d\n",g_next_state); } else { g_next_state = fsm[g_current_state].nextState[2]; // proceed pc.printf("g_next_state = %d\n",g_next_state); } } } void screen_selection() { reset_entered_pin(); // re-set each element of the entered pin array to -1 if (g_next_state == 0) { state_0_screen(); } else if (g_next_state == 1) { state_1_screen(); } else if (g_next_state == 2) { state_2_screen(); } else if (g_next_state == 3) { state_3_screen(); } else if (g_next_state == 4) { state_4_screen(); } else if (g_next_state == 5) { state_5_screen(); } else if (g_next_state == 6) { state_6_screen(); } else if (g_next_state == 7) { state_7_screen(); } else { state_8_screen(); } } // Screen Animation Functions void setting_animation() { setting_alarm_counter = setting_alarm_counter + 5; // increment setting_alarm_counter in steps of five if (setting_alarm_counter < 101) { lcd.drawRect(0,20,setting_alarm_counter,5,1); // prints the loading bar to the LCD // format how the percentage is displayed depending on its value if (setting_alarm_counter < 10) { length = sprintf(buffer,"0%d%%",setting_alarm_counter); } else { length = sprintf(buffer,"%d%%",setting_alarm_counter); } if (length <= 14) { // if length of string will fit on the screen ( WIDTH = 6 * 24 = 84 pixels ) if (setting_alarm_counter < 100) { lcd.printString(buffer,33,4); } else { lcd.printString(buffer,30,4); // this string is four characters long and is therefore shifted to the left of the screen } } lcd.refresh(); // refresh screen } } void timeout_protocol() { pin_timeout_counter++; seconds_till_timeout = 21 - pin_timeout_counter; // timeout counts down from 20 if (seconds_till_timeout == 0) { // if 20 seconds passes g_next_state = 8; pin_timeout_counter = 0; } else { // less than 20 seconds has passed // These if statements manage the formatting of the number of seconds remaining if (seconds_till_timeout >= 10) { length = sprintf(buffer,"%d",seconds_till_timeout); } else { length = sprintf(buffer,"0%d",seconds_till_timeout); } // if the length of the formatted string will fit on the screen print it ( WIDTH = 14 * 6 = 84 pixels ) if (length <= 14) lcd.printString(buffer,3,4); lcd.refresh(); } } // Read Distance Functions void get_setting_distance() { distance[setting_distance_counter] = srf02.getDistanceCm(); // distance array stores 10 distance readings setting_distance_counter++; if (setting_distance_counter == 10) { // if distance array has 10 new readings (arrays are zero indexed) setting_distance.detach(); calculate_setting_distance(); // find the average of the 10 distance readings } } void get_intruder_distance() { distance[intruder_distance_counter] = srf02.getDistanceCm(); // distance array stores 10 distance readings intruder_distance_counter++; if (intruder_distance_counter == 10) { // if distance array has 10 new readings (arrays are zero indexed) intruder_distance.detach(); calculate_intruder_distance(); // find the average of the 10 distance readings } } void calculate_setting_distance() { for (int i = 0; i < 10; i++) { one_second_distance = one_second_distance + distance[i]; // add all 10 readings together } initial_setting_distance = (one_second_distance / 10); pc.printf("Initial Setting Distance = %.2f cm\n",initial_setting_distance); setting_distance_counter = 0; one_second_distance = 0; transition.attach(&screen_5_transition,5); // transition to the set screen in five seconds } void calculate_intruder_distance() { for (int i = 0; i < 10; i++) { one_second_distance = one_second_distance + distance[i]; // add all 10 distance readings together } one_second_avg_distance = one_second_distance / 10; pc.printf("Intruder Distance = %.2f cm\n",one_second_avg_distance); intruder_distance_counter = 0; one_second_distance = 0; if (one_second_avg_distance > (1.1*initial_setting_distance)) { // if the current average distance is 10% greater than the initial_setting_distance set off the alarm g_next_state = 7; g_current_state = 7; screen_selection(); } else if (one_second_avg_distance < (0.9 * initial_setting_distance)) { // if the current average distance is 10% smaller than the initial_setting_distance set off the alarm g_next_state = 7; g_current_state = 7; screen_selection(); } else { // if the current distance is within 10% of the initial_setting_distance carry on reading distance intruder_distance.attach(&intruder_distance_isr,0.1); } } // Timeout Functions void screen_5_transition() { g_next_state = 5; accelerometer.detach(); screen_selection(); // sets the LCD to screen 5 g_current_state = 5; } void pin_confirm() { lcd.clear(); lcd_border(); lcd.printString("Press C",24,1); lcd.printString("to",36,2); lcd.printString("Confirm",24,3); if (g_current_state == 7) { lcd.drawRect(1,30,15,10,0); } lcd.refresh(); } void state_1_transition() { g_next_state = 1; screen_selection(); g_current_state = 1; alerts.detach(); } void alarm_setting_buzz() { buzzer.write(0.0); // turn off buzzer } // Accelerometer Function void get_axis_data() { acc.getX(acc_X); acc.getY(acc_Y); acc.getZ(acc_Z); } void compare_axis_data() { get_axis_data(); pc.printf("X1 = %.4f \nY1 = %.4f \nZ1 = %.4f \n",acc_X,acc_Y,acc_Z); if (abs(acc_X) < 0.2f*abs(setting_acc_X)) { // Uses abs() due to possibility of axis dat being negative device_tampered_protocol(); pc.printf("acc_X < setting_acc_X\n"); } else if (abs(acc_X) > 5.0f*abs(setting_acc_X)) { // Uses abs() due to possibility of axis dat being negative device_tampered_protocol(); pc.printf("acc_X > setting_acc_X\n"); } else if (abs(acc_Y) < 0.2f*abs(setting_acc_Y)) { // Uses abs() due to possibility of axis dat being negative device_tampered_protocol(); pc.printf("acc_Y < setting_acc_Y\n"); } else if (abs(acc_Y) > 5.0f*abs(setting_acc_Y)) { // Uses abs() due to possibility of axis dat being negative device_tampered_protocol(); pc.printf("acc_Y > setting_acc_Y\n"); } else if (abs(acc_Z) < 0.2f*abs(setting_acc_Z)) { // Uses abs() due to possibility of axis dat being negative device_tampered_protocol(); pc.printf("acc_Z < setting_acc_Z\n"); } else if (abs(acc_Z) > 5.0f*abs(setting_acc_Z)) { // Uses abs() due to possibility of axis dat being negative device_tampered_protocol(); pc.printf("acc_Z > setting_acc_Z\n"); } else { // Do nothing } } void device_tampered_protocol() { setting_distance.detach(); // stop reading distance setting_screen.detach(); // stop setting screen animation accelerometer.detach(); // stop taking readings from the accelerometer transition.detach(); // cancel scheduled transition to state 5 alerts.detach(); // turn off LED and Buzzer lcd.clear(); lcd.printString("DEVICE MOVED",6,1); lcd.printString("SETTING",21,3); lcd.printString("INCOMPLETE",12,4); lcd_border(); lcd.refresh(); alerts.attach(&led_buzzer_isr,0.35); tamper_transition.attach(&state_1_transition,3); // transition to state 1 due to the device been tampered with whilst setting } // Pin Functions void enter_pin() { // current value of the pin_counter determines where '*' is printed if (pin_counter == 1) { lcd.printString("*",20,4); } else if (pin_counter == 2) { lcd.printString("*",34,4); } else if (pin_counter == 3) { lcd.printString("*",48,4); } else if (pin_counter == 4) { lcd.printString("*",62,4); confirm.attach(&pin_confirm,0.5); // 'Press C to Confirm' screen } } void reset_entered_pin() { for (int i = 0; i < 4; i++) { entered_pin[i] = -1; // sets each element of entered_pin to -1 } pin_counter = 0; } void check_pin() { for (int i = 0; i < 4; i++) { if (entered_pin[i] != set_pin[i]) { // if any element of entered_pin doesn't match set_pin pc.printf("entered pin doesn't match set pin..."); incorrect_pin_flag = 1; break; } } } void change_pin() { delete_file("/sd/test.txt"); pin = fopen("/sd/test.txt", "a"); if (pin == NULL) { // if it can't open the file then print error message pc.printf("Error! Unable to open file!\n"); } else { pc.printf("Writing to file....\n"); for(int i = 0; i < 4; i++) { int pin_element = entered_pin[i];; // pin_element takes on the value of each element in the entered_pin array fprintf(pin, "%d,%d\n",i,pin_element); // pin element is printed to SD card file (CSV) } for(int i = 0; i < 4; i++) { pc.printf("[%d] %d\n",i,entered_pin[i]); // print to PC for debugging purposes } pc.printf("Done.\n"); fclose(pin); // close the file after writing } } void read_pin() { pin = fopen("/sd/test.txt", "r"); int i = 0; pc.printf("Reading into set_pin array...\n"); while (fscanf(pin, "%d,%d",&index_array[i],&set_pin[i]) != EOF) { // EOF ---> End of File i++; // read data into array and increment index } fclose(pin); // close the file after reading for(int i = 0; i < 4 ; i++) { pc.printf("[%d] %d\n",i,set_pin[i]); // print to PC for debugging purposes } pc.printf("Done.\n"); } void delete_file(char filename[]) { pc.printf("Deleting file '%s'...",filename); FILE *fp = fopen(filename, "r"); // try and open file if (fp != NULL) { // if it does open... fclose(fp); // close it remove(filename); // delete the file pc.printf("Done!\n"); } // if it can't be opened, it doesn't exist and can't be deleted }