//Création des différents états de la MAE
enum State {
ATT, // En attente que l'utilisateur appuie sur une touche
CODE, // L'utilisateur entre un code
BON, // Le code est correct
ERREUR, // Le code est incorrect
ALARME // L'alarme est déclenchée après 3 erreurs
};
State currentState = ATT;
const int buttonPins[] = {4, 5, 6, 7, 9, 10, 11, 12}; // Broches des boutons
const int CodeCorrect[] = {10, 7, 9, 11}; // Code correct Jaune / Bleu ciel / Vert / Orange
int CodeSaisi[4] = {-1, -1, -1, -1}; // Code saisi, 0 peut exister en tant que broche alors que -1 non
int EtpSaisieCode = 0; // Étape de saisie du code
int CmptErreur = 0; // Nombre d'erreurs
int NbrBPN = 0; // Nombre d'appuis sur le bouton noir (12)
bool buttonStates[8] = {true, true, true, true, true, true, true, true}; // Représente les boutons dans l'état relâché
// Passe à l'état false quand pression
/**-----------------------------------------------------------------------------------*/
void setup() {
Serial.begin(9600); // Pour les messages de débogage
pinMode(A3, OUTPUT); // LED Orange
pinMode(A4, OUTPUT); // LED Rouge
pinMode(A5, OUTPUT); // LED Verte // Configuration des LEDs
for (int i = 0; i < 8; i++) {
pinMode(buttonPins[i], INPUT_PULLUP); // Configure les boutons en INPUT_PULLUP
}
}
// Initialisation des états
void loop() {
switch (currentState) {
case ATT:
handleAttState();
break;
case CODE:
handleCodeState();
break;
case BON:
handleBonState();
break;
case ERREUR:
handleErreurState();
break;
case ALARME:
handleAlarmeState();
break;
}
}
/**-----------------------------------------------------------------------------------*/
// Gestion des états
//État attente d'appuie
void handleAttState() {
for (int i = 0; i < 8; i++) {
if (isButtonPressed(i)) { // Bouton pressé
Serial.println("Début de la saisie du code.");
currentState = CODE;
return;
}
}
}
//État récupération du code entré
void handleCodeState() {
if (EtpSaisieCode < 4) {
for (int i = 0; i < 8; i++) {
if (isButtonPressed(i)) { // Nouveau bouton pressé
delay(200); // Anti-rebond
CodeSaisi[EtpSaisieCode] = buttonPins[i];
Serial.print("Touche pressée : ");
Serial.println(buttonPins[i]);
EtpSaisieCode++;
if (EtpSaisieCode == 4) {
if (checkCode()) {
currentState = BON;
} else {
currentState = ERREUR;
}
}
return;
}
}
}
}
// État Bon -> activation de la led verte (ouverture)
void handleBonState() {
Serial.println("Code correct !");
digitalWrite(A5, HIGH); // Allume la LED Verte
delay(4000);
digitalWrite(A5, LOW);
// Réinitialisation complète après un code correct
CmptErreur = 0; // Réinitialise le compteur d'erreurs
NbrBPN = 0; // Réinitialise les appuis sur le bouton noir
resetState(); // Retour à l'état initial (ATT)
}
// État erreur -> incrémentation du coompteur d'erreur et allumlage led rouge
void handleErreurState() {
Serial.println("Code incorrect.");
digitalWrite(A4, HIGH); // Allume la LED Rouge
delay(2000);
digitalWrite(A4, LOW);
EtpSaisieCode = 0;
CmptErreur++;
// Si compteur erreur >= 3 alors on passe à l'état alarme
if (CmptErreur >= 3) {
currentState = ALARME;
} else {
resetState();
}
}
// État alarme -> Boucle de led pour alarme
void handleAlarmeState() {
static unsigned long lastToggle = 0;
static int ledState = 0; // 0 = LED Verte, 1 = Pause après Verte, 2 = LED Orange, 3 = Pause après Orange
static bool awaitingCode = false;
unsigned long currentTime = millis();
// Gestion du clignotement des LEDs pour l'alarme
//Utilisation de Switch Case pour plus de clarté
switch (ledState) {
case 0: // LED Verte active
if (currentTime - lastToggle >= 1000) { // 1 seconde active
lastToggle = currentTime;
digitalWrite(A5, LOW); // Éteint la LED Verte
Serial.println("LED Verte éteinte.");
ledState = 1; // Passe à la pause
} else {
digitalWrite(A5, HIGH); // Allume la LED Verte
Serial.println("LED Verte active.");
}
break;
case 1: // Pause après LED Verte
if (currentTime - lastToggle >= 500) { // 0.5 seconde de pause
lastToggle = currentTime;
ledState = 2; // Passe à la LED Orange
}
break;
case 2: // LED Orange active
if (currentTime - lastToggle >= 1000) { // 1 seconde active
lastToggle = currentTime;
digitalWrite(A3, LOW); // Éteint la LED Orange
Serial.println("LED Orange éteinte.");
ledState = 3; // Passe à la pause
} else {
digitalWrite(A3, HIGH); // Allume la LED Orange
Serial.println("LED Orange active.");
}
break;
case 3: // Pause après LED Orange
if (currentTime - lastToggle >= 500) { // 0.5 seconde de pause
lastToggle = currentTime;
ledState = 0; // Retour à la LED Verte
}
break;
}
// Gestion des 3 appuis sur le bouton noir
if (!awaitingCode && isButtonPressed(7)) { // Bouton noir pressé
delay(200); // Anti-rebond
NbrBPN++;
Serial.print("Appuis sur le bouton noir : ");
Serial.println(NbrBPN);
if (NbrBPN >= 3) {
Serial.println("Entrer le code pour quitter l'alarme.");
awaitingCode = true; // Permet de saisir le code
EtpSaisieCode = 0; // Réinitialise la saisie
}
}
// Gestion de l'entrée du code pour désactivé
if (awaitingCode) {
for (int i = 0; i < 8; i++) {
if (isButtonPressed(i)) { // Nouveau bouton pressé
delay(200); // Anti-rebond
CodeSaisi[EtpSaisieCode] = buttonPins[i];
Serial.print("Touche pressée : ");
Serial.println(buttonPins[i]);
EtpSaisieCode++;
if (EtpSaisieCode == 4) { // Code complet
if (checkCode()) {
Serial.println("Code correct ! Alarme désactivée.");
// Réinitialisation après le bon code
CmptErreur = 0; // Réinitialise le compteur d'erreurs
NbrBPN = 0; // Réinitialise les appuis sur le bouton noir
awaitingCode = false; // Sort de la saisie du code
resetState(); // Retour à ATT
} else {
Serial.println("Code incorrect. Essayer à nouveau.");
EtpSaisieCode = 0; // Réinitialise la saisie pour retenter
}
}
return;
}
}
}
}
/**-----------------------------------------------------------------------------------*/
// Fonctions utilitaires
// Vérification du code : est-ce que le code entré = code demandé
bool checkCode() {
for (int i = 0; i < 4; i++) {
if (CodeSaisi[i] != CodeCorrect[i]) {
return false;
}
}
return true;
}
// Rénitialisation des étapes et rénitialsiation du tabelau d'entrée de code
void resetState() {
EtpSaisieCode = 0;
for (int i = 0; i < 4; i++) {
CodeSaisi[i] = -1;
}
currentState = ATT;
digitalWrite(A3, LOW);
digitalWrite(A4, LOW);
digitalWrite(A5, LOW);
}
bool isButtonPressed(int buttonIndex) {
bool currentState = digitalRead(buttonPins[buttonIndex]) == LOW;
if (currentState && buttonStates[buttonIndex]) {
buttonStates[buttonIndex] = false; // Marque le bouton comme pressé
return true;
} else if (!currentState) {
buttonStates[buttonIndex] = true; // Réinitialise l’état lorsque le bouton est relâché
}
return false;
}