/* ------------------------COFFRE FORT
Clavier 4x4 : Chaque touche appuyée est lue par l’Arduino et ajoutée à une chaîne de caractères enteredCode.
Validation du code : Si l'utilisateur appuie sur #, le code entré est comparé au code correct.

    Si le code est correct, le servomoteur bouge pour déverrouiller.
    Si le code est incorrect, le buzzer émet un son pour signaler l'erreur.

Bouton de réinitialisation (*) : Permet de réinitialiser le code entré.

Détection de l'état du coffre :
        Si le coffre est déjà ouvert et que l'utilisateur entre le code correct à nouveau, la fonction verrouillerCoffre() est appelée pour fermer le coffre.
        Si le coffre est fermé, le code correct déverrouille le coffre avec la fonction unlockCoffre().

Cela permet de verrouiller et déverrouiller le coffre avec le même code, selon son état actuel.

--------------------------CONNECTIONS
Clavier 4x4 (Keypad) :

    R1 → D2
    R2 → D3
    R3 → D4
    R4 → D5
    C1 → D6
    C2 → D7
    C3 → D8
    C4 → D9

Servomoteur :

    Signal → D10
    VCC → 5V
    GND → GND

Buzzer :

    Signal → D11
    VCC → 5V
    GND → GND*/

#include <Keypad.h>
#include <Servo.h>

// Configuration du clavier 4x4
const byte ROWS = 4; // 4 rangées
const byte COLS = 4; // 4 colonnes
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; // Connexion des lignes du keypad aux pins D2-D5
byte colPins[COLS] = {6, 7, 8, 9}; // Connexion des colonnes du keypad aux pins D6-D9

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// Code correct à entrer
String correctCode = "123AD";
String enteredCode = "";

// Configuration du servomoteur et du buzzer
Servo myServo;
int buzzerPin = 11; // Pin du buzzer
int servoPin = 10;  // Pin du servomoteur
bool coffreOuvert = false; // Variable pour suivre l'état du coffre

void setup() {
  Serial.begin(9600);  // Initialisation de la communication série
  myServo.attach(servoPin);  // Initialisation du servomoteur sur la pin D10
  verrouillerCoffre();       // Verrouiller le coffre au démarrage
  pinMode(buzzerPin, OUTPUT); // Configuration du buzzer en sortie
}

void loop() {
  char key = keypad.getKey(); // Lire la touche pressée

  if (key) {
    if (key == '#') { // '#' est utilisé pour vérifier le code entré
      if (enteredCode == correctCode) {
        Serial.println("Code correct");
        if (coffreOuvert) {
          verrouillerCoffre(); // Verrouiller si le coffre est déjà ouvert
        } else {
          unlockCoffre(); // Déverrouiller si le coffre est fermé
        }
      } else {
        Serial.println("Code incorrect");
        alertBuzzer();
      }
      enteredCode = ""; // Réinitialiser le code entré après vérification
    } else if (key == '*') { // '*' est utilisé pour effacer l'entrée
      enteredCode = "";
      Serial.println("Code réinitialisé");
    } else {
      enteredCode += key; // Ajouter la touche pressée au code entré
      Serial.println("Code actuel: " + enteredCode);
    }
  }
}

// Fonction pour déverrouiller le coffre
void unlockCoffre() {
  myServo.write(90);  // Tourner le servomoteur pour déverrouiller (angle 90)
  coffreOuvert = true; // Marquer le coffre comme ouvert
  Serial.println("Coffre déverrouillé.");
}

// Fonction pour verrouiller le coffre
void verrouillerCoffre() {
  myServo.write(0);    // Retourner à la position verrouillée (angle 0)
  coffreOuvert = false; // Marquer le coffre comme fermé
  Serial.println("Coffre verrouillé.");
}

// Fonction pour alerter avec le buzzer en cas de code incorrect
void alertBuzzer() {
  for (int i = 0; i < 3; i++) {
    tone(buzzerPin, 1000);  // Émettre un son à 1000 Hz
    delay(500);             // Attendre 500ms
    noTone(buzzerPin);      // Arrêter le son
    delay(500);             // Attendre 500ms avant de refaire le son
  }
}