#include #include #include #include #include #include #define LCD_RS 0 #define LCD_RW 1 #define LCD_E 2 struct state_t{ bool armed; bool triggered; char password[5]; int motion_threshold; int zerocounter; int micstate; int micstate_times[2]; }; typedef struct state_t state_mode; static int time; static bool do_alarm; //LCD_getaddress reads the address counter and busy flag. For the address only, mask off bit7 of the return //value. char LCD_getaddr(void) { //make var for the return value char address; //PortD is input DDRB = 0; //RW high, strobe enable PORTD |= ((1<password)); i++){ strcat(passzeros, "0"); } strcat(passzeros, state->password); strcpy(state->password, passzeros); } void speaker_sound(int delay, int soundlen) { int i = 0; DDRa = 0xFF; while (i < soundlen){ if (PINa == 0b00000000){ PORTa = 0b00010000; _delay_loop_2(delay); } else { PORTa = 0b00000000; _delay_loop_2(delay); } i++; } DDRa = 0b11011111; } char wait_button_pressed() { int portd_save = PORTD; DDRa = 0xFF; //Vanta tills ingen knapp ar ned tryckt PORTD = 0b11110000; while(PINa != 0b00000000) {} while(1) { //Vanta 20 sek innan larmet gar if (get_timer()>20000 && (get_timer()%1000) ==0 && do_alarm) speaker_sound(0xFFF, 100); //Check through row 1 PORTD = 0b00010000; if (PINa == 0b00000001) { speaker_sound(0xFF, 200); return '0'; } else if (PINa == 0b00000010) { return '4'; } else if (PINa == 0b00000100) { return '8'; } else if (PINa == 0b00001000) { return 'L'; } //Check through row 2 PORTD = 0b00100000; if (PINa == 0b00000001) { return '1'; } else if (PINa == 0b00000010) { return '5'; } else if (PINa == 0b00000100) { return '9'; } else if (PINa == 0b00001000) { return 'R'; } //Check through row 3 PORTD = 0b01000000; if (PINa == 0b00000001) { return '2'; } else if (PINa == 0b00000010) { return '6'; } else if (PINa == 0b00000100) { return 'Y'; } else if (PINa == 0b00001000) { return 'U'; } //Check through row 4 PORTD = 0b10000000; if (PINa == 0b00000001) { return '3'; } else if (PINa == 0b00000010) { return '7'; } else if (PINa == 0b00000100) { return 'N'; } else if (PINa == 0b00001000) { return 'D'; } } PORTD = portd_save; DDRa = 0b11011111; } int aDC_read(unsigned char channel) { int value; aDMUX = 0x60 | channel; aDCSRa=aDCSRa|0x80; //enable adc aDCSRa=aDCSRa|0x40; //start conversion while((aDCSRa&0x10)==0); //wait untill conversion is done value=aDCL; //Read 8 low bits first (important) value|=(int)aDCH << 8; //read 2 high bits and shift into top byte return value; } void LCD_putint(int value){ char buf[20]; itoa(value, buf, 10); LCD_putword(buf); } void time_delay(int delay_ms) { int delay = delay_ms; //Konfigurera Timer1 TCNT1 = 0; TCCR1a = 0x00; TCCR1B = 0b00001101; //Borja om vid Output Compare, systemklockan/8 while(delay>=0){ if(TCNT1>=8) { delay = delay - 1; TCNT1 = 0; } } } void start_timer() { time = 0; TCNT1 = 0; TCCR1a = 0x00; TCCR1B = 0b00001101; //Borja om vid Output Compare, systemklockan/8 } int get_timer() { time += TCNT1/8; TCNT1 = TCNT1%8; return time; } bool check_mic(){ int value; value = aDC_read(0b00111); if (value > 0) return true; else return false; } void poll_while_armed(state_mode *state) { //Poll motion if ((PINa & 0b00100000) == 0){ state->zerocounter++; } else if (state->zerocounter > 0) { state->zerocounter=state->zerocounter - 1; } if (state->zerocounter > state->motion_threshold*400) { LCD_clear(); LCD_putword("Motion detected!\nCode: "); state->triggered = true; state->armed = false; state->zerocounter = 0; } //Poll mic if (check_mic()){ int thetime; if(state->micstate == 0){ start_timer(); state->micstate = 1; _delay_loop_2(0xFFFF); } else if(state->micstate == 1){ thetime = get_timer(); if (thetime > state->micstate_times[0] - 250 && thetime < state->micstate_times[0] + 250){ start_timer(); state->micstate = 2; _delay_loop_2(0xFFFF); } else { state->micstate = 0; _delay_loop_2(0xFFFF); } } else if(state->micstate == 2){ thetime = get_timer(); if (thetime > state->micstate_times[1] - 250 && thetime < state->micstate_times[1] + 250){ //Korrekt mic-kod! LCD_clear(); LCD_putword("Correct code!\nWelcome home!"); speaker_sound(0xFF, 200); speaker_sound(0xFF, 200); speaker_sound(0xFFF, 200); //Delay sa att man hinner se status time_delay(2000); LCD_clear(); state->triggered = false; state->armed = false; state->micstate = 0; } else { state->micstate = 0; _delay_loop_2(0xFFFF); } } } else if (get_timer() > 5000) { state->micstate = 0; } //Poll door if (PIND == 0b00000000) { LCD_clear(); LCD_putword("Door opened!\nCode: "); state->triggered = true; state->armed = false; } } void poll_while_disarmed(state_mode *state) { int i; char c; char entered[5]; //Poll keypad c = wait_button_pressed(); speaker_sound(0xFF, 200); if (c == 'Y') { //Y = andra kod LCD_clear(); LCD_putword("Changing code\nOld code: "); for(i = 0;i<4;i++) { //Tryck in den gamla koden c = wait_button_pressed(); if(isalpha(c)==0){ entered[i] = c; entered[i+1] = '\0'; LCD_putchar('*'); speaker_sound(0xFF, 200); } else --i; } if (strcmp(entered, state->password) == 0) { LCD_clear(); LCD_putword("Changing code\nNew code: "); for(i = 0;i<4;i++) { //Tryck in den nya koden c = wait_button_pressed(); if(isalpha(c)==0){ state->password[i] = c; state->password[i+1] = '\0'; LCD_putchar('*'); speaker_sound(0xFF, 200); } else --i; } LCD_clear(); LCD_putword("Code changed!"); eeprom_write_word(0xF0, atoi(state->password)); } else { LCD_clear(); LCD_putword("Wrong code!"); } //Delay sa att man hinner se status time_delay(2000); LCD_clear(); LCD_putword("Standby mode"); } else if (c == 'N') { //N = Skriv losenord for att alarmera systemet LCD_clear(); LCD_putword("arming system\nCode: "); for(i = 0;i<4;i++) { //Tryck in koden c = wait_button_pressed(); if(isalpha(c)==0){ entered[i] = c; entered[i+1] = '\0'; LCD_putchar('*'); speaker_sound(0xFF, 200); } else i--; } if (strcmp(entered, state->password) == 0) { LCD_clear(); //Vanta 30 sec innan systemet blir alarmerat for(i = 30; i>0; i--) { LCD_clear(); LCD_putword("alarm on in "); LCD_putint(i); LCD_putword(" s"); time_delay(1000); } state->triggered = false; state->armed = true; state->micstate = 0; state->zerocounter = 0; LCD_clear(); LCD_putword("armed"); } else { LCD_clear(); LCD_putword("Wrong Code!"); //Delay sa att man hinner se status time_delay(2000); LCD_clear(); LCD_putword("Standby mode"); } } else if (c == 'D') { LCD_clear(); LCD_putword("Current sense: "); LCD_putint(state->motion_threshold); LCD_putword(" New sense: "); c = wait_button_pressed(); while(isalpha(c)!=0){ c = wait_button_pressed(); } LCD_clear(); LCD_putword("New sense: "); char temp[2]; temp[0]=c; temp[1]='\0'; state->motion_threshold = atoi(temp); LCD_putint(state->motion_threshold); eeprom_write_word(0x05, state->motion_threshold); //Delay sa att man hinner se status time_delay(2000); LCD_clear(); LCD_putword("Standby mode"); } else if(c == 'U') { int time1, time2; LCD_clear(); LCD_putword("Knock once to\nstart timing"); while(!check_mic()){} _delay_loop_2(0xFFFF); _delay_loop_2(0xFFFF); _delay_loop_2(0xFFFF); start_timer(); LCD_clear(); LCD_putword("Timing started.."); while(!check_mic()){} time1 = get_timer(); LCD_clear(); LCD_putword("1st time: "); LCD_putint(time1); start_timer(); while(!check_mic()){} time2 = get_timer(); LCD_clear(); LCD_putword("2nd time: "); LCD_putint(time2); eeprom_write_word(0x07, time1); eeprom_write_word(0x09, time2); state->micstate_times[0] = time1; state->micstate_times[1] = time2; //Delay sa att man hinner se status time_delay(2000); LCD_clear(); LCD_putword("Standby mode"); } } void poll_while_triggered(state_mode* state) { int i; char c; char entered[5]; for(i = 0;i<4;i++) { c = wait_button_pressed(); if(isalpha(c)==0){ entered[i] = c; entered[i+1] = '\0'; LCD_putchar('*'); speaker_sound(0xFF, 200); } else i--; } if (strcmp(entered, state->password) == 0) { LCD_clear(); time=0;//Stanger av larmet TCNT1=0; TCCR1B = 0b00001000; do_alarm = false; LCD_putword("Correct code!\nWelcome home!"); //Delay sa att man hinner se status time_delay(2000); LCD_clear(); state->triggered = false; state->armed = false; } else { LCD_clear(); LCD_putword("Wrong code!\nCode: "); } //Lat larmet ga igang efter 20 sec if (get_timer()>20000 && (get_timer()%1000) ==0 && do_alarm) { speaker_sound(0xFFF, 100); } } void init_system(state_mode *state) { //Har initieras alla pinnar DDRD = 0xFF; DDRa = 0b11011111; //Displayen initsieras LCD_init(); //Initsiering av state_mode if ((int)eeprom_read_word(0xF0) < 0) { eeprom_write_word(0xF0, 1234); } if ((int)eeprom_read_word(0x05) < 0) { eeprom_write_word(0x05, 5); } if ((int)eeprom_read_word(0x07) < 0) { eeprom_write_word(0x07, 1000); } if ((int)eeprom_read_word(0x09) < 0) { eeprom_write_word(0x09, 1000); } state->armed = false; state->triggered = false; state->zerocounter = 0; state->micstate = 0; state->motion_threshold = eeprom_read_word(0x05); state->micstate_times[0] = eeprom_read_word(0x07); state->micstate_times[1] = eeprom_read_word(0x09); itoa(eeprom_read_word(0xF0), state->password, 10); check_password(state); do_alarm = false; } int main() { state_mode * state; state = (state_mode*)malloc(sizeof(state_mode)); init_system(state); while(1) { while(state->armed) { poll_while_armed(state); } if (!state->armed && !state->triggered) { LCD_putword("Standby mode"); while(!state->armed && !state->triggered) { poll_while_disarmed(state); } } if (state->triggered) { speaker_sound(0xaaa, 300); start_timer(); do_alarm = true; while(state->triggered) { poll_while_triggered(state); } } } }