// ***************************************************** // *** Serrure de GN hackable - version 3.0 // *** Marcelin Delcour, 01-2017 // *** mathkuma (_@_) gmail (_._) com // ***************************************************** #include #include //on definit les etats possible de la serrure #define FERMEE 0 // serrure fermée #define OUVERTE 1 // serrure ouverte #define BLOQUEE 2 // la serrure est bloquée pendant X secondes #define TAILLEMAX 8 struct SERRURE_STRUCT { char code[TAILLEMAX]; int longCode; int erreurMax; int bloqueeDelai; int statutSerrure; int backup; }; // ***************************************************** // *** // *** Paramètres modifiables via le clavier // *** // ***************************************************** SERRURE_STRUCT mySerrure { "12345678", // mot de passe par defaut : 12345678 , chiffre de 0 à 9 ou A, B, C, D 4, // nombre de caracteres dans le code, !! entre 1 et 8 !! 3, // nombre d'erreur de code autorisées avant blocage 10, // delai pendant lequel la serrure sera bloquee, en secondes FERMEE, // état de la serrure, 0 fermée, 1 ouverte, 2 bloquée 666 // marqueur de backup eeprom, pas touche !! }; // ***************************************************** // *** Fonctions, serrure en mode OUVERTE // *** appui long sur A -> changement du code, appuyer sur X characteres // *** appui long sur B -> changement du nombre max d erreur, entrer le nouveau nombre + # pour valider // *** appui long sur C -> changement du delai de blocage, entrer le delai + # pour valider // *** appui long sur D -> changement de la longueur du code, entre 1 et 8 // ***************************************************** // ***************************************************** // *** Fonction accessible pendant les 3 secondes qui suivent l'allumage // *** appui simple sur # -> pour réinitialiser l'eeprom avec les parametres par defaut (voir SERRURE_STRUCT serrureDefaut) // ***************************************************** // on initialise une struct serrrue avec les valeurs par defaut SERRURE_STRUCT serrureDefaut { "12345678", // mot de passe par defaut : 123456789 , chiffre de 0 à 9 ou A, B, C, D 4, // nombre de caracteres dans le code, !! entre 1 et 8 !! 3, // nombre d'erreur de code autorisées avant blocage 10, // delai pendant lequel la serrure sera bloquee, en secondes FERMEE, // état de la serrure, 0 fermée, 1 ouverte, 2 bloquée 666 // marqueur de backup eeprom, pas touche !! }; // hack int reed[3]={A0, A1, A2}; int reedStatut[3]={0,0,0}; int reedStatutPrec[3]={0,0,0}; bool testReed=true; bool uneFois=true; // on definit les variables du clavier const byte ROWS = 4; //four rows const byte COLS = 4; //four columns char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'#','0','#','D'} }; byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // on definit les 2 LED int ledVerte = 11; int ledRouge = 12; bool etatLed = false; // on definit le buzzer int buzzerPin = 10; int statusSerrurePrecedent=FERMEE; int mauvaisCodeCpt=0; int paniqueCpt=0; int nouveauCodeCpt=0; bool codeOK = false; bool nouveauCodeOK = false; bool nouveauErreurMaxOK = false; bool nouveauBloqueeDelaiOK = false; bool nouveauLongCodeOK = false; char codeTempo[TAILLEMAX]={'0','0','0','0','0','0','0','0'}; unsigned long int ul_PreviousMillisCP; int ledCpt=0; int ledStatut=HIGH; void setup() { // on initialise la sortie serie pour debug Serial.begin(9600); // LED pinMode(ledVerte, OUTPUT); pinMode(ledRouge, OUTPUT); majLed(ledVerte, LOW); majLed(ledRouge, HIGH); // buzzer pinMode(buzzerPin, OUTPUT); // listener pour gerer les appuis longs keypad.addEventListener(keypadEvent); keypad.setHoldTime(2000); // initialisation des reed for (int i=0;i<3;i++) { pinMode(reed[i], INPUT); digitalWrite(reed[i], HIGH); reedStatut[i]=digitalRead(reed[i]); reedStatutPrec[i]=reedStatut[i]; } // init time reference ul_PreviousMillisCP = millis(); // Check param mySerrure.longCode=max(min(mySerrure.longCode,8),1); // GESTION EEPROM // RESET // 3 secondes pour appuyer sur # et reset l'eeprom beep(); int resetCpt=0; while(millis()-ul_PreviousMillisCP<3000) { char key = keypad.getKey(); if (key) { if (key == '#') { Serial.println("RESET EEPROM"); // on ecrit les données de la serrure par defaut EEPROM.put(0, serrureDefaut); Serial.println("RESET EEPROM OK OK"); beep(); delay(150); beep(); delay(150); } } resetCpt++; if (resetCpt>10000) { ledStatut=!ledStatut; majLed(ledVerte, ledStatut); majLed(ledRouge, ledStatut); resetCpt=0; } } EEPROM.get(0, mySerrure); // 1ERE UTILISATION // premiere utilisation, on ecrit mySerrure dans l'eeprom if (mySerrure.backup!=666) { backupToEEPROM(); Serial.println("1ERE UTILISATION, EEPROM OK"); } // LECTURE DEPUIS EEPROM EEPROM.get(0, mySerrure); Serial.print("code: "); for (int i=0;i=mySerrure.erreurMax) { statusSerrurePrecedent=mySerrure.statutSerrure; mySerrure.statutSerrure=BLOQUEE; paniqueCpt=0; Serial.println("Serrure en mode bloquee"); } } for (int i=0;i(mySerrure.bloqueeDelai*10)) { mySerrure.statutSerrure=statusSerrurePrecedent; mauvaisCodeCpt=0; paniqueCpt=0; } } void blinkLed() { for (int i=0;i<5;i++) { majLed(ledVerte, HIGH); majLed(ledRouge, LOW); delay(150); majLed(ledVerte, LOW); majLed(ledRouge, HIGH); delay(150); } } void majLed(int led, int etat) { digitalWrite(led, etat); } void beep() { tone(buzzerPin, 1000, 50); } void longBeep() { // 1 seconde tone(buzzerPin, 500, 1000); } // Taking care of some special events. void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case HOLD: // si la serrure est a l'etat ouvert if (mySerrure.statutSerrure == OUVERTE) { // appui long sur A, on change le code if (key == 'A') { beep(); nouveauCodeCpt=0; nouveauCodeOK=false; nouveauCode(); backupToEEPROM(); } // appui long sur B, on change le nombre max d'erreur if (key == 'B') { beep(); nouveauErreurMaxOK=false; mySerrure.erreurMax=0; nouveauErreurMax(); backupToEEPROM(); } // appui long sur C, on change le delai de blocage if (key == 'C') { beep(); nouveauBloqueeDelaiOK=false; mySerrure.bloqueeDelai=0; nouveauBloqueeDelai(); backupToEEPROM(); } // appui long sur D, on change la taille du code if (key == 'D') { beep(); nouveauLongCodeOK=false; mySerrure.longCode=0; nouveauLongCode(); backupToEEPROM(); } } break; } } // changement de code void nouveauCode() { Serial.println("A - changement de code"); majLed(ledVerte, HIGH); majLed(ledRouge, HIGH); while(!nouveauCodeOK) { char key = keypad.getKey(); if (key) { if (key != '#') { mySerrure.code[nouveauCodeCpt]=key; nouveauCodeCpt+=1; beep(); } } if (nouveauCodeCpt==mySerrure.longCode) { nouveauCodeOK=true; Serial.print("code change: "); for (int i=0;i=48 && key<=57) { // nouveau nombre d erreur mySerrure.erreurMax*=10; mySerrure.erreurMax+=(key-48); beep(); } else { if (key == '#') { nouveauErreurMaxOK=true; beep(); delay(100); beep(); mauvaisCodeCpt=0; if (mySerrure.erreurMax == 0) { mySerrure.erreurMax=1; } Serial.print("nouveau nb d erreur: "); Serial.println(mySerrure.erreurMax); } } } ledCpt++; if (ledCpt>10000) { ledStatut=!ledStatut; majLed(ledRouge, ledStatut); ledCpt=0; } } } // changement du delai de blocage void nouveauBloqueeDelai() { Serial.println("C - changement du delai de blocage"); majLed(ledVerte, HIGH); majLed(ledRouge, HIGH); int ledCpt=0; int ledStatut=HIGH; while(!nouveauBloqueeDelaiOK) { char key = keypad.getKey(); if (key) { // ascii code, 0=48, 9=57 if (key>=48 && key<=57) { // nouveau nombre d erreur mySerrure.bloqueeDelai*=10; mySerrure.bloqueeDelai+=(key-48); beep(); } else { if (key == '#') { nouveauBloqueeDelaiOK=true; beep(); delay(100); beep(); paniqueCpt=0; Serial.print("nouveau delai: "); Serial.println(mySerrure.bloqueeDelai); } } } ledCpt++; if (ledCpt>10000) { ledStatut=!ledStatut; majLed(ledVerte, ledStatut); ledCpt=0; } } } // changement de la taille du code void nouveauLongCode() { Serial.println("D - changement de la taille du code"); majLed(ledVerte, HIGH); majLed(ledRouge, HIGH); int ledCpt=0; int ledStatut=HIGH; while(!nouveauLongCodeOK) { char key = keypad.getKey(); if (key) { // taille min=1, taille max=8 // ascii code, 1=49, 8=56 if (key>=49 && key<=56) { // nouvelle taille mySerrure.longCode=(key-48); nouveauLongCodeOK=true; beep(); delay(100); beep(); paniqueCpt=0; Serial.print("nouvelle taille du code: "); Serial.println(mySerrure.longCode); // on reinitialise le code à "12345678" for (int i=0;i10000) { ledStatut=!ledStatut; majLed(ledVerte, ledStatut); majLed(ledRouge, ledStatut); ledCpt=0; } } } void backupToEEPROM() { // for (int i=0;i<8;i++) // { // mySerrure.code[i]=code[i]; // } // // mySerrure.longCode=longCode; // mySerrure.erreurMax=erreurMax; // mySerrure.bloqueeDelai=bloqueeDelai; // mySerrure.statutSerrure=statutSerrure; // mySerrure.backup=666; EEPROM.put(0, mySerrure); }