/*Codage avec une machine du type ENIGMA
Affichage direct du décodage sur 2 lignes.
Rajout de la variable Decalage permet 16 codages se suivant différents pour
le même alphanumérique.
*/
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27,16,2);
int curSeur=3;
int const resEt=0; //4 Bp.
int const moiNs=1;
int const plUs=2;
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 switchL=4; //position codage.
int switchR=5; //position décodage.
int choiX=0;
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] {'J','3','+','Y'}; //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 LCD en cas d'overflow.
int Ligne=0; //ligne LCD, 0 ou 1.
int Decalage=0;
void setup() {
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(6, OUTPUT);
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(3, 0);
LCD.print("ENIGMA by");
LCD.setCursor(1, 1);
LCD.print("MS-Electronics"); //Pub !!!
delay(1500);
LCD.noDisplay();
delay(300);
LCD.display();
delay(1500);
LCD.clear();
LCD.setCursor(2,0);
LCD.print("Joint Venture");
LCD.setCursor(6,1);
LCD.print("with");
delay(1500);
LCD.clear();
LCD.setCursor(4,0);
LCD.print("FFP - C");
LCD.setCursor(2,1);
LCD.print("B29 PROJECT");
delay(2500);
LCD.home();
LCD.print("This device is");
LCD.setCursor(0,1);
LCD.print("property of MS-E");
delay(2500);
LCD.clear();
Serial.begin(9600);
}
void loop() {
AUTHENT1: //insertion du mot de passe pour identification.
NoCaracter=1;
choiX=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(1350);
LCD.clear();
AUTHENT2:
LCD.home();
LCD.print("Inserez MDP");
LCD.setCursor(13,0);
LCD.print(NoCaracter);
if(digitalRead(plUs)==LOW) {choiX=++choiX; delay(100);} //delay d'incrément ou décrément.
if(digitalRead(moiNs)==LOW) {choiX=--choiX; delay(100);}
if(choiX<0) {choiX=41;}
if(choiX>41) {choiX=0;}
char selecTionAlphaNum=Tablo[choiX];
if(digitalRead(resEt)==LOW) {flash(); LCD.clear();goto AUTHENT1;}
LCD.setCursor(0,1);
LCD.print(selecTionAlphaNum);
LCD.setCursor(2,1);
LCD.print("-/+=>Validez");
delay(200);
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};
++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:
choiX=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:
if(digitalRead(plUs)==LOW) {choiX=++choiX; delay(100);} //delay d'incrément ou décrément.
if(digitalRead(moiNs)==LOW) {choiX=--choiX; delay(100);}
if(choiX<0) {choiX=10;}
if(choiX>10) {choiX=0;}
int cleFduJour=TabloClef[choiX];
if(digitalRead(resEt)==LOW) {goto ZERO1;}
LCD.setCursor(0,1);
LCD.print(cleFduJour);
if(cleFduJour<10) {LCD.setCursor(1,1);LCD.print(" ");}
LCD.setCursor(3,1);
LCD.print("-/+=>Validez");
delay(200);
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);
choiX=0;
ZERO3:
if(digitalRead(plUs)==LOW) {choiX=++choiX; delay(100);} //delay d'incrément ou décrément.
if(digitalRead(moiNs)==LOW) {choiX=--choiX; delay(100);}
if(choiX<0) {choiX=6;} //Clef N°2 = N° du jour soit 1 à 7.
if(choiX>6) {choiX=0;}
int increMent=TabloClef[choiX];
if(digitalRead(resEt)==LOW) {goto ZERO1;}
LCD.setCursor(0,1);
LCD.print(increMent);
if(increMent<10) {LCD.setCursor(1,1);LCD.print(" ");}
LCD.setCursor(3,1);
LCD.print("-/+=>Validez");
delay(200);
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;
lastDigit=0;
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");
//modif affichage
delay(1500);
LCD.clear();
cleFduJourIncr=cleFduJour+increMentSup; // incrément Sup !!!
choiX=0;
ONE: //boucle ONE pour choisir le caractère alphanumérique à coder.
if(digitalRead(plUs)==LOW) {choiX=++choiX; delay(100);} //delay d'incrément ou décrément.
if(digitalRead(moiNs)==LOW) {choiX=--choiX; delay(100);}
if(choiX<0) {choiX=41;}
if(choiX>41) {choiX=0;}
if(digitalRead(resEt)==LOW) {goto SWITCH;choiX=0;}
selecTionAlphaNum=Tablo[choiX];
//modif affichage
LCD.setCursor(0,0);
LCD.print(selecTionAlphaNum);
delay(200);
if(digitalRead(valiDe)==LOW) {flash();goto TWO;} //si validation.
else {goto ONE;}
TWO: //Calcul du code
if(digitalRead(resEt)==LOW) {goto SWITCH;choiX=0;}
NumRoulo=choiX+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;}
cleFduJourIncr=cleFduJourIncr+increMent; //Calcul du décalage total.
if(cleFduJourIncr>39) {cleFduJourIncr=Decalage++;}
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");
//Modif affichage
delay(1500);
LCD.clear();
cleFduJourIncr=cleFduJour+increMentSup; // incrément Sup!!!
choiX=0;
FOUR:
if(digitalRead(plUs)==LOW) {choiX=++choiX; delay(100);} //delay d'incrément ou décrément.
if(digitalRead(moiNs)==LOW) {choiX=--choiX; delay(100);}
if(choiX<0) {choiX=41;}
if(choiX>41) {choiX=0;}
if(digitalRead(resEt)==LOW) {goto SWITCH;choiX=0;}
selecTionAlphaNum=Tablo[choiX];
LCD.setCursor(0,0);
LCD.print(selecTionAlphaNum);
delay(200);
if(digitalRead(valiDe)==LOW) {flash();goto FIVE;} //si validation.
else {goto FOUR;}
FIVE:
if(digitalRead(resEt)==LOW) {goto SWITCH;choiX=0;}
NumRoulo=choiX-cleFduJourIncr; //Calcul du code.
if(NumRoulo<0) {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;}
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);
}