This shows you the differences between two versions of the page.
pm:prj2023:avaduva:faceid_security_system [2023/05/06 20:15] razvan.uleia |
pm:prj2023:avaduva:faceid_security_system [2023/05/29 20:09] (current) razvan.uleia |
||
---|---|---|---|
Line 2: | Line 2: | ||
by Uleia Răzvan-Alexandru | by Uleia Răzvan-Alexandru | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | |||
- | <note tip> | ||
- | Prezentarea pe scurt a proiectului vostru: | ||
- | * ce face | ||
- | * care este scopul lui | ||
- | * care a fost ideea de la care aţi pornit | ||
- | * de ce credeţi că este util pentru alţii şi pentru voi | ||
- | </note> | ||
The **FaceId Security System** is based on recognizing the user's face and unlocking the lock if the face matches. If the system fails to recognize the face 3 times, then the user will be directed to introduce the pin manually to be able to unlock the lock. | The **FaceId Security System** is based on recognizing the user's face and unlocking the lock if the face matches. If the system fails to recognize the face 3 times, then the user will be directed to introduce the pin manually to be able to unlock the lock. | ||
- | ===== Descriere generală ===== | + | ===== General Description ===== |
- | {{:pm:prj2023:avaduva:block_diagram.png?200|}} | + | The user will put his face within the camera reach. Firstly, the user will be asked to introduce a PIN to secure the lock. The ESP32-CAM will detect the user's face, and the user is able to add his face to the camera's feed. After this the lock will be activated. If the user wants to unlock the specific lock, he just has to put his face in the camera such that it will detect and recognize it. If somehow there is a software error and the face cannot be recognized, the user will be asked to introduce the PIN he just created to be able to unlock it. |
- | <note tip> | + | |
- | O schemă bloc cu toate modulele proiectului vostru, atât software cât şi hardware însoţită de o descriere a acestora precum şi a modului în care interacţionează. | + | |
- | Exemplu de schemă bloc: http://www.robs-projects.com/mp3proj/newplayer.html | + | {{:pm:prj2023:avaduva:block_diagram-faceid_security.png?800|}} |
- | </note> | + | |
===== Hardware Design ===== | ===== Hardware Design ===== | ||
Line 32: | Line 21: | ||
* 7805 Regulator | * 7805 Regulator | ||
* Display LCD 2x16 | * Display LCD 2x16 | ||
+ | * 4x4 Keypad | ||
+ | |||
+ | *this is not the final version, I will upload more irl pictures as soon as I get my wires delivered* | ||
+ | {{:pm:prj2023:avaduva:schemadiagram.png?800|}} | ||
+ | |||
+ | |||
+ | {{:pm:prj2023:avaduva:enterpasskeypad_.png?350|}}{{:pm:prj2023:avaduva:enternewpass.png?350|}} | ||
+ | {{:pm:prj2023:avaduva:passwordchanged.png?350|}} | ||
+ | {{:pm:prj2023:avaduva:accessdenied.png?350|}} | ||
Line 38: | Line 36: | ||
- | <note tip> | + | <code> |
- | Descrierea codului aplicaţiei (firmware): | + | #include "esp_camera.h" |
- | * mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR) | + | #include <WiFi.h> |
- | * librării şi surse 3rd-party (e.g. Procyon AVRlib) | + | #include <ESPAsyncWebSrv.h> |
- | * algoritmi şi structuri pe care plănuiţi să le implementaţi | + | // |
- | * (etapa 3) surse şi funcţii implementate | + | // WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality |
- | </note> | + | // Ensure ESP32 Wrover Module or other board with PSRAM is selected |
+ | // Partial images will be transmitted if image exceeds buffer size | ||
+ | // | ||
+ | |||
+ | // Select camera model | ||
+ | //#define CAMERA_MODEL_WROVER_KIT // Has PSRAM | ||
+ | //#define CAMERA_MODEL_ESP_EYE // Has PSRAM | ||
+ | //#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM | ||
+ | //#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM | ||
+ | //#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM | ||
+ | //#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM | ||
+ | #define CAMERA_MODEL_AI_THINKER // Has PSRAM | ||
+ | //#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM | ||
+ | |||
+ | #include "camera_pins.h" | ||
+ | |||
+ | #define output 2 | ||
+ | |||
+ | const char* ssid = "your_SSID"; | ||
+ | const char* password = "your_PASSWORD"; | ||
+ | AsyncWebServer server(8080); | ||
+ | void startCameraServer(); | ||
+ | |||
+ | |||
+ | bool activateRelay = false; | ||
+ | bool isFaceDetected = false; | ||
+ | unsigned long prevMillis=0; | ||
+ | unsigned long currentMillis; | ||
+ | int interval = 5000; | ||
+ | |||
+ | void setup() { | ||
+ | |||
+ | pinMode(output, OUTPUT); | ||
+ | prevMillis = 0; | ||
+ | |||
+ | Serial.begin(115200); | ||
+ | Serial.setDebugOutput(true); | ||
+ | Serial.println(); | ||
+ | |||
+ | |||
+ | camera_config_t config; | ||
+ | config.ledc_channel = LEDC_CHANNEL_0; | ||
+ | config.ledc_timer = LEDC_TIMER_0; | ||
+ | config.pin_d0 = Y2_GPIO_NUM; | ||
+ | config.pin_d1 = Y3_GPIO_NUM; | ||
+ | config.pin_d2 = Y4_GPIO_NUM; | ||
+ | config.pin_d3 = Y5_GPIO_NUM; | ||
+ | config.pin_d4 = Y6_GPIO_NUM; | ||
+ | config.pin_d5 = Y7_GPIO_NUM; | ||
+ | config.pin_d6 = Y8_GPIO_NUM; | ||
+ | config.pin_d7 = Y9_GPIO_NUM; | ||
+ | config.pin_xclk = XCLK_GPIO_NUM; | ||
+ | config.pin_pclk = PCLK_GPIO_NUM; | ||
+ | config.pin_vsync = VSYNC_GPIO_NUM; | ||
+ | config.pin_href = HREF_GPIO_NUM; | ||
+ | config.pin_sscb_sda = SIOD_GPIO_NUM; | ||
+ | config.pin_sscb_scl = SIOC_GPIO_NUM; | ||
+ | config.pin_pwdn = PWDN_GPIO_NUM; | ||
+ | config.pin_reset = RESET_GPIO_NUM; | ||
+ | config.xclk_freq_hz = 20000000; | ||
+ | config.pixel_format = PIXFORMAT_JPEG; | ||
+ | |||
+ | // if PSRAM IC present, init with UXGA resolution and higher JPEG quality | ||
+ | // for larger pre-allocated frame buffer. | ||
+ | if(psramFound()){ | ||
+ | config.frame_size = FRAMESIZE_UXGA; | ||
+ | config.jpeg_quality = 10; | ||
+ | config.fb_count = 2; | ||
+ | } else { | ||
+ | config.frame_size = FRAMESIZE_SVGA; | ||
+ | config.jpeg_quality = 12; | ||
+ | config.fb_count = 1; | ||
+ | } | ||
+ | |||
+ | #if defined(CAMERA_MODEL_ESP_EYE) | ||
+ | pinMode(13, INPUT_PULLUP); | ||
+ | pinMode(14, INPUT_PULLUP); | ||
+ | #endif | ||
+ | |||
+ | // camera init | ||
+ | esp_err_t err = esp_camera_init(&config); | ||
+ | if (err != ESP_OK) { | ||
+ | Serial.printf("Camera init failed with error 0x%x", err); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | sensor_t * s = esp_camera_sensor_get(); | ||
+ | // initial sensors are flipped vertically and colors are a bit saturated | ||
+ | if (s->id.PID == OV3660_PID) { | ||
+ | s->set_vflip(s, 1); // flip it back | ||
+ | s->set_brightness(s, 1); // up the brightness just a bit | ||
+ | s->set_saturation(s, -2); // lower the saturation | ||
+ | } | ||
+ | // drop down frame size for higher initial frame rate | ||
+ | s->set_framesize(s, FRAMESIZE_QVGA); | ||
+ | |||
+ | #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM) | ||
+ | s->set_vflip(s, 1); | ||
+ | s->set_hmirror(s, 1); | ||
+ | #endif | ||
+ | |||
+ | |||
+ | WiFi.softAP(ssid, password); | ||
+ | IPAddress apIP = WiFi.softAPIP(); | ||
+ | Serial.print("Access Point IP address: "); | ||
+ | Serial.println(apIP); | ||
+ | server.begin(); | ||
+ | |||
+ | startCameraServer(); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | |||
+ | // Serial.println(isFaceDetected); | ||
+ | delay(2000); | ||
+ | |||
+ | //Serial.println(isFaceDetected); | ||
+ | delay(2000); | ||
+ | currentMillis = millis(); | ||
+ | if(isFaceDetected==true) | ||
+ | { | ||
+ | activateRelay=true; | ||
+ | if ((currentMillis - prevMillis >= interval) && activateRelay == true){ | ||
+ | digitalWrite(output,LOW); | ||
+ | delay(2000); | ||
+ | prevMillis = currentMillis; | ||
+ | activateRelay=false; | ||
+ | isFaceDetected=false; | ||
+ | delay(2000); | ||
+ | } | ||
+ | digitalWrite(output, HIGH); | ||
+ | |||
+ | |||
+ | |||
+ | /* if (isFaceDetected == true) { | ||
+ | // Activate the relay by setting the relay pin to HIGH | ||
+ | delay(2000); | ||
+ | digitalWrite(output, LOW); | ||
+ | delay(2000); | ||
+ | } else { | ||
+ | // Deactivate the relay by setting the relay pin to LOW | ||
+ | dleay(2000); | ||
+ | digitalWrite(output, HIGH); | ||
+ | delay(2000); | ||
+ | }*/ | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | This is the code for the camera to work. I have used the "CameraWebServer" example as a guiding point and I have done the necessary modifications. | ||
+ | |||
+ | In it, I have modified the "httpds.cpp" file so that when the ESP32-CAM detects my face, it will send a message in the Serial. The message from the Serial is read by Arduino Uno through connecting it to the RXD and TXD pins of the ESP32-CAM. The message sends a voltage through the Relay Module and the Relay Module Opens the 12V Solenoid Lock making it open. | ||
+ | |||
+ | <code> | ||
+ | const int relayPin = 10; | ||
+ | |||
+ | #include <Keypad.h> | ||
+ | #include <Wire.h> | ||
+ | #include <LiquidCrystal_I2C.h> | ||
+ | #include <EEPROM.h> | ||
+ | |||
+ | |||
+ | const byte ROWS = 4; | ||
+ | const byte COLS = 4; | ||
+ | |||
+ | char keys[COLS][ROWS] = { | ||
+ | {'1', '2', '3', 'A'}, | ||
+ | {'4', '5', '6', 'B'}, | ||
+ | {'7', '8', '9', 'C'}, | ||
+ | {'*', '0', '#', 'D'} | ||
+ | }; | ||
+ | |||
+ | byte rowPins[ROWS] = {2,3,4,5}; | ||
+ | byte colPins[COLS] = {6,7,8,9}; | ||
+ | |||
+ | Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); | ||
+ | |||
+ | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); | ||
+ | char password[5]; // Default password | ||
+ | char enteredPassword[5]; // Entered password | ||
+ | bool changeMode = false; | ||
+ | bool passwordChanged = false; | ||
+ | |||
+ | const int passwordAddress = 0; | ||
+ | |||
+ | void setup() { | ||
+ | // Initialize the serial communication | ||
+ | Serial.begin(115200); | ||
+ | lcd.begin(16, 2); // Initialize the LCD | ||
+ | lcd.clear(); // Clear the LCD screen | ||
+ | |||
+ | lcd.print("Hello User"); // Display initial message on LCD | ||
+ | delay(2000); | ||
+ | lcd.clear(); | ||
+ | lcd.print("Enter password:"); | ||
+ | |||
+ | // Set the relay pin as an output | ||
+ | pinMode(relayPin, OUTPUT); | ||
+ | digitalWrite(relayPin, HIGH); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | // Check if there are any incoming serial messages | ||
+ | if (Serial.available()) { | ||
+ | // Read the incoming message | ||
+ | char message = Serial.read(); | ||
+ | delay(2000); | ||
+ | Serial.println(message); | ||
+ | // Check if the message indicates a face detection | ||
+ | if (message == 'q' ) { | ||
+ | Serial.println("Triggering Relay"); | ||
+ | // Trigger the relay module by setting the relay pin high | ||
+ | digitalWrite(relayPin, LOW); | ||
+ | delay(5000); // Keep the relay activated for 1 second | ||
+ | digitalWrite(relayPin, HIGH); // Turn off the relay | ||
+ | } | ||
+ | } | ||
+ | |||
+ | char key = keypad.getKey(); // Get the pressed key | ||
+ | |||
+ | if (key != NO_KEY) { // If a key is pressed | ||
+ | if (key == 'A') { // Enter password change mode | ||
+ | lcd.clear(); | ||
+ | lcd.print("Enter new pass:"); | ||
+ | changeMode = true; | ||
+ | } else if (key == 'D') { // Verify entered password | ||
+ | if (changeMode) { | ||
+ | lcd.clear(); | ||
+ | lcd.print("Password changed"); | ||
+ | delay(2000); | ||
+ | lcd.clear(); | ||
+ | lcd.print("Verify it:"); | ||
+ | changeMode = false; | ||
+ | EEPROM.put(passwordAddress, password); // Store the new password in EEPROM | ||
+ | } else { | ||
+ | EEPROM.get(passwordAddress, password); // Retrieve the password from EEPROM | ||
+ | if (strcmp(enteredPassword, password) == 0) { | ||
+ | lcd.clear(); | ||
+ | lcd.print("Access granted"); | ||
+ | digitalWrite(relayPin, LOW); | ||
+ | delay(5000); // Keep the relay activated for 1 second | ||
+ | digitalWrite(relayPin, HIGH); // Turn off the relay | ||
+ | } else { | ||
+ | lcd.clear(); | ||
+ | lcd.print("Access denied"); | ||
+ | } | ||
+ | delay(2000); | ||
+ | lcd.clear(); | ||
+ | lcd.print("Enter password:"); | ||
+ | memset(enteredPassword, 0, sizeof(enteredPassword)); // Clear entered password | ||
+ | } | ||
+ | } else { // Append entered digit to password | ||
+ | if (changeMode) { | ||
+ | lcd.setCursor(strlen(enteredPassword), 1); // Set cursor position to the end of entered password | ||
+ | lcd.print(''); // Display "" instead of entered digits | ||
+ | strcat(enteredPassword, &key); | ||
+ | strcpy(password, enteredPassword); // Update the password array when a new password is entered | ||
+ | } else { | ||
+ | lcd.setCursor(strlen(enteredPassword), 1); // Set cursor position to the end of entered password | ||
+ | lcd.print(''); // Display "" instead of entered digits | ||
+ | strcat(enteredPassword, &key); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | This is the code that allows the Relay Module to be actioned by the KeyPad aswell | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
Line 74: | Line 341: | ||
</note> | </note> | ||
- | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | + | <html> |
+ | <a href="https://ocw.cs.pub.ro/courses/pm/prj2023/avaduva/faceid_security_system"> Link to project page </a> | ||
+ | <a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a> | ||
+ | </html> | ||