// CHAIMAA TABHIRET ET HANANE AOUZAL
// ALARME ANTI-INTRUTION
//====================> COFFRE-FORT <===================//
//définissent les identifiants Blynk nécessaires
//pour la connexion à la plateforme Blynk
#define BLYNK_TEMPLATE_ID "TMPL2u74eCHlG"
#define BLYNK_TEMPLATE_NAME "coffre Door"
#define BLYNK_AUTH_TOKEN "8CQLxrjh3TAy4ChVgxXm-l84w29o0Otv"
char auth[] = BLYNK_AUTH_TOKEN;
//définissent les broches utilisées pour les composants
//tels que la LED, le buzzer, le clavier, le servo-moteur et l'écran LCD.
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
int switchState;// Déclaration de la variable pour stocker l'état du commutateur
BlynkTimer timer;// Déclaration de la minuterie Blynk
BLYNK_CONNECTED() { // Fonction appelée lors de la connexion à Blynk
Blynk.syncVirtual(V5); // Synchronise l'état virtuel V5 avec la variable locale switchState
}
BLYNK_WRITE(V5) {// Fonction appelée lorsqu'une valeur virtuelle de Blynk (V5) est mise à jour
switchState = param.asInt(); // Met à jour la variable switchState avec la nouvelle valeur de V5
}
int Blynk_up = 0;//Déclaration de la variable pour stocker l'état de Blynk_up
BLYNK_WRITE(V0) {//Fonction appelée lorsqu'une valeur virtuelle de Blynk (V0) est mise à jour
Blynk_up = param.asInt();// Met à jour la variable Blynk_up avec la nouvelle valeur de V0
}
Ces lignes définissent les broches utilisées
pour les composants tels que la LED, le buzzer, le clavier, le servo-moteur et l'écran LCD.
#define led 25
#define buzzer 13
// Configuration du clavier matriciel
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
// Déclaration des broches pour les lignes du clavier matriciel
byte rowPins[ROWS] = {15, 2, 4, 5};
// Déclaration des broches pour les colonnes du clavier matriciel
byte colPins[COLS] = {18, 19, 27};
// Initialisation de l'objet Keypad avec la configuration du clavier
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Servo myServo;// Déclaration de l'objet Servo pour contrôler un servo-moteur
const int servoPin = 14;// Broche à laquelle le servo-moteur est connecté
// Positions du servo-moteur pour verrouiller et déverrouiller le coffre
const int lockPosition = 0;
const int unlockPosition = 90;
// Déclaration de l'objet LiquidCrystal_I2C pour contrôler un écran LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Code PIN pré-défini pour le coffre
char Code[4] = { '1', '1', '1', '1'};
// Tableau pour stocker le code entré par l'utilisateur
char enteredCode[4];
// Indice pour suivre la position actuelle dans le code entré
int codeIndex = 0;
byte STATE = 0;// État actuel du système
byte PREVIOUS_STATE = 1;// État précédent du système
void setup() {
// Démarre la communication série avec une vitesse de 9600 bauds.
Serial.begin(9600);
// Initialisez la connexion Blynk avec le jeton d'authentification et le réseau WiFi.
Blynk.begin(auth, "Wokwi-GUEST", "");
// Attache le servo-moteur à la broche spécifiée.
myServo.attach(servoPin);
// Initialise l'écran LCD.
lcd.init();
// Active le rétroéclairage de l'écran LCD.
lcd.backlight();
// Configure une minuterie pour appeler la fonction updateBlynk toutes les 1000 millisecondes (1 seconde).
pinMode(led, OUTPUT);// Configure la broche LED en mode de sortie.
pinMode(buzzer, OUTPUT); // Configure la broche du buzzer en mode de sortie.
}
void loop() {
// Blynk.run() traite la communication Blynk dans la boucle
Blynk.run();
// timer.run() traite toutes les tâches chronométrées définies par BlynkTimer
timer.run();
//keypad.getKey() vérifie si une touche est enfoncée sur le clavier
//===================> MAKE DECISIONS <====================//
// Vérifie si l'état actuel (STATE) diffère de l'état précédent (PREVIOUS_STATE)
if(STATE != PREVIOUS_STATE){
// Utilise une structure de commutation pour prendre des décisions en fonction de l'état actuel
switch (STATE) {
case 0:
// Affiche "Coffer locked" sur l'écran LCD et verrouille le servo-moteur
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Coffer locked");
myServo.write(lockPosition);
// Désactive les indicateurs virtuels sur l'application Blynk
Blynk.virtualWrite(V2, LOW);
Blynk.virtualWrite(V3, LOW);
Blynk.virtualWrite(V4, LOW);
// Met à jour l'état précédent
PREVIOUS_STATE = STATE;
break;
case 1:
// Affiche "Verifying..." sur l'écran LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Verifying...");
// Met à jour l'état précédent
PREVIOUS_STATE = STATE;
break;
case 2:
// Affiche "Coffer unlocked" sur l'écran LCD, verrouille le servo-moteur, et active un indicateur virtuel sur Blynk
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Coffer unlocked");
lcd.setCursor(0, 1);
lcd.print("Coffer locked");
myServo.write(unlockPosition);
Blynk.virtualWrite(V2, HIGH);
// Met à jour l'état précédent
PREVIOUS_STATE = STATE;
break;
case 3:
// Affiche "Wrong PIN" sur l'écran LCD, active la LED et le buzzer, et met à jour les indicateurs virtuels sur Blynk
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wrong PIN");
digitalWrite(led,HIGH);
digitalWrite(buzzer,HIGH);
analogWrite(buzzer,100);
Blynk.virtualWrite(V3, HIGH);
Blynk.virtualWrite(V4, HIGH);
// Met à jour l'état précédent
PREVIOUS_STATE = STATE;
break;
case 4:
// Affiche "Wrong PIN Verifying..." sur l'écran LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wrong PIN");
lcd.setCursor(0, 1);
lcd.print("Verifying...");
// Met à jour l'état précédent
PREVIOUS_STATE = STATE;
break;
}}
//==========> UPDATE THE STATE : keypad <==========//
// Met à jour l'état en fonction des touches du clavier matriciel
char key = keypad.getKey();
if(key != NO_KEY){
if(STATE == 0){
switch ( key ) {
case '*':
// Réinitialise l'état à "Verifying..." et réinitialise l'indice du code
PREVIOUS_STATE = 1;
PREVIOUS_STATE = 1;
codeIndex = 0;
break;
case '#':
// Vérifie le code entré et met à jour l'état en conséquence
if(codeIndex == 4){
if(Code[0]==enteredCode[0] && Code[1]==enteredCode[1] && Code[2]==enteredCode[2] && Code[3]==enteredCode[3])
{
STATE = 1;
codeIndex = 0;
}else{
STATE = 4;
codeIndex = 0;
}
}
break;
default:
// Enregistre la touche dans le code entré, affiche "*" sur l'écran LCD, et incrémente l'indice du code
if(codeIndex < 4){
enteredCode[codeIndex] = key;
lcd.setCursor(codeIndex, 1);
lcd.print("*");
codeIndex++;
}
break;
}
}else if(STATE == 1 && key == '*'){
// Réinitialise l'état à "Coffer locked" si la touche "*" est pressée pendant la vérification
STATE = 0;
}else if(STATE == 2 && key == '*'){
// Réinitialise l'état à "Coffer locked" si la touche "*" est pressée pendant le déverrouillage
STATE = 0;
}
}
//==========> UPDATE THE STATE : blynk <==========//
// Vérifie si la condition Blynk_up est vraie
if(Blynk_up){
// Vérifie l'état actuel
if(STATE == 1){
// Si l'interrupteur est activé (HIGH), met à jour l'état à "Coffer unlocked" (2), sinon à "Wrong PIN" (3)
if(switchState == HIGH){
STATE = 2;
}else{
STATE = 3;
}
}
// Vérifie l'état actuel
if(STATE == 4){
// Si l'interrupteur est activé (HIGH), met à jour l'état à "Coffer locked" (0), sinon à "Wrong PIN" (3)
if(switchState == HIGH){
STATE = 0;
}else{
STATE = 3;
}
}
}
}