// === Identifiants Blynk (à personnaliser) ===
#define BLYNK_TEMPLATE_ID "TMPL2w8FAMSWd"
#define BLYNK_TEMPLATE_NAME "ControleAccesRFID"
#define BLYNK_AUTH_TOKEN "rbtycjfsdWR5COJY2EtmIk_gbInWMC45"
#define BLYNK_PRINT Serial // Active les logs internes de Blynk
#include <Arduino.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// === Broches ===
#define BUZZER_PIN 14
#define GREEN_LED 26
#define RED_LED 27
#define RELAY_PIN 21 // CHANGED FROM 12 TO 21 TO AVOID BOOT CRASH
#define SERVO_PIN 13
Servo myServo;
// === Pins virtuels Blynk ===
#define VIRTUAL_INPUT V0 // Champ texte pour e-KTP
#define VIRTUAL_UNLOCK V1 // Bouton manuel
String receivedID = "";
// === Fonction de connexion Wi-Fi ===
void connectWiFi() {
Serial.print("Connexion WiFi...");
WiFi.begin(ssid, pass);
int retries = 0;
while (WiFi.status() != WL_CONNECTED && retries < 20) {
delay(500);
Serial.print(".");
retries++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println(" OK");
Serial.print("Adresse IP : ");
Serial.println(WiFi.localIP());
} else {
Serial.println(" FAILED");
}
}
// === SETUP ===
void setup() {
Serial.begin(115200);
delay(100); // Laisse le temps au terminal de s'ouvrir
Serial.println("\n\n--- Démarrage du Système de Contrôle d'Accès ---");
pinMode(BUZZER_PIN, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
digitalWrite(RELAY_PIN, LOW);
myServo.attach(SERVO_PIN);
myServo.write(0); // Porte fermée
Serial.println("Composants initialisés. Porte fermée.");
// 1. Connexion au Wi-Fi manuelle (avec logs)
connectWiFi();
// 2. Configuration et connexion à Blynk
Serial.print("Connexion au serveur Blynk...");
Blynk.config(BLYNK_AUTH_TOKEN);
if(Blynk.connect()) {
Serial.println(" OK");
Serial.println("✅ SYSTÈME EN LIGNE : En attente d'un badge ou d'une commande web !");
} else {
Serial.println(" FAILED (Vérifiez le Token Blynk)");
}
}
// === Lecture du champ texte V0 (e-KTP) ===
BLYNK_WRITE(VIRTUAL_INPUT) {
receivedID = param.asString();
receivedID.trim();
Serial.print("\n▶ [BLYNK] Code reçu : ");
Serial.println(receivedID);
if (isValidFormat(receivedID)) {
if (receivedID.equals("12 34 56 78")) {
accessGranted();
} else {
accessDenied();
}
} else {
Serial.println("❌ Erreur : Format de code invalide !");
Blynk.virtualWrite(V0, "Format: XX XX XX XX");
}
}
// === Bouton manuel V1 ===
BLYNK_WRITE(VIRTUAL_UNLOCK) {
int state = param.asInt();
Serial.print("\n▶ [BLYNK] Bouton manuel cliqué. État = ");
Serial.println(state == 1 ? "ON" : "OFF");
if (state == 1) {
accessGranted();
}
}
// === LOOP PRINCIPALE ===
void loop() {
Blynk.run();
}
// === Vérifie le format "XX XX XX XX" ===
bool isValidFormat(String input) {
if (input.length() == 11 && input.charAt(2) == ' ' && input.charAt(5) == ' ' && input.charAt(8) == ' ') {
for (int i = 0; i < input.length(); i++) {
if (i != 2 && i != 5 && i != 8 && !isDigit(input.charAt(i))) {
return false;
}
}
return true;
}
return false;
}
// === Accès autorisé ===
void accessGranted() {
Serial.println("🟢 RÉSULTAT : Accès autorisé !");
Blynk.logEvent("access_granted", "Ouverture autorisée via e-KTP ou bouton");
digitalWrite(BUZZER_PIN, HIGH);
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo.write(40); // Ouvre la porte
delay(5000);
Serial.println("Fermeture automatique de la porte.");
myServo.write(0); // Ferme
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RELAY_PIN, LOW);
}
// === Accès refusé ===
void accessDenied() {
Serial.println("🔴 RÉSULTAT : Accès refusé !");
Blynk.logEvent("access_denied", "e-KTP non reconnu");
digitalWrite(BUZZER_PIN, HIGH);
digitalWrite(RED_LED, HIGH);
delay(5000);
Serial.println("Fin de l'alerte.");
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RED_LED, LOW);
}