2022_Projet_IOT-Surveillance_connectée
Dans l'objectif de sécuriser une salle de notre école, nous avons décidé de créer un dispositif permettant de réguler son accès et de répertorier les entrées et sorties dans un document en ligne consultable à tout moment. Pour ce faire, nous allons utiliser les puces RFID de nos cartes étudiantes pour pouvoir les scanner à l'entrée de la zone sensible. Aussi, nous allons mettre en place un système de surveilance vidéo qui intégrera de la reconnaissance faciale pour détecter le moindre intru.
Slides & Videos
Members
Name | Contribution |
---|---|
Ludovic DUVAL | Programmation du module RFID et de l'ESP-12F. Programmation de la réception et envoi des données sur le google sheet avec Google Apps Script. Recherche du matériel. |
Thibault FLORES | Recherche de l'état d'art. Recherche du matériel. Découverte et compréhension de librairies pour la programmation. Assistant pour la programmation du module RFID et de l'ESP-12F. Assistant pour la programmation du module caméra de l'ESP32-CAM. |
Aeneas RUS LIN | Programmation du module caméra de l'ESP32-CAM et mise en place du programme de reconnaissance faciale de l'ESP32-CAM. Câblage et soudage des différents modules du projet. Modélisation 3D et impression du boîtier. Organisation du travail et des tâches. |
State of the Art
Business Aspect
La reconnaissance faciale, nouvelle méthode de pointage
Il existe déjà de nombreux systèmes de ce type :
- Système de pointage à reconnaissance faciale. La plupart des technologies existantes se trouvent aux alentours de 500€, 300€ pour les entrées de gamme et jusqu’à 2500€ pour les matériels plus perfectionnés. Les applications dans le domaine professionnel sont nombreuses, notamment pour le pointage en entreprise. Les entreprises peuvent capturer, gérer et intégrer en toute sécurité les données de temps et de présence de leurs employés dans des systèmes de paie tels que ADP, QuickBooks, Paychex, etc., quand cela leur convient et de n’importe où via le Web. On les retrouve aussi dans les laboratoires et endroits aux accès sécurisés et contrôlés.
- Les avantages :
Technologie de reconnaissance faciale à toute épreuve pour identifier instantanément les employés
Alternative hygiénique sans contact aux lecteurs d’empreintes digitales et manuels.
Evite la triche, les employés ne peuvent pas pointer pour les autres
- Une caméra de surveillance à reconnaissance faciale. La technologie existe aussi et coûte entre 80€ et 400€. Elle est utilisée dans le domaine de la sécurité.
Cependant, notre problème est plus spécifique et nécessite une adaptation des systèmes. De plus, notre budget ne sera pas le même que les systèmes existants déjà.
Technical Aspect
ESP32-CAM Video Streaming and Face Recognition with Arduino IDE
Les principales techniques utilisées dans ce projet sont : -La vidéo surveillance avec reconnaissance faciale -La lecture de carte RFID -L’écriture en ligne. Afin de réaliser le système de surveillance, nous utilisons un lecteur de cartes RFID compatible Arduino, il a une portée de détection assez faible, ce qui le rend efficace pour la lecture de carte d’accès. On en retrouve différents types dans le commerce. Pour le domaine de la sécurité, le même type de lecteur est utilisé. Pour ce qui est de la caméra, nous utilisons un ESP32 CAM avec une caméra compatible. La résolution de la caméra est de 720p x 720 p, elle permet d’obtenir une image net, cependant il est possible d‘obtenir une image de meilleure qualité. Notre caméra fonctionne aussi par Wi-Fi. La plupart des systèmes de vidéo surveillance utilisent quant à eux des caméras de meilleure qualité. La plupart fonctionnent de manière filaire ce qui les rend plus difficiles à optimiser en matière de placement. L’utilisation d’Arduino permet une configuration efficace et spécifique. Dans le commerce, la plupart des installateurs utilisent leur propre logiciel ainsi que des PCB réalisés sur mesure. Il est difficile d’avoir davantage d’information à cause des normes de sécurité liées à ce domaine.
Project Description
Problem Definition
Challenges & Motivation
Dans un deuxième temps, nous souhaitons mettre en place un système de surveillance à l’intérieur de la zone via caméra. Ce système aura pour but d’enregistrer les activités, suspectes ou non à l’intérieur de la zone. L’objectif est d’identifier de potentiels intrus via reconnaissance faciale et de valider l’accès qui aura été donné par le système RFID. Si une personne passe la première barrière du système RFID mais a utilisé la carte d’un autre étudiant afin de passer, il sera filmé et identifié.
Le dernier objectif du système est de répertorier toutes les entrées et sorties dans la zone dans un tableau. On y stockera les identités des personnes ayant pénétré dans la zone ainsi que les horaires et les dates d'entrée et sortie. Les données seront exportées dans un document Google Sheet stocké en ligne et consultable à tout moment sur tout appareil connecté à internet avec les autorisations nécessaires.
Real and Complete Usecases
Le système d’accès : dans un premier temps, nous allons essayer d’identifier les étudiants grâce aux puces RFID contenues dans les cartes étudiantes. Celles-ci possèdent aussi un code barre que l’on peut scanner dans le cas où la méthode RFID ne fonctionnerait pas. Lorsque l’individu est reconnu par le système en tant que personne autorisée, la barrière permettant l’accès à la zone s’ouvre pour laisser passer la personne. On pourra ainsi savoir qui utilise la zone et quand ces personnes y entrent et en sortent. Ces données seront enregistrées dans un fichier excel sur le Google Drive du BDE. Le système de surveillance : il s’applique à la zone derrière le bar de la salle où se trouvent les biens. Il a pour but de sonner une alarme ainsi que d’enregistrer l’apparence et les actions d’un intrus lorsqu’il pénètre dans cette zone. L’observation est réalisée à l’aide d’une caméra qui est toujours allumée mais qui enregistre que quand une personne est dans la zone. Pour savoir si une personne est autorisée ou non, on utilise un système de reconnaissance faciale. Si la reconnaissance faciale ne correspond pas aux données renvoyées par le système d’accès, la personne sera considérée comme intrus.
Technical Description
Afin de réaliser ce projet, nous avons mis en commun nos différentes qualités. Nous avons utilisé l’ensemble des connaissances propres à chacun. Ces connaissances viennent à la fois de projets personnels, de notre enseignement académique, mais aussi de la documentation sur internet. Nous avons utilisé nos skills dans le domaine de l’électronique afin de mettre en place les connectiques entre les différents éléments de notre système. Nous avons mis en avant nos apprentissages sur l’environnement de développement Arduino. Nous avons utilisé nos enseignements pour les mettre à profit de ce projet.
Nous avons aussi utilisé nos compétences en design 3D afin de créer un boitier compact et fonctionnel. Il a été indispensable de trouver quelqu’un dans le groupe avec un bon esprit de leadership, c’est pourquoi un chef de projet est indispensable pour le bon fonctionnement du groupe. Nous avons appris à utiliser les différents outils de GOOGLE plus en détails tels que les googlent sheets et GOOGLE app script pour les faire communiquer avec notre système de surveillance.
Hardware
Materials
Schematic
Software
Arduino Code
var ss = SpreadsheetApp.openById('17J4FlfJIhlSSz_mlQSM4RuHyEAhmnrKBzPVJw6mSPEk'); var sheet = ss.getSheetByName('Sheet1'); var timezone = "Europe/Paris" //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM function doGet(e){ Logger.log( JSON.stringify(e) ); //---------------------------------------------------------------------------------- //write_google_sheet() function in esp32 sketch, is send data to this code block //---------------------------------------------------------------------------------- //get gps data from ESP32 if (e.parameter == 'undefined') { return ContentService.createTextOutput("Received data is undefined"); } //---------------------------------------------------------------------------------- var Curr_Date = new Date(); var Curr_Time = Utilities.formatDate(Curr_Date, timezone, 'HH:mm:ss'); var name = stripQuotes(e.parameters.name); //Logger.log('name=' + name); //---------------------------------------------------------------------------------- var nextRow = sheet.getLastRow() + 1; sheet.getRange("A" + nextRow).setValue(Curr_Date); sheet.getRange("B" + nextRow).setValue(Curr_Time); sheet.getRange("C" + nextRow).setValue(name); //---------------------------------------------------------------------------------- //returns response back to ESP32 return ContentService.createTextOutput("Card holder name is stored in column C"); //---------------------------------------------------------------------------------- } //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM function stripQuotes( value ) { return value.toString().replace(/^["']|['"]$/g, ""); } //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM //Extra Function. Not used in this project. //planning to use in future projects. //this function is used to handle POST request function doPost(e) { var val = e.parameter.value; if (e.parameter.value !== undefined){ var range = sheet.getRange('A2'); range.setValue(val); } } //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
#include "esp_camera.h" #include// // WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality // 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" const char* ssid = "Ananas"; const char* password = "catbread"; void startCameraServer(); void setup() { 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.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); startCameraServer(); Serial.print("Camera Ready! Use 'http://"); Serial.print(WiFi.localIP()); Serial.println("' to connect"); } void loop() { // put your main code here, to run repeatedly: }
#include#include #include #include #include #include #include #include #include //----------------------------------------- #define RST_PIN D3 #define SS_PIN D4 #define BUZZER D2 //----------------------------------------- /* Be aware of Sector Trailer Blocks */ int blockNum = 2; /* Create another array to read data from Block */ /* Legthn of buffer should be 2 Bytes more than the size of Block (16 Bytes) */ byte bufferLen = 18; byte readBlockData[18]; //----------------------------------------- String card_holder_name; const String sheet_url = "https://script.google.com/macros/s/AKfycbyHFGk0PHcxqFmBRMBD_O6_JbHDj3dP6UwSV5YvHr2V9sOT8ScuJ3dS1H8f1A77Jpml/exec?name="; //----------------------------------------- // Fingerprint for demo URL, expires on Monday, May 2, 2022 7:20:58 AM, needs to be updated well before this date // 0x9a, 0x71, 0xde, 0xe7, 0x1a, 0xb2, 0x25, 0xca, 0xb4, 0xf2, 0x36, 0x49, 0xab, 0xce, 0xf6, 0x25, 0x62, 0x04, 0xe4, 0x3c const uint8_t fingerprint[20] = {0x9a, 0x71, 0xde, 0xe7, 0x1a, 0xb2, 0x25, 0xca, 0xb4, 0xf2, 0x36, 0x49, 0xab, 0xce, 0xf6, 0x25, 0x62, 0x04, 0xe4, 0x3c}; //----------------------------------------- #define WIFI_SSID "Ananas" #define WIFI_PASSWORD "catbread" //----------------------------------------- MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class MFRC522::MIFARE_Key key; String tag; int attente = 2000; int valid = 0; int i,j; int UID_receive[4]; char* UID_c; char* identite; #define NB_max 10 int UID_ref[NB_max][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; char* liste_identite[NB_max] = {"User1","User2","User3","User4","User5","User6","User7","User8","User9","User10"}; int admin[4] = {162,80,234,26}; int NB_id = 0; int UID_equals(int* a, int* b){ for(int k = 0; k < 4; k++){ if (a[k] != b[k]) return 0; } return 1; } #define LED_BLEUE D0 #define LED_VERTE D1 #define LED_ROUGE D8 /**************************************************************************************************** * setup() function ****************************************************************************************************/ void setup() { pinMode(LED_BLEUE, OUTPUT); pinMode(LED_VERTE, OUTPUT); pinMode(LED_ROUGE, OUTPUT); digitalWrite(LED_BLEUE, LOW); digitalWrite(LED_VERTE, LOW); digitalWrite(LED_ROUGE, LOW); //-------------------------------------------------- /* Initialize serial communications with the PC */ Serial.begin(9600); //Serial.setDebugOutput(true); //-------------------------------------------------- //WiFi Connectivity Serial.println(); Serial.print("Connecting to AP"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED){ Serial.print("."); delay(200); } Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println(); //-------------------------------------------------- /* Set BUZZER as OUTPUT */ pinMode(BUZZER, OUTPUT); //-------------------------------------------------- /* Initialize SPI bus */ SPI.begin(); rfid.PCD_Init(); // Init MFRC522 //-------------------------------------------------- } /**************************************************************************************************** * loop() function ****************************************************************************************************/ void loop() { //Serial.printf(".\n"); //Serial.printf("###################\n"); if ( ! rfid.PICC_IsNewCardPresent()) return; //Serial.printf("........\n"); if (rfid.PICC_ReadCardSerial()) { for (i = 0; i < 4; i++) { UID_receive[i] = rfid.uid.uidByte[i]; } if(UID_equals(admin, UID_receive)){ if (NB_id == NB_max - 1){ Serial.printf("Nombre maximal d'utilisateurs atteint !\n"); }else{ digitalWrite(LED_VERTE, HIGH); Serial.printf("Patientez 5s\n"); delay(1000); Serial.printf("Patientez 4s\n"); delay(1000); Serial.printf("Patientez 3s\n"); delay(1000); Serial.printf("Patientez 2s\n"); delay(1000); Serial.printf("Patientez 1s\n"); delay(1000); digitalWrite(LED_VERTE, LOW); digitalWrite(LED_BLEUE, HIGH); Serial.printf("Scannez le nouvelle utilisateur.\n"); while(! rfid.PICC_IsNewCardPresent()); if (rfid.PICC_ReadCardSerial()) { for (i = 0; i < 4; i++) { UID_receive[i] = rfid.uid.uidByte[i]; } } for (i = 0; i < 4; i++) { UID_ref[NB_id][i] = UID_receive[i]; } NB_id++; Serial.printf("La carte est enregistrée !\n"); delay(1000); digitalWrite(LED_BLEUE, LOW); } }else{ //Serial.printf("..........................\n"); for(i=0;i client(new BearSSL::WiFiClientSecure); //------------------------------------------------------------------------------- client->setFingerprint(fingerprint); // Or, if you want to ignore the SSL certificate //then use the following line instead: // client->setInsecure(); //----------------------------------------------------------------- card_holder_name = sheet_url + identite; card_holder_name.trim(); Serial.println(card_holder_name); //----------------------------------------------------------------- HTTPClient https; Serial.print(F("[HTTPS] begin...\n")); //----------------------------------------------------------------- //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN if (https.begin(*client, (String)card_holder_name)){ //----------------------------------------------------------------- // HTTP Serial.print(F("[HTTPS] GET...\n")); // start connection and send HTTP header int httpCode = https.GET(); //----------------------------------------------------------------- // httpCode will be negative on error if (httpCode > 0) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTPS] GET... code: %d\n", httpCode); // file found at server } //----------------------------------------------------------------- else {Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());} //----------------------------------------------------------------- https.end(); delay(1000); } //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN else { Serial.printf("[HTTPS} Unable to connect\n"); } //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN } digitalWrite(LED_VERTE, LOW); //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM }else{ digitalWrite(LED_ROUGE, HIGH); Serial.printf("Personne non reconnue !\n"); delay(2000); digitalWrite(LED_ROUGE, LOW); } } } valid = 0; i = 0; rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); //Serial.printf("........................................................\n"); }
External Services
C’est sur ce document en ligne que nous envoyons les données d’entrée et sortie dans la zone protégée. On récupère notamment l’identifiant des personnes autorisées à entrer dans la zone au moment où elles scannent leur carte étudiante.
C’est grâce à cette application que nous pouvons recevoir les données de l’arduino et les transférer sur le Google Sheet.