// Author : Quentin BENETHUILLERE // Date of creation : 2021/03/27 // Last modification : 2021/04/27 /* * Program function(s): * The main purpose for the end user is to find a given access code set in this program. This access code represents a DNA sequence with letters A,C,T,G. * - 5 push buttons are available (1 push button per character (=4) + 1 erase button). * - A LCD displays the combination that user is currently typing. * - When the whole sequence has been entered (16 characters), the program will trigger different actions depending on whether the code is correct or not. * -> correct code : green LED ON + "Access Authorized" on the LCD for a few seconds * -> incorrect code : red LED ON + "Access Denied" on the LCD for a few seconds. */ //* ----------- //* LIBRAIRIES //* ----------- //#include // Library for LCD. #include // Library for debouncing push buttons. #include #include #include // ------------------------- // DECLARATION OF DEFINES // ------------------------- // ------------------------- // DECLARATION OF VARIABLES // ------------------------- const int debounce_delay = 10; // Delay used to debounce buttons (if button state change has been observed for this consecutive delay at least, then the state change is confirmed). const char code[17]="CTGGATACCAAGTACG"; // DNA sequence code to be found. [17] because character '\0' added at the end of a string input, and this avoid confusions when string comparison will be performed later. //const char code[17]="AAAAAAAAAAAAAAAA"; // For testing purposes, this code can be used instead. // ------------------------------------------------ // Adjustable variables (program main parameters) // ------------------------------------------------ // ------------------------------------------------ // PIN connections // ------------------------------------------------ const unsigned char PIN_LCD_rs = A0; // pin connected to LCD "Register Selection". Note: an analogic pin is used here but this is only because no more digital pin were available on the Arudino Uno. const unsigned char PIN_LCD_enable = A1; // pin connected to LCD "Enable". Note: an analogic pin is used here but this is only because no more digital pin were available on the Arudino Uno. const unsigned char PIN_LCD_d4 = 2; // pin connected to LCD "data 4". const unsigned char PIN_LCD_d5 = 3; // pin connected to LCD "data 5". const unsigned char PIN_LCD_d6 = 4; // pin connected to LCD "data 6". const unsigned char PIN_LCD_d7 = 13; // pin connected to LCD "data 7". const unsigned char PIN_LED_green = 6; // pin connected to green led anode. const unsigned char PIN_LED_red = 7; // pin connected to red led anode. const unsigned char PIN_buttons[5]={8,9,10,11,12}; // pins connected respectively to {PIN_button_A,PIN_button_C,PIN_button_T,PIN_button_G,PIN_button_erase}; const unsigned char buttons_letters[5]={'A','C','T','G','_'}; // ------------------------------------------------ // Other variables // ------------------------------------------------ char lcd_line_0[17] = "Access Code?"; // Message to be displayed on the first line of the LCD. char lcd_line_1[17] = "________________"; // Message to be displayed on the second line of the LCD. unsigned char button_A_state = 0; // variable to know whether button A is pushed (1) or not (0). unsigned char button_C_state = 0; // variable to know whether button C is pushed (1) or not (0). unsigned char button_T_state = 0; // variable to know whether button T is pushed (1) or not (0). unsigned char button_G_state = 0; // variable to know whether button G is pushed (1) or not (0). unsigned char button_erase_state = 0; // variable to know whether button Erase is pushed (1) or not (0). unsigned char input_position = 0; // variable to know the position of next user input in the sequence (corresponds basically to the column position the next input will be displayed in the LCD). // ------------------------- // DECLARATION OF OBJECTS // ------------------------- //LiquidCrystal lcd(PIN_LCD_rs,PIN_LCD_enable,PIN_LCD_d4,PIN_LCD_d5,PIN_LCD_d6,PIN_LCD_d7); // Declaration of a LiquidCrystal type object. LiquidCrystal_I2C lcd(0x27, 16, 2);// définit le type d'écran lcd pour ma part j'utilise un 16 x 2 Bounce2::Button button_A; // Declaration of push button A. Bounce2::Button button_C; // Declaration of push button C. Bounce2::Button button_T; // Declaration of push button T. Bounce2::Button button_G; // Declaration of push button G. Bounce2::Button button_erase; // Declaration of push button Erase. Bounce2::Button buttons[5]={button_A,button_C,button_T,button_G,button_erase}; // Declaration of push button A. Servo servo; // ------------------------- // INITIALIZATION // ------------------------- // Setup code. Run once at power up, or each time the RESET button is pressed: void setup() { // Initialization of the LCD object : //lcd.begin(16,2); lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(2,0); lcd.print(lcd_line_0); lcd.setCursor(0,1); lcd.print(lcd_line_1); // Initialization of push buttons objects, with debounce delay and state when pressed : for (unsigned char i=0; i<=4; i++){ buttons[i].attach(PIN_buttons[i]); buttons[i].interval(debounce_delay); buttons[i].setPressedState(HIGH); } servo.attach(5); servo.write(30); // ------------------------------------------------ // Input / Output // ------------------------------------------------ pinMode(PIN_LCD_rs, OUTPUT); pinMode(PIN_LCD_enable, OUTPUT); pinMode(PIN_LED_green, OUTPUT); pinMode(PIN_LED_red, OUTPUT); pinMode(PIN_LCD_d4, OUTPUT); pinMode(PIN_LCD_d5, OUTPUT); pinMode(PIN_LCD_d6, OUTPUT); pinMode(PIN_LCD_d7, OUTPUT); for (unsigned char i=0; i<=4; i++){ pinMode(PIN_buttons[i],INPUT); } // ------------------------------------------------ // PIN initial states // ------------------------------------------------ digitalWrite(PIN_LED_green,LOW); // green LED OFF. digitalWrite(PIN_LED_red,LOW); // red LED OFF. } // end of setup() function // ------------------------- // MAIN // ------------------------- // Loop function that runs repeatedly: void loop() { // Check push buttons state for each loop : for (unsigned char i=0; i<=4; i++){ buttons[i].update(); if (buttons[i].pressed()){ // If a button corresponding to a letter is pressed, then the letter is added to the sequence and displayed on the LCD. if (i!=4){ lcd_line_1[input_position]=buttons_letters[i]; lcd.setCursor(input_position,1); lcd.write(buttons_letters[i]); input_position=input_position+1; }// end if // If the erase button is pressed, the last character entered is erased and replaced by a "_" (only if there are still some characters to be erased). else{ if (input_position!=0){ lcd_line_1[input_position-1]=buttons_letters[i]; lcd.setCursor(input_position-1,1); lcd.write(buttons_letters[i]); input_position=input_position-1; }// end if }// end else } // end if } // end for // Once the number of characters expected (16) has been entered, the sequence entered is compared to the real code. Depending on the result, different actions occur. if (input_position==16){ code_verification(lcd_line_1,code); // Reinitialization of the variables and LCD display input_position=0; for (int i=0;i<16;i++){ lcd_line_1[i] = '_'; } // end for lcd.clear(); lcd.setCursor(2,0); lcd.print(lcd_line_0); lcd.setCursor(0,1); lcd.print(lcd_line_1); } // end if } // end of loop() function void code_verification(char char1[17], char char2[17]){ // If sequence matches the real code : if(strcmp(char1, char2) == 0){ digitalWrite(PIN_LED_green,HIGH); // green LED ON lcd.clear(); lcd.setCursor(5,0); lcd.print("Access"); lcd.setCursor(2,1); lcd.print("Authorized!"); servo.write(140); delay(5000); digitalWrite(PIN_LED_green,LOW); // green LED OFF servo.write(30); } // end if // If sequence does not match the real code : else{ digitalWrite(PIN_LED_red,HIGH); // red LED ON lcd.clear(); lcd.setCursor(5,0); lcd.print("Access"); lcd.setCursor(5,1); lcd.print("Denied!"); delay(3000); digitalWrite(PIN_LED_red,LOW); // red LED OFF } // end else } // end "code_verification" function