/*Codage ENIGMA 2 avec encodeur.
On utilise les différents void readEncodeur pour le MDP, les clefs et le codage.
Affichage sur deux lignes.
Enigma MS-Electronics.
*/
#include "RotaryEncoder.h"
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27,16,2);
RotaryEncoder encoder(A2,A3); //DT,CLK
int lastPos;
int newPos;
int curSeur=3; //Curseur sur la 2ème ligne LCD.
int const resEt=0;
int const valiDe=3;
int const Bleue=6; //Led de confirmation visuelle de la prise en compte de la validation.
int const Buzzer=7; //Alarme si > 3 essais de MDP !
int const switchL=4; //position codage.
int const switchR=5; //position décodage.
int cleFduJour; //Addition des chiffres de la date => 1 ≤ clef ≤ 11.
int cleFduJourIncr=0; //Le premier codage décalle de la clef 1, les suivants de clef1+2.
int increMent; //incrémentation = jour de la semaine. LMMJVSD=1,2,3,4,5,6 ou 7.
int increMentSup=0; //3 ème incrément.
int NumRoulo=0;
int NoCaracter=1;
int NbBuzzer=0; //décompte des essais MDP.
char array_CodeBase [4] {'A','B','C','D'}; //mot de passe.
char array_CodeInser [4] {'0','0','0','0'}; //tableau de comparaison du mot de passe.
char selecTionAlphaNum;
char Tablo[42]= //Pour l'écriture des messages codés. Tableau 'char'
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N',
'O','P','Q','R','S','T','U','V','W','X','Y','Z','+','-','=','.','?','/',
'0','1','2','3','4','5','6','7','8','9'};
int TabloClef[11]= //Pour l'insertion des 2 clefs. Tableau 'int'
{1,2,3,4,5,6,7,8,9,10,11};
//bool lastDigit=false; //effacement des 4 derniers digits en cas d'overflow.
int Ligne=0;
int Decalage=0;
void setup() {
//Serial.begin(9600);
pinMode(resEt, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(Bleue, OUTPUT);
pinMode(valiDe, INPUT_PULLUP);
pinMode(switchL, INPUT_PULLUP);
pinMode(switchR, INPUT_PULLUP);
pinMode(Buzzer, OUTPUT);
digitalWrite(Bleue, LOW);
digitalWrite(13, LOW);
LCD.init(); // initialisation de l'afficheur
LCD.backlight();
LCD.setCursor(2, 0);
LCD.print("ENIGMA II by");
LCD.setCursor(1, 1);
LCD.print("MS-Electronics"); //Pub !!!
delay(1500);
LCD.noDisplay();
delay(300);
LCD.display();
delay(1500);
LCD.clear();
LCD.home();
LCD.print("This device is");
LCD.setCursor(0,1);
LCD.print("property of MS-E");
delay(2500);
LCD.clear();
}
void loop() {
AUTHENT1: //insertion du mot de passe pour identification.
NoCaracter=1;
encoder.setPosition(0);
for (int i=0;i<4;i++) {array_CodeInser[i]='0';} //remise à zéro du tableau.
LCD.home();
LCD.print("INSEREZ LE MOT");
LCD.setCursor(3,1);
LCD.print("DE PASSE.");
delay(1500);
LCD.clear();
AUTHENT2:
LCD.home();
LCD.print("Inserez MDP");
LCD.setCursor(13,0);
LCD.print(NoCaracter);
LCD.setCursor(2,1);
LCD.print("-/+=>Validez");
readEncoder1();
char selecTionAlphaNum=Tablo[newPos];
if(digitalRead(resEt)==LOW) {flash(); LCD.clear();goto AUTHENT1;}
if(digitalRead(valiDe)==HIGH) {goto AUTHENT2;}
else {flash(); //fonction void flash() créée pour flash Led Bleue, confirmation de la validation.
array_CodeInser[NoCaracter-1]={selecTionAlphaNum}; //-1 car le premier est 0 !
++NoCaracter;} //Incrément du No de caractère.
if(NoCaracter>=5) {goto AUTHENT3;}
goto AUTHENT2;
AUTHENT3:
if (!memcmp(array_CodeBase, array_CodeInser, 4)) //comparaison des 2 arrays.
{LCD.clear();LCD.setCursor(5,0);LCD.print("MATCH !"); delay(1100);goto ZERO1;}
else //sinon on recommence.
++NbBuzzer; //Incrément Buzzer.
if(NbBuzzer>=2) {tone(Buzzer,100,3000);} //Au 2ème mauvais MDP le Buzzer tone!
LCD.clear();
LCD.print("NO MATCH - RETRY");
delay(1500);
LCD.clear();
LCD.setCursor(5,0);
for(int i=0;i<4;i++) {LCD.print(array_CodeInser[i]);}
LCD.setCursor(2,1);
LCD.print("Press Reset");
while(digitalRead(resEt)==HIGH) {}
flash();
LCD.clear();
goto AUTHENT1;
ZERO1:
encoder.setPosition(0);
LCD.clear();
LCD.setCursor(4,0);
LCD.print("Insertion");
LCD.setCursor(3,1);
LCD.print("des 2 CLEFS");
delay(1500);
LCD.clear();
LCD.home();
LCD.print("Inserez Clef No1");
delay(1000);
ZERO2:
encoder.setPosition(0);
LCD.setCursor(2,1);
LCD.print("-/+=>Validez");
readEncoder2();
int cleFduJour=TabloClef[newPos];
if(digitalRead(resEt)==LOW) {goto ZERO1;}
if(digitalRead(valiDe)==HIGH) {goto ZERO2;}
else flash(); //fonction void flash() créée pour flash Led Bleue, confirmation de la validation.
LCD.clear();
LCD.home();
LCD.print("Inserez Clef No2");
delay(1000);
encoder.setPosition(-41);
ZERO3:
encoder.setPosition(0);
LCD.setCursor(2,1);
LCD.print("-/+=>Validez");
readEncoder3();
int increMent=TabloClef[newPos];
if(digitalRead(resEt)==LOW) {goto ZERO1;}
if(digitalRead(valiDe)==HIGH) {goto ZERO3;}
else flash();
LCD.clear();
LCD.setCursor(2,0);
LCD.print("Clefs");
LCD.setCursor(8,0);
LCD.print(cleFduJour);
LCD.setCursor(10,0);
LCD.print("/");
LCD.setCursor(11,0);
LCD.print(increMent);
delay(1000);
ZERO4: //Validation des deux clefs.
LCD.setCursor(0,1);
LCD.print("VALIDEZ ou RESET");
if(digitalRead(resEt)==LOW) {goto ZERO1;} //Si erreur on recommence.
if(digitalRead(valiDe)==HIGH) {goto ZERO4;}
else flash();
//modif pour 3 ème incrément.Augmenter la première incrémentation si paramètres <= à 3.
if(cleFduJour<=3 ||increMent<=3) {increMentSup=7;}
else {increMentSup=2;}
Decalage=cleFduJour+increMent; //rajouté le 2 oct 24.
SWITCH: //inverseur permettant de choisir la fonction codage/décodage.
curSeur=3; //Pour le Reset il faut appuyer Rouge et maintenir puis Valide.
Ligne=0;
Decalage=0;
if(digitalRead(switchL)==LOW) {goto CODE;}
else {goto DECODE;}
CODE: //Codage
LCD.clear();
LCD.setCursor(5,0);
LCD.print("CODAGE");
LCD.setCursor(5,1);
LCD.print(cleFduJour);
LCD.setCursor(7,1);
LCD.print(" / ");
LCD.setCursor(10,1);
LCD.print(increMent);
delay(2000);
LCD.clear();
LCD.setCursor(3,0);
LCD.print("TO DECODE");
LCD.setCursor(0,1);
LCD.print("SWITCH and RESET");
delay(2000);
LCD.clear();
LCD.print("+/- => Validez");
delay(1500);
LCD.clear();
cleFduJourIncr=cleFduJour+increMentSup; // incrément Sup !!!
encoder.setPosition(0);
ONE: //boucle ONE pour choisir le caractère alphanumérique à coder.
readEncoder4(); //on utilise la void readEncoder pour faire défiler les alphanum.
if(digitalRead(resEt)==LOW) {goto SWITCH;newPos=0;} //Il faut appuyer sur Reset et Valide car
selecTionAlphaNum=Tablo[newPos]; //...sinon on est bloqué dans la void readEncoder.
//modif affichage LCD.
LCD.setCursor(0,0);
LCD.print(selecTionAlphaNum);
TWO: //Calcul du code
NumRoulo=newPos+cleFduJourIncr;
if(NumRoulo>41) {NumRoulo=NumRoulo-42;}
//Modification affichage LCD.
LCD.setCursor(1,0);
LCD.print("=>");
LCD.setCursor(curSeur,Ligne);
LCD.print(Tablo[NumRoulo]);
curSeur++;
if(curSeur>15 && Ligne==0) {curSeur=3;Ligne=1;}
if(curSeur>16 && Ligne==1) {goto SIX;}
flash();
cleFduJourIncr=cleFduJourIncr+increMent; //Calcul du décalage total.
if(cleFduJourIncr>39) {cleFduJourIncr=Decalage++;} //décalage sup.
goto ONE;
DECODE: //Décodage.
LCD.clear();
LCD.setCursor(4,0);
LCD.print("DECODAGE");
LCD.setCursor(5,1);
LCD.print(cleFduJour);
LCD.setCursor(7,1);
LCD.print(" / ");
LCD.setCursor(10,1);
LCD.print(increMent);
delay(2000);
LCD.clear();
LCD.setCursor(3,0);
LCD.print("TO CODE");
LCD.setCursor(0,1);
LCD.print("SWITCH and RESET");
delay(2000);
LCD.clear();
LCD.print("+/- => Validez");
delay(1500);
LCD.clear();
cleFduJourIncr=cleFduJour+increMentSup; // incrément Sup!!!
encoder.setPosition(0);
FOUR:
readEncoder4();
if(digitalRead(resEt)==LOW) {goto SWITCH;newPos=0;} //il faut appuyer simultanément sur Valide et Reset à
selecTionAlphaNum=Tablo[newPos]; //...cause de la boucle readEncoder1.
LCD.setCursor(0,0);
LCD.print(selecTionAlphaNum);
FIVE:
NumRoulo=newPos-cleFduJourIncr; //Calcul du code.
if(NumRoulo<0) {NumRoulo=NumRoulo+42;}
LCD.setCursor(1,0);
LCD.print("=>");
LCD.setCursor(curSeur,Ligne);
LCD.print(Tablo[NumRoulo]);
curSeur++;
if(curSeur>15 && Ligne==0) {curSeur=3;Ligne=1;}
if(curSeur>16 && Ligne==1) {goto SIX;}
flash();
cleFduJourIncr=cleFduJourIncr+increMent;
if(cleFduJourIncr>39) {cleFduJourIncr=Decalage++;}
goto FOUR;
SIX:
LCD.clear();
delay(200);
LCD.print(" -RESET-");
delay(1500);
goto SWITCH;
}
void flash(){ //Fonction clignotement Led Bleue lors des validations.
digitalWrite(Bleue, HIGH);
delay(500);
digitalWrite(Bleue, LOW);
}
void readEncoder1() { //Utilisé pour le Mot de passe AUTHENT2.
TEN:
encoder.tick();
newPos = encoder.getPosition();
if(newPos<0){
encoder.setPosition(41);
newPos=41;}
else if (newPos>41){
encoder.setPosition(0);
newPos=-0;}
if (lastPos != newPos) {lastPos = newPos;}
char selecTionAlphaNum=Tablo[newPos];
LCD.setCursor(0,1);
LCD.print(selecTionAlphaNum);
if(digitalRead(valiDe)==HIGH){goto TEN;}
}
void readEncoder2() { //Clef 1. ZERO2:
TEN:
encoder.tick();
newPos = encoder.getPosition();
if(newPos<0){
encoder.setPosition(10);
newPos=10;}
else if (newPos>10){
encoder.setPosition(0);
newPos=0;}
if (lastPos != newPos) {lastPos = newPos; }
int cleFduJour=TabloClef[newPos];
LCD.setCursor(0,1);
LCD.print(cleFduJour);
if(cleFduJour<10) {LCD.setCursor(1,1);LCD.print(" ");}
if(digitalRead(valiDe)==HIGH){goto TEN;}
}
void readEncoder3() { //Clef 2. ZERO3:
TEN:
encoder.tick();
newPos = encoder.getPosition();
if(newPos<0){
encoder.setPosition(6);
newPos=6;}
else if (newPos>6){
encoder.setPosition(0);
newPos=0;}
if (lastPos != newPos) {lastPos = newPos; }
int increMent=TabloClef[newPos];
LCD.setCursor(0,1);
LCD.print(increMent);
if(digitalRead(valiDe)==HIGH){goto TEN;}
}
void readEncoder4() { //Utilisé pour Codage / Décodage.
TEN:
encoder.tick();
newPos = encoder.getPosition();
if(newPos<0){
encoder.setPosition(41);
newPos=41;}
else if (newPos>41){
encoder.setPosition(0);
newPos=-0;}
if (lastPos != newPos) {lastPos = newPos;}
char selecTionAlphaNum=Tablo[newPos];
LCD.setCursor(0,0);
LCD.print(selecTionAlphaNum);
if(digitalRead(valiDe)==HIGH){goto TEN;}
}