/* * keypad.c * * Created: 2022-05-13 12:34:20 * Author : ca4215be-s */ #define F_CPU 16000000UL #include #include #include #include int fill_entered(); // Fills code entering array with -1 int fill_correct(); // Fills code checking array with -1 void enter_digit(int enter); // Enters digit into enter array void enter_code(); // Checks state, either the checking code or entering code, uses functions such as checkCode and too_Short int checkCode(); // Compares checking array with enter array, returns true if code i correct int too_short(); // Checks if input into checking array is less than 4 elements, returns true if true void clear(); // Clears the checking array or the enter code array and LCD void lcd_data(unsigned char data); // Writes data to LCD void lcd_cmd(unsigned char command); // Sends a command code to LCD void stringwrite(unsigned char s[]); // Builds string to be printed on LCD void lcd_initialise(); // Initializes LCD void beep(); // beep void green(); // green void red(); // red int correct_code[16]; int entered_code[16]; static int choose_or_enter = 0; // States (0 = choose code), (1 = enter code) static int counter = 0; // Keeps track of next place in the code array where entered number is to be placed int main(void) { DDRB=0xFF; DDRA|=(1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<2); lcd_initialise(); sei(); // Initializes Interrupt function PCICR = 0b00001000; // chooses interrupt register bank (port D) PCMSK3 = 0b00000111; fill_correct(); // fills correct_code array with *s fill_entered(); // fills entered_code array with *s while(1) { } } ISR(PCINT3_vect) { // Interrupt-routine for button-push _delay_ms(30); if (PIND == 0b00001001) { stringwrite("1"); beep(); enter_digit(1); } else if (PIND == 0b00001010) { stringwrite("2"); beep(); enter_digit(2); } else if (PIND == 0b00001100) { stringwrite("3"); beep(); enter_digit(3); } else if (PIND == 0b00010001) { stringwrite("4"); beep(); enter_digit(4); } else if (PIND == 0b00010010) { stringwrite("5"); beep(); enter_digit(5); } else if (PIND == 0b00010100) { stringwrite("6"); beep(); enter_digit(6); } else if (PIND == 0b00100001) { stringwrite("7"); beep(); enter_digit(7); } else if (PIND == 0b00100010) { stringwrite("8"); beep(); enter_digit(8); } else if (PIND == 0b00100100) { stringwrite("9"); beep(); enter_digit(9); } else if (PIND == 0b01000010) { stringwrite("0"); beep(); enter_digit(0); } else if (PIND == 0b01000100) { enter_code(); } else if (PIND == 0b01000001) { beep(); clear(); beep(); } _delay_ms(40); } int fill_entered() { // 0 = correct_code, 1 = entered_code for (int k = 0; k<16; k++) { entered_code[k] = -1; } } int fill_correct() { // 0 = correct_code, 1 = entered_code for (int i = 0; i<16; i++) { correct_code[i] = -1; } } void enter_digit(int enter) { if (choose_or_enter == 0) { correct_code[counter] = enter; counter++; } else if (choose_or_enter == 1) { entered_code[counter] = enter; counter++; } } void enter_code() { lcd_cmd(0x01); if (choose_or_enter == 0) { // when choosing code if (too_short()) { lcd_cmd(0x80); stringwrite("Code too short,"); lcd_cmd(0xC0); stringwrite("enter code > 4"); _delay_ms(1500); clear(); } else { choose_or_enter = 1; lcd_cmd(0x80); stringwrite("Enter code:"); lcd_cmd(0xC0); counter = 0; } } else if (choose_or_enter == 1) { // when entering code if (checkCode()) { green(); lcd_cmd(0x80); stringwrite("Access Granted!"); lcd_cmd(0xC0); _delay_ms(1500); clear(); } else { red(); lcd_cmd(0x80); stringwrite("Access Denied!"); lcd_cmd(0xC0); _delay_ms(1500); clear(); } counter = 0; } } int checkCode() { if (entered_code[0] == -1){ return 0; } for (int i = 0; i<16; i++) { if (entered_code[i] != -1 && entered_code[i] != correct_code[i]) { return 0; } } return 1; } int too_short() { int counter1 = 0; for (int y = 0; y<16; y++) { if (correct_code[y] == -1) { break; } counter1++; } if (counter1 < 4) { return 1; } else { return 0; } } void clear() { lcd_cmd(0x01); if (choose_or_enter == 0) { lcd_cmd(0x80); stringwrite("Choose code:"); lcd_cmd(0xC0); fill_correct(); // fills correct_code array with -1 counter = 0; } else if (choose_or_enter == 1) { lcd_cmd(0x80); stringwrite("Enter code:"); lcd_cmd(0xC0); fill_entered(); // fills entered_code array with -1 counter = 0; } } void lcd_data(unsigned char data) { PORTB=data; PORTA|=(1<<0); PORTA|=(1<<1); _delay_ms(10); PORTA&=(~(1<<1)); _delay_ms(10); } void lcd_cmd(unsigned char command) { PORTB=command; PORTA &= ~(1<<0); PORTA |=(1<<1); _delay_ms(10); PORTA &=(~(1<<1)); _delay_ms(10); } void stringwrite(unsigned char s[]) { int i; for (i=0;s[i]!=0;i++) { lcd_data(s[i]); } } void lcd_initialise() { lcd_cmd(0x38); // 16x2 8-bit lcd_cmd(0x0C); // display on, cursor off lcd_cmd(0x06); // Auto Increment cursor lcd_cmd(0x01); // clear display lcd_cmd(0x02); // cursor at home position stringwrite("Choose Code:"); lcd_cmd(0xC0); } void beep() { PORTA|=(1<<3); _delay_ms(200); PORTA&=~(1<<3); } void red() { PORTA|=(1<<2); _delay_ms(200); PORTA&=~(1<<2); } void green() { PORTA|=(1<<4); _delay_ms(200); PORTA&=~(1<<4); }