Dans ce projet, vous construirez un système de gestion des utilisateurs de code QR avec un serveur Web qui s’exécute sur un ESP32-cam. L’ESP32-CAM utilise constamment son appareil photo pour rechercher de nouveaux codes QR à l’aide de la bibliothèque ESP32QRCODEREReader et une version modifiée de la bibliothèque Quirc. Lorsqu’il détecte un code QR valide, il stocke les données de code QR sur la carte microSD. Vous pouvez accéder au serveur Web dans n’importe quel navigateur pour gérer les utilisateurs et afficher le journal complet. L’ESP32-CAM sera programmé à l’aide d’Arduino IDE.

Aperçu du projet
Le diagramme suivant montre un aperçu de haut niveau du fonctionnement du projet.

1) Lorsque l’ESP32-CAM détecte un code QR valide, il lit ses données et le flash LED intégré clignote.
2) L’ESP32-CAM enregistre l’heure de cette interaction et enregistre les données de code et de code QR sur la carte microSD sur un fichier appelé log.txt.
3) L’ESP32-CAM héberge également un serveur Web pour afficher et gérer les informations de la carte microSD.
4) L’URL root (/) affiche le journal complet (enregistré sur le journal du module de carte microSD.TXT) avec l’horodatage et les données de code QR.
5) Il y a une autre page sur le chemin / add-user qui vous permet d’ajouter des utilisateurs et leurs rôles à l’aide d’un formulaire.
6) Les données entrées via ce formulaire seront enregistrées sur le fichier user.txt enregistré sur la carte microSD.
7) Il existe une autre page sur le chemin / manage des utilisateurs qui vous permet de consulter et de supprimer les utilisateurs.
8) Cette page vous permet d’interagir avec le fichier users.txt.
Pièces requises
Nous utiliserons la carte ESP32-CAM étiquetée comme module AI-Thinker, mais d’autres modules devraient également fonctionner en effectuant la bonne affectation de broches dans le code. La carte ESP32-CAM est un appareil à 9 $ (ou moins) qui combine une puce ESP32-S, une caméra OV2640, une fente de carte microSD et plusieurs broches GPIO.

Pour suivre ce tutoriel, vous avez besoin des composants suivants:
Si vous utilisez une carte de caméra ESP32 sans prise en charge de la carte microSD, vous avez également besoin d’un module de carte microSD:
Vous pouvez utiliser les liens précédents ou aller directement à makeradvisor.com/tools pour trouver toutes les pièces de vos projets au meilleur prix!

Pour une introduction à l’ESP32-cam, vous pouvez suivre les prochains tutoriels:
Préparation de l’IDE Arduino
Nous allons programmer la carte ESP32 à l’aide d’Arduino IDE. Vous avez donc besoin de l’ide Arduino installée ainsi que du module complémentaire ESP32. Vous pouvez suivre le prochain tutoriel pour installer le module complémentaire ESP32, si vous ne l’avez pas déjà fait:
Installation de la bibliothèque ESP32QRCODEREReader
Pour ce tutoriel, nous utiliserons la bibliothèque ESP32QRCODEREReader par Alvarowolfx, ce qui facilite la lecture des codes QR avec la carte ESP32-CAM.
Ensuite, dans l’ide Arduino, allez dans Sketch> Inclure la bibliothèque> Ajouter une bibliothèque .zip et installer la bibliothèque que vous venez de télécharger dans le lien précédent.

Installation des bibliothèques de serveurs Web asynchrones
Nous allons créer le serveur Web à l’aide des bibliothèques suivantes:
Vous pouvez installer ces bibliothèques dans le gestionnaire de bibliothèque Arduino. Ouvrez le gestionnaire de bibliothèque en cliquant sur l’icône de la bibliothèque dans la barre latérale gauche.
Recherchez EspasyncWebserver et installez le EspasyncWerver par ESP32Async.

Ensuite, installez la bibliothèque AsyncTCP. Recherchez ASYNCTCP et installez l’ASYNCTCP par ESP32Async.

Plugin de téléchargeur Littlefs
Les fichiers utilisés pour créer le serveur Web seront enregistrés sur le système de fichiers ESP32 LITTHFS. Assurez-vous que le plugin Littlefs Téléchargeur est installé dans votre IDE Arduino. Vous pouvez suivre ce tutoriel:
Préparer la carte microSD
Avant de poursuivre le tutoriel, assurez-vous de formater votre carte microSD en tant que FAT32. Suivez les instructions suivantes pour formater votre carte microSD ou utiliser un outil logiciel comme le formateur de carte SD (compatible avec Windows et Mac OS).
1. Insérez la carte microSD dans votre ordinateur. Allez sur mon ordinateur et cliquez avec le bouton droit sur la carte SD. Sélectionnez le format comme indiqué dans la figure ci-dessous.

2. Une nouvelle fenêtre apparaît. Sélectionnez FAT32, appuyez sur Démarrer pour initialiser le processus de formatage et suivez les instructions à l’écran.

Fixez la carte microSD à l’ESP32-cam:

Pour apprendre à utiliser la carte microSD avec l’ESP32-cam, vous pouvez lire le prochain tutoriel:
Organiser vos fichiers
Pour garder le projet organisé et faciliter la compréhension, nous créerons 6 fichiers pour créer le serveur Web:
- Sketch Arduino: pour gérer le serveur Web, le lecteur de code QR et la carte microSD;
- full-log.html: charge le journal de chaque code QR qui a été analysé avec succès et ses données utilisateur;
- manage-users.html: page Web qui vous permet d’afficher et de supprimer les utilisateurs;
- Add-user.html: page Web qui vous permet d’ajouter de nouveaux utilisateurs avec un code QR unique;
- get.html: gère toutes les demandes de GET HTTP;
- style.css: pour styliser la page Web.

Vous devez enregistrer les fichiers HTML et CSS dans un dossier appelé Data dans le dossier Arduino Sketch, comme indiqué dans le diagramme précédent. Nous téléchargerons ces fichiers sur le système de fichiers ESP32-CAM (LITTHFS).
Vous pouvez télécharger tous les fichiers du projet:
Fichiers html
Copiez ce qui suit dans le fichier complet.html.
Manage Users
🗑️ Delete log.txt File
Afficher le code brut
Copiez ce qui suit dans le fichier manage-users.html.
Manage Users
🗑️ Delete users.txt File
Afficher le code brut
Copiez ce qui suit dans le fichier add-user.html.
Add User
➕ Add User
Enter the QR Code data.
Afficher le code brut
Copiez ce qui suit dans le fichier get.html.
Add User
Afficher le code brut
Fichier CSS
Copiez ce qui suit dans le fichier style.css. N’hésitez pas à le modifier pour que la page Web ait l’air comme vous le souhaitez.
/* General Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
color: #333;
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
margin: 0;
}
/* Navigation Bar Styles */
nav {
width: 100%;
background-color: #333;
padding: 1rem 0;
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 1rem;
}
.brand {
color: #fff;
text-decoration: none;
font-size: 1.5rem;
font-weight: bold;
}
.nav-menu {
list-style-type: none;
display: flex;
}
.nav-menu li {
margin-left: 1.5rem;
}
.nav-menu a {
color: #fff;
text-decoration: none;
font-size: 1rem;
transition: color 0.3s;
}
.nav-menu a:hover, .nav-menu a.active {
color: #f4f4f9;
}
.main-container {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
width: 100%;
}
.main-section {
max-width: 900px;
padding: 2rem;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
text-align: center;
}
.main-section h2 {
margin-bottom: 1rem;
color: #333;
}
.user-form label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
color: #333;
}
.user-form input, .user-form select {
width: 100%;
padding: 0.5rem;
margin-bottom: 1rem;
border: 1px solid #ddd;
border-radius: 4px;
}
.user-form button {
width: 100%;
padding: 0.7rem;
background-color: #333;
color: #fff;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
.user-form button:hover {
background-color: #555;
}
.button {
display: inline-block;
padding: 10px 20px;
margin: 10px;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
transition-duration: 0.4s;
}
.button-delete {
background-color: #780320;
color: #fff;
}
.button-home {
background-color: #333;
color: #fff;
}
#tableData {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 100%;
}
#tableData td, #tableData th {
border: 1px solid #ddd;
padding: 8px;
}
#tableData tr:nth-child(even) {
background-color: #f2f2f2;
}
#tableData tr:hover {
background-color: #ddd;
}
#tableData th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #1f1f1f;
color: white;
}
Afficher le code brut
Code – ESP32-CAM QR Code Reader Server Web
Copiez le code du lecteur de code QR sur votre IDE Arduino.
/*********
Rui Santos & Sara Santos - Raspberryme.com
Complete instructions at https://Raspberryme.com/esp32-cam-qr-code-reader-web-server/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include
#include
#include
#include
#include
#include "FS.h"
#include "SD_MMC.h"
#include
#include
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// FOR THIS PROJECT, YOUR ESP32-CAM NEEDS TO HAVE PSRAM.
// Some of the compatible boards: CAMERA_MODEL_AI_THINKER | CAMERA_MODEL_WROVER_KIT | CAMERA_MODEL_ESP_EYE
// CAMERA_MODEL_M5STACK_PSRAM | CAMERA_MODEL_M5STACK_V2_PSRAM | CAMERA_MODEL_M5STACK_WIDE
ESP32QRCodeReader reader(CAMERA_MODEL_AI_THINKER);
long timezone = 0;
byte daysavetime = 1;
const int ledPin = 4;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char* PARAM_INPUT_1 = "qrCode";
const char* PARAM_INPUT_2 = "role";
const char* PARAM_INPUT_3 = "delete";
const char* PARAM_INPUT_4 = "delete-user";
String inputMessage;
String inputParam;
void onQrCodeTask(void *pvParameters) {
struct QRCodeData qrCodeData;
while (true) {
if (reader.receiveQrCode(&qrCodeData, 100)) {
Serial.println("Scanned new QRCode");
if (qrCodeData.valid) {
String qrCodeString = String((const char *)qrCodeData.payload);
Serial.print("Valid payload: ");
Serial.println(qrCodeString);
String role = getRoleFromFile("/users.txt", qrCodeString);
if (role != "") {
Serial.print("Role for QR Code: ");
Serial.print(qrCodeString);
Serial.print(" is ");
Serial.println(role);
} else {
role = "unknown";
Serial.print("QR Code: ");
Serial.print(qrCodeString);
Serial.println(" not found, set user role to unknown");
}
String sdMessage = qrCodeString + "," + role;
appendFile(SD_MMC, "/log.txt", sdMessage.c_str());
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
}
else {
Serial.print("Invalid payload: ");
Serial.println((const char *)qrCodeData.payload);
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// Write to the SD card
void writeFile(fs::FS &fs, const char * path, const char * message) {
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file) {
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)) {
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
// Append data to the SD card
void appendFile(fs::FS &fs, const char * path, const char * message) {
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file) {
Serial.println("Failed to open file for appending");
return;
}
time_t t = file.getLastWrite();
struct tm *tmstruct = localtime(&t);
char bufferDate[50]; // Adjust buffer size as needed
snprintf(bufferDate, sizeof(bufferDate), "%d-%02d-%02d",
(tmstruct->tm_year) + 1900,
(tmstruct->tm_mon) + 1,
tmstruct->tm_mday);
char bufferTime[50]; // Adjust buffer size as needed
snprintf(bufferTime, sizeof(bufferTime), "%02d:%02d:%02d",
tmstruct->tm_hour,
tmstruct->tm_min,
tmstruct->tm_sec);
String lastWriteTime = bufferDate;
String finalString = String(bufferDate) + "," + String(bufferTime) + "," + String(message) + "\n";
Serial.println(lastWriteTime);
if(file.print(finalString.c_str())) {
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
// Append data to the SD card
void appendUserFile(fs::FS &fs, const char * path, const char * message) {
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file) {
Serial.println("Failed to open file for appending");
return;
}
String finalString = String(message) + "\n";
if(file.print(finalString.c_str())) {
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void deleteFile(fs::FS &fs, const char *path) {
Serial.printf("Deleting file: %s\n", path);
if (fs.remove(path)) {
Serial.println("File deleted");
} else {
Serial.println("Delete failed");
}
// If the log.txt file doesn't exist, create a file on the SD card and write the header
File file = SD_MMC.open("/log.txt");
if(!file) {
Serial.println("Creating new log.txt file...");
writeFile(SD_MMC, "/log.txt", "Date,Time,QR_Code,Role\r\n");
}
else {
Serial.println("log.txt file already exists");
}
file.close();
// If the users.txt file doesn't exist, create a file on the SD card and write the header
file = SD_MMC.open("/users.txt");
if(!file) {
Serial.println("Creating new users.txt file...");
writeFile(SD_MMC, "/users.txt", "QR_Code,Role\r\n");
}
else {
Serial.println("users.txt file already exists");
}
file.close();
}
String processor(const String& var){
return String("HTTP GET request sent to your ESP on input field ("
+ inputParam + ") with value: " + inputMessage +
"
Return to Home Page");
}
void deleteLineFromFile(const char* filename, int lineNumber) {
File file = SD_MMC.open(filename);
if (!file) {
Serial.println("Failed to open file for reading.");
return;
}
// Read all lines except the one to delete
String lines = "";
int currentLine = 0;
while (file.available()) {
String line = file.readStringUntil('\n');
if (currentLine != lineNumber) {
lines += line + "\n";
}
currentLine++;
}
file.close();
// Write back all lines except the deleted one
file = SD_MMC.open(filename, FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing.");
return;
}
file.print(lines);
file.close();
Serial.println("Line deleted successfully.");
}
String getRoleFromFile(const char* filename, String qrCode) {
File file = SD_MMC.open(filename);
if (!file) {
Serial.println("Failed to open file for reading.");
return "";
}
// Skip the header line
file.readStringUntil('\n');
// Read each line and check for QR Code
while (file.available()) {
String line = file.readStringUntil('\n');
int commaIndex = line.indexOf(',');
if (commaIndex > 0) {
String fileQrCode = line.substring(0, commaIndex);
String role = line.substring(commaIndex + 1);
// Compare qrCode
if (fileQrCode == qrCode) {
file.close();
role.trim(); // Remove any extra spaces or newline characters
return role;
}
}
}
file.close();
return ""; // Return empty string if qrCode not found
}
void initLittleFS() {
if(!LittleFS.begin()){
Serial.println("An Error has occurred while mounting LittleFS");
return;
}
}
void initWifi() {
// Connect to Wi-Fi
WiFi.begin(ssid, password);
int connectAttempt = 0;
Serial.println("Connecting to WiFi..");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
connectAttempt ++;
if (connectAttempt == 10){
ESP.restart();
}
}
// Print ESP32 Local IP Address
Serial.print("\nESP IP Address: ");
Serial.println(WiFi.localIP());
}
void initTime() {
Serial.println("Initializing Time");
struct tm tmstruct;
tmstruct.tm_year = 0;
getLocalTime(&tmstruct);
Serial.printf(
"Time and Date right now is : %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min,
tmstruct.tm_sec
);
}
void initSDCard() {
if (!SD_MMC.begin("/sdcard", true)) {
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD_MMC.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
// If the log.txt file doesn't exist, create a file on the SD card and write the header
File file = SD_MMC.open("/log.txt");
if(!file) {
Serial.println("log.txt file doesn't exist");
Serial.println("Creating file...");
writeFile(SD_MMC, "/log.txt", "Date,Time,QR_Code,Role\r\n");
}
else {
Serial.println("log.txt file already exists");
}
file.close();
// If the users.txt file doesn't exist, create a file on the SD card and write the header
file = SD_MMC.open("/users.txt");
if(!file) {
Serial.println("users.txt file doesn't exist");
Serial.println("Creating file...");
writeFile(SD_MMC, "/users.txt", "QR_Code,Role\r\n");
}
else {
Serial.println("users.txt file already exists");
}
file.close();
}
void setup() {
Serial.begin(115200); // Initialize serial communication
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
reader.setup();
Serial.println("\nSetup QRCode Reader");
reader.beginOnCore(1);
Serial.println("Begin on Core 1");
xTaskCreate(onQrCodeTask, "onQrCode", 4 * 1024, NULL, 4, NULL);
initWifi();
initLittleFS();
configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
initTime();
initSDCard();
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/full-log.html");
});
// Route for root /add-user web page
server.on("/add-user", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/add-user.html");
});
// Route for root /manage-users web page
server.on("/manage-users", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/manage-users.html");
});
// Serve Static files
server.serveStatic("/", LittleFS, "/");
// Loads the log.txt file
server.on("/view-log", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SD_MMC, "/log.txt", "text/plain", false);
});
// Loads the users.txt file
server.on("/view-users", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SD_MMC, "/users.txt", "text/plain", false);
});
// Receive HTTP GET requests on /get?input=
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
// GET input1 and input2 value on /get?input1=&input2=
if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = String(PARAM_INPUT_1);
inputMessage += " " + request->getParam(PARAM_INPUT_2)->value();
inputParam += " " + String(PARAM_INPUT_2);
String finalMessageInput = String(request->getParam(PARAM_INPUT_1)->value()) + "," + String(request->getParam(PARAM_INPUT_2)->value());
appendUserFile(SD_MMC, "/users.txt", finalMessageInput.c_str());
}
else if (request->hasParam(PARAM_INPUT_3)) {
inputMessage = request->getParam(PARAM_INPUT_3)->value();
inputParam = String(PARAM_INPUT_3);
if(request->getParam(PARAM_INPUT_3)->value()=="users") {
deleteFile(SD_MMC, "/users.txt");
}
else if(request->getParam(PARAM_INPUT_3)->value()=="log") {
deleteFile(SD_MMC, "/log.txt");
}
}
else if (request->hasParam(PARAM_INPUT_4)) {
inputMessage = request->getParam(PARAM_INPUT_4)->value();
inputParam = String(PARAM_INPUT_4);
deleteLineFromFile("/users.txt", inputMessage.toInt());
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
request->send(LittleFS, "/get.html", "text/html", false, processor);
});
// Start server
server.begin();
}
void loop() {
}
Afficher le code brut
Avant de télécharger le code, vous devez insérer vos informations d’identification réseau dans les lignes suivantes afin que l’ESP32-cam puisse établir une connexion Wi-Fi.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_SSID";
Pour ce projet, nous utilisons le modèle AI-Thinker ESP32-CAM, cependant, si vous utilisez un autre tableau, vous devez le définir ici:
// FOR THIS PROJECT, YOUR ESP32-CAM NEEDS TO HAVE PSRAM.
// Some of the compatible boards: CAMERA_MODEL_AI_THINKER | CAMERA_MODEL_WROVER_KIT | CAMERA_MODEL_ESP_EYE
// CAMERA_MODEL_M5STACK_PSRAM | CAMERA_MODEL_M5STACK_V2_PSRAM | CAMERA_MODEL_M5STACK_WIDE
ESP32QRCodeReader reader(CAMERA_MODEL_AI_THINKER);
Remarque: Votre conseil a besoin d’avoir du PSRAM.
Ressources pour vous aider à comprendre le code
Ce code est assez long et nous n’expliquerons pas en détail comment il fonctionne car tous les sujets couverts ici ont déjà été expliqués dans les projets précédents.
Voici une liste des tutoriels que vous devriez consulter pour en savoir plus sur les sujets couverts ici:
1) Lire des codes QR: ESP32-CAM QR Code Reader / Scanner (Arduino IDE)
2) Obtenir un horodatage à l’aide d’un serveur NTP: ESP32 NTP Client-Server: Get Date and Heure (Arduino IDE).
3) Lecture et écriture de / vers la carte microSD: ESP32: Guide du module de carte microSD à l’aide d’Arduino IDE.
4) Création d’un serveur Web avec l’ESP32: une liste de tous nos projets de serveur Web.
5) Envoi des données à partir d’une page Web au formulaire ESP32 via HTML: Données d’entrée sur le formulaire HTML Formulaire ESP32 / ESP8266 Serveur Web à l’aide d’Arduino IDE.
6) En savoir plus sur l’ESP32-CAM avec nos projets EBOT EBOT EBOT dédiés ESP32-CAM à l’aide d’Arduino IDE.
Téléchargez le code sur l’ESP32-cam AI-Thinker à l’aide du programmeur USB ESP32-CAM-MB
Pour télécharger du code sur la carte ESP32-CAM, nous utiliserons le programmeur ESP32-CAM-MB. Joignez le programmeur Micro USB ESP32-CAM-MB à votre carte (vous pouvez apprendre comment cela fonctionne en lisant ce guide).

Si vous avez un programmeur FTDI, vous pouvez suivre ce tutoriel à la place: comment programmer / télécharger du code sur ESP32-cam AI-Thinker (Arduino IDE à l’aide d’un programmeur FTDI).
Ensuite, connectez la carte à votre ordinateur à l’aide d’un câble USB.
Après cela, dans votre IDE Arduino, accédez à Tools> Board et sélectionnez l’ESP32-CAM AI-Thinker. Ou recherchez cette planche sur la barre supérieure. Vous devez installer le module complémentaire ESP32. Sinon, cette planche n’apparaîtra pas dans le menu des planches.

Accédez à Tools> Port et sélectionnez le port COM à laquelle le CAM ESP32 est connecté.
Remarque: Si la carte n’apparaît pas, cela signifie que vous n’avez probablement pas les pilotes CH340C installés sur votre ordinateur. Accédez à Google et recherchez des «pilotes CH340C» suivis de votre système d’exploitation et installez les pilotes.
Enfin, cliquez sur le bouton Télécharger dans votre IDE Arduino.

Et c’est tout! Votre code de scanner de code QR devrait être exécuté dans votre ESP32-cam.
Télécharger le code et le dossier de données
Après avoir inséré vos informations d’identification réseau, enregistrez le code. Allez dans Sketch> Afficher le dossier Sketch et créez un dossier appelé DATA.

À l’intérieur de ce dossier, vous devez placer le HTML et les fichiers CSS fournis précédemment.
Téléchargement de l’image du système de fichiers
Téléchargez ces fichiers sur le système de fichiers: appuyez sur [Ctrl] + [Shift] + [P] sous Windows ou [⌘] + [Shift] + [P] sur macOS pour ouvrir la palette de commande. Recherchez le téléchargement Littlefs vers la commande PICO / ESP8266 / ESP32 et cliquez dessus.
Si vous n’avez pas cette option, c’est parce que vous n’avez pas installé le plugin de téléchargement de système de fichiers. Vérifiez ce tutoriel.

Important: assurez-vous que le moniteur série est fermé avant de télécharger sur le système de fichiers. Sinon, le téléchargement échouera.
Téléchargement du code
Après avoir téléchargé le code et les fichiers dans le dossier de données, ouvrez le moniteur série à un taux en bauds de 115200. Appuyez sur le bouton ESP32-CAM EN / RST. Il doit initialiser le scanner de code QR et le serveur Web. Vérifiez la fenêtre Arduino IDE Serial Monitor pour voir si tout fonctionne comme prévu.

Il devrait imprimer l’adresse IP ESP32. Dans mon cas, il est 192.168.1.76. Enregistrez votre IP car vous en aurez besoin à l’étape suivante.
Tester le lecteur de code QR
Voici 4 exemples de codes QR (leurs données correspondantes sont dans la légende de l’image). Vous pouvez utiliser n’importe quel générateur de code QR en ligne pour créer des codes QR personnalisés avec vos données souhaitées.




Pointez l’ESP32-cam vers un code QR et maintenez-le stable.

Les données de charge utile doivent être imprimées dans le moniteur série Arduino IDE:

Si dans le moniteur série Arduino IDE, vous continuez à recevoir ce message:
Invalid payload: ECC failure
Vous devrez peut-être utiliser un code QR plus petit, rendre la caméra plus stable et la pointer directement vers le code QR avec de meilleures conditions d’éclairage.
L’ESP32-CAM a certaines limites de résolution et lutte contre le mouvement, vous devez donc le viser régulièrement au code QR. De plus, la détection des codes QR peut être difficile dans de mauvaises conditions d’éclairage, qu’elle soit trop brillante ou trop sombre.
Démonstration
Ouvrez un navigateur sur votre réseau local et saisissez l’adresse IP ESP32-CAM. Vous devez accéder à la page du serveur Web qui ressemble à ceci, il devrait avoir une table vierge par défaut.

Scannez certains codes QR avec votre ESP32-cam. Chaque fois que vous numérisez un code QR valide, la LED flash intégrée doit s’allumer. Dans votre moniteur de série Arduino IDE, les données QR seront imprimées:

À des fins de test, je recommande de numériser plusieurs codes QR, afin que vous ayez plus de données affichées dans votre serveur Web. Copiez les données de l’un de vos codes QR (par exemple: RUI_Santos). Ensuite, ouvrez l’onglet Ajouter un utilisateur.

Tapez les données du code QR et sélectionnez le rôle (utilisateur ou administrateur). Enfin, cliquez sur le bouton «Enregistrer». J’ai répété ce processus pour les autres codes QR mentionnés dans ce post.

Maintenant, si vous parcourez la page Web des utilisateurs du gestionnaire:

Il charge une table avec tous les codes QR et leurs rôles utilisateur correspondants, vous pouvez cliquer sur «X» pour supprimer un utilisateur.

Analysez les codes QR quelques fois de plus, puis ouvrez la page d’accueil du serveur Web. La table de journal doit avoir toutes les entrées avec un horodatage, un code QR et les rôles utilisateur correspondants.

Au bas des pages Web complètes du journal et des utilisateurs du gestionnaire, vous avez la possibilité de supprimer les fichiers log.txt et utilisateurs.txt de la carte microSD à tout moment.

Vous pouvez également accéder à la page du serveur Web de votre smartphone.

Dépannage et conseils
Comme nous l’avons mentionné plus tôt, ce scanner de code QR utilise beaucoup de mémoire, donc votre ESP32-cam doit avoir du PSRAM. Voici quelques conseils qui ont été testés et devraient fonctionner avec cet exemple:
- Caméra_model_ai_thinker
- Caméra_model_wrover_kit
- Caméra_model_esp_eye
- Caméra_model_m5stack_psram
- Caméra_model_m5stack_v2_psram
- Caméra_model_m5stack_wide
Si vous obtenez l’une des erreurs suivantes, lisez notre guide de dépannage ESP32-cam: problèmes les plus courants résolus
- Échec de la connexion à ESP32: Tourné en attente d’en-tête de paquet
- Camera init a échoué avec l’erreur 0x20001 ou similaire
- Détecteur Brownout ou Erreur de méditation Guru
- Sketch Trop Big Error – Mauvais Schéma de partition sélectionné
- La carte à Comx n’est pas disponible – le port com non sélectionné
- Erreur PSRAM: le service GPIO ISR n’est pas installé
Emballage
Dans ce didacticiel, vous avez combiné différents sujets pour créer un système de gestion de code QR et un enregistreur avec l’ESP32-cam. Voici une liste des sujets que nous avons couverts: différentes fonctionnalités du serveur Web, obtenant un horodatage, la données de données, l’interfaçage de l’appareil photo intégré en tant que lecteur de code QR, la lecture et l’écriture de fichiers sur une carte microSD, et bien plus encore.
Nous espérons que vous avez trouvé ce projet utile, si vous voulez en savoir plus sur l’ESP32-cam, vous pouvez lire les guides suivants:
Merci d’avoir lu.
Revivez l’histoire de Raspberry Pi dans cette vidéo :

