Les points d'accès WiFi sur les carte Arduino ne permettent pas le routage entre les clients. Il faudrait utiliser une carte Raspberry.
Créer un point d'accès Wifi sur un PC ArduiLabs
password : OSI-2026!

https://ledmatrix-editor.arduino.cc/

#include "Arduino_LED_Matrix.h"
#include "WiFiS3.h"
#include <vector> // Nécessaire pour la liste dynamique
// --- Configuration Matrice LED ---
ArduinoLEDMatrix matrix;
const uint32_t check[] = { 0x00300600, 0xcc186303, 0x601c0080 }; // Check
const uint32_t cross[] = { 0x60c3181b, 0x00e00e01, 0xb031860c }; // Cross
// --- Configuration Matériel ---
const int GACHE_PIN = 8; // Signal vers IRF520
// --- Configuration Réseau AP ---
const char* ssid = "ArduiLabs";
const char* password = "OSI-2026!";
const char* esp32CamIp = "192.168.110.100";
const char* unoR4Ip = "192.168.110.110";
IPAddress local_IP(192, 168, 110, 254);
IPAddress gateway(192, 168, 110, 254);
IPAddress subnet(255, 255, 255, 0);
// --- Sécurité et Logs ---
std::vector<String> allowedUIDs; // Liste dynamique vide au démarrage
WiFiServer server(80);
String logRFID = "";
// --- Fonctions de gestion de la liste ---
bool isAuthorized(String uid) {
for (const String& id : allowedUIDs) {
if (id == uid) return true;
}
return false;
}
void removeUID(String uid) {
for (auto it = allowedUIDs.begin(); it != allowedUIDs.end(); ++it) {
if (*it == uid) {
allowedUIDs.erase(it);
break;
}
}
}
void setup() {
Serial.begin(115200);
while (!Serial);
matrix.begin();
pinMode(GACHE_PIN, OUTPUT);
digitalWrite(GACHE_PIN, LOW);
Serial.println("-----------------------------------");
Serial.println("*** UNO R4 SERVER ***");
Serial.println("*** LISTE DYNAMIQUE ***");
Serial.println("-----------------------------------");
WiFi.config(local_IP, gateway, subnet);
Serial.print("Création du réseau : "); Serial.println(ssid);
WiFi.begin(ssid, password);
// Attente de la connexion physique
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
// FORCE L'ATTENTE DU DHCP (Évite le 0.0.0.0)
Serial.println("Connexion établie !");
Serial.print("Attente de l'adresse IP...");
while (WiFi.localIP() == IPAddress(0,0,0,0)) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println(WiFi.localIP());
Serial.println("-----------------------------------");
server.begin();
Serial.print("WEB Serveur ready : ");
Serial.println(WiFi.localIP());
Serial.println("-----------------------------------");
}
void loop() {
WiFiClient client = server.available();
if (client) {
String request = client.readStringUntil('\r');
Serial.println("Requête : " + request);
// --- Route : AJOUTER un UID ---
if (request.indexOf("GET /add?uid=") != -1) {
int start = request.indexOf("uid=") + 4;
int end = request.indexOf(" ", start);
String uid = request.substring(start, end);
if (!isAuthorized(uid)) {
allowedUIDs.push_back(uid);
Serial.println("Ajouté : " + uid);
}
client.println("HTTP/1.1 303 See Other\r\nLocation: /\r\n\r\n");
}
// --- Route : RETIRER un UID ---
else if (request.indexOf("GET /remove?uid=") != -1) {
int start = request.indexOf("uid=") + 4;
int end = request.indexOf(" ", start);
String uid = request.substring(start, end);
removeUID(uid);
Serial.println("Retiré : " + uid);
client.println("HTTP/1.1 303 See Other\r\nLocation: /\r\n\r\n");
}
// --- Page Web de contrôle ---
else if (request.indexOf("GET / ") != -1) {
sendHeader(client);
client.println("<h1>Contrôle Accès OSI 2026</h1>");
client.println("<br><a href='/open' style='font-size:20px; padding:10px; background:#ddd;'>OUVRIR LA PORTE</a><br>");
client.println("<h2>Historique des passages</h2>");
client.println("<table border='1' width='100%'><tr><th>Badge</th><th>Photo</th><th>Statut</th><th>Action</th></tr>");
client.println(logRFID);
client.println("</table></body></html>");
}
// --- Ouverture manuelle ---
else if (request.indexOf("GET /open") != -1) {
triggerUnlock();
client.println("HTTP/1.1 303 See Other\r\nLocation: /\r\n\r\n");
}
// --- Réception donnée RFID (POST) ---
else if (request.indexOf("POST /data") != -1) {
while (client.available()) {
String line = client.readStringUntil('\n');
if (line.startsWith("uid=")) {
String uid = line.substring(4);
uid.trim();
uid.toUpperCase();
askCameraToCapture(uid);
bool auth = isAuthorized(uid);
String actionBtn = "";
if (auth) {
triggerUnlock();
actionBtn = "<a href='/remove?uid=" + uid + "'>[Retirer]</a>";
logRFID = "<tr><td>" + uid + "</td><td><a href='http://192.168.110.100/capture?rfid=" + uid + "'target='_blank'>Photo</a></td><td style='color:green;'>OK</td><td>" + actionBtn + "</td></tr>" + logRFID;
} else {
matrix.loadFrame(cross);
actionBtn = "<a href='/add?uid=" + uid + "'>[Ajouter]</a>";
logRFID = "<tr><td>" + uid + "</td><td><a href='http://192.168.110.100/capture?rfid=" + uid + "'target='_blank'>Photo</a></td><td style='color:red;'>REFUS</td><td>" + actionBtn + "</td></tr>" + logRFID;
delay(2000);
matrix.clear();
}
}
}
client.println("HTTP/1.1 200 OK\r\n\r\n");
}
// --- Déclenchement physique gâche ---
else if (request.indexOf("POST /unlock") != -1) {
digitalWrite(GACHE_PIN, HIGH);
matrix.loadFrame(check);
delay(3000);
digitalWrite(GACHE_PIN, LOW);
matrix.clear();
client.println("HTTP/1.1 200 OK\r\n\r\n");
}
client.stop();
}
}
void sendHeader(WiFiClient& client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML><html><head><meta charset='UTF-8'>");
client.println("<meta http-equiv='refresh' content='10'></head><body style='text-align:center;'>");
}
void triggerUnlock() {
WiFiClient localClient;
if (localClient.connect("127.0.0.1", 80)) {
localClient.println("POST /unlock HTTP/1.1");
localClient.println("Host: localhost");
localClient.println("Content-Length: 0");
localClient.println();
localClient.stop();
}
}
void askCameraToCapture(String uid) {
WiFiClient client;
if (client.connect("192.168.110.100", 80)) {
client.println("POST /capture?rfid=" + uid + " HTTP/1.1");
client.println("Host: 192.168.110.100");
client.println("Content-Length: 0");
client.println();
client.stop();
}
}

#include <SPI.h>
#include <Adafruit_PN532.h>
#include "WiFiS3.h"
#include "Arduino_LED_Matrix.h" // Bibliothèque spécifique à la R4 WiFi
ArduinoLEDMatrix matrix;
const uint32_t happy[] = {
0x7fe801b1, 0xda91b19a, 0x918017fe // RFID card (Read OK)
};
// Définition des pins SPI
#define PN532_SCK (13)
#define PN532_MISO (12)
#define PN532_MOSI (11)
#define PN532_SS (10)
#define PN532_RST (3)
// Initialisation du module en mode SPI matériel
Adafruit_PN532 nfc(PN532_SS);
const char* ssid = "ArduiLabs";
const char* password = "OSI-2026!";
const char* serverIp = "192.168.110.254"; // IP de l'Arduino R4 SERVEUR
// --- Configuration IP Statique ---
IPAddress local_IP(192, 168, 110, 110); // Adresse du lecteur
IPAddress gateway(192, 168, 110, 254); // IP du serveur R4
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("-----------------------------------");
Serial.println("*** Hello UNO R4 RFID ***");
Serial.println("*** SPI ***");
Serial.println("-----------------------------------");
WiFi.config(local_IP, gateway, subnet);
Serial.print("Connexion au WiFi...");
WiFi.begin(ssid, password);
// Attente de la connexion physique
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
// FORCE L'ATTENTE DU DHCP (Évite le 0.0.0.0)
Serial.println("Connexion établie !");
Serial.print("Attente de l'adresse IP...");
while (WiFi.localIP() == IPAddress(0,0,0,0)) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println(WiFi.localIP());
Serial.println("-----------------------------------");
matrix.begin();
Serial.println("Initialisation du bus SPI et du PN532...");
// Reset forcé du module via la pin RST
pinMode(PN532_RST, OUTPUT);
digitalWrite(PN532_RST, LOW);
delay(100);
digitalWrite(PN532_RST, HIGH);
delay(500);
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (!versiondata) {
Serial.println("ERREUR : PN532 introuvable en SPI. Verifiez les switches (1:OFF, 2:OFF).");
while (1);
}
Serial.print("PN532 detecte ! Firmware v");
Serial.print((versiondata >> 16) & 0xFF, DEC); Serial.print('.');
Serial.println((versiondata >> 8) & 0xFF, DEC);
nfc.SAMConfig(); // Configuration du mode lecture
Serial.println("-----------------------------------");
Serial.println("--> Fin de l'init !!!");
}
void loop() {
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t uidLength;
// Lecture d'un badge (non bloquant pendant 100ms)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 100);
if (success) {
matrix.loadFrame(happy); // Affiche OK
String tagID = "";
for (uint8_t i = 0; i < uidLength; i++) {
if (uid[i] < 0x10) tagID += "0";
tagID += String(uid[i], HEX);
}
tagID.toUpperCase();
Serial.println("Badge detecte : " + tagID);
// Envoi au serveur central
sendToServer(tagID);
delay(2000); // Anti-rebond
}
}
void sendToServer(String id) {
WiFiClient client;
if (client.connect(serverIp, 80)) {
String postData = "uid=" + id;
client.println("POST /data HTTP/1.1");
client.print("Host: "); client.println(serverIp);
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: "); client.println(postData.length());
client.println("Connection: close");
client.println();
client.print(postData);
client.stop();
Serial.println("Donnee transmise.");
} else {
Serial.println("Erreur de connexion au serveur.");
}
delay(300);
matrix.clear();
}

L'utilisation de la carte SD fait clignoter la led Flash...
#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include "esp_camera.h"
#include <WebServer.h>
#include "FS.h"
#include "SD_MMC.h"
const char* ssid = "ArduiLabs";
const char* password = "OSI-2026!";
const char* serverUrl = "http://192.168.110.254/data"; // IP de l'Arduino R4
// --- Configuration IP Statique ---
IPAddress local_IP(192, 168, 110, 100); // Adresse du lecteur
IPAddress gateway(192, 168, 110, 254); // IP du serveur R4
IPAddress subnet(255, 255, 255, 0);
WebServer server(80);
// Config Caméra AI-THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// --- Route POST /capture : Enregistre sur SD ---
void handlePostCapture() {
Serial.println("-----------------------------------");
if (!server.hasArg("rfid")) {
server.send(400, "text/plain", "RFID manquant");
return;
}
String rfid = server.arg("rfid");
// --- ÉTAPE DE PURGE ---
// On récupère et on rend immédiatement 1 ou 2 images
// pour vider les anciens tampons du capteur.
camera_fb_t * fb_tmp = esp_camera_fb_get();
if (fb_tmp) esp_camera_fb_return(fb_tmp);
fb_tmp = esp_camera_fb_get();
if (fb_tmp) esp_camera_fb_return(fb_tmp);
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
server.send(500, "text/plain", "Echec capture camera");
return;
}
// Nom du fichier basé sur l'ID RFID
String path = "/" + rfid + ".jpg";
Serial.println("POST Image : " + path);
File file = SD_MMC.open(path.c_str(), FILE_WRITE);
if (!file) {
Serial.println(" Erreur ouverture SD");
server.send(500, "text/plain", "Erreur Carte SD");
} else {
file.write(fb->buf, fb->len);
file.close();
Serial.println(" Image enregistree : " + path);
server.send(200, "text/plain", "Image OK");
}
esp_camera_fb_return(fb);
Serial.println("-----------------------------------");
}
// --- Route GET /capture?rfid=... : Renvoie l'image ---
void handleGetPhoto() {
Serial.println("-----------------------------------");
if (!server.hasArg("rfid")) {
server.send(400, "text/plain", "RFID manquant");
return;
}
String rfid = server.arg("rfid");
String path = "/" + rfid + ".jpg";
Serial.println("GET Image : " + path);
File file = SD_MMC.open(path.c_str());
if (!file) {
server.send(404, "text/plain", "Photo introuvable");
return;
}
server.streamFile(file, "image/jpeg");
file.close();
Serial.println("-----------------------------------");
}
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("-----------------------------------");
Serial.println("*** Hello ESP32-CAM ***");
Serial.println("*** ***");
Serial.println("-----------------------------------");
// Initialisation SD Card (Mode 1-bit pour libérer des pins si nécessaire)
if(!SD_MMC.begin("/sdcard", true)){
Serial.println("Erreur : Carte SD absente");
} else {
Serial.println("Carte SD OK!");
}
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_sccb_sda = SIOD_GPIO_NUM; config.pin_sccb_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;
config.frame_size = FRAMESIZE_QVGA; config.jpeg_quality = 12; config.fb_count = 1;
esp_camera_init(&config);
WiFi.config(local_IP, gateway, subnet);
Serial.print("Connexion au WiFi...");
WiFi.begin(ssid, password);
// Attente de la connexion physique
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
// FORCE L'ATTENTE DU DHCP (Évite le 0.0.0.0)
Serial.println("Connexion établie !");
Serial.print("Attente de l'adresse IP...");
while (WiFi.localIP() == IPAddress(0,0,0,0)) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println(WiFi.localIP());
Serial.println("-----------------------------------");
delay(500);
// Routes HTTP
server.on("/capture", HTTP_POST, handlePostCapture); // Pour enregistrer
server.on("/capture", HTTP_GET, handleGetPhoto); // Pour lire
server.begin();
}
void loop() {
server.handleClient();
}



