/*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.
Suppression du Serial.begin(9600) pour faciliter la lecture sur iPhone. Ne fonctionne pas.
C'est le Bp moins qui met le bazar car branché sur la Pin 1 TX. Il faut changer la brochage !!!
*/
#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=8; //modifié de 1 à 8 !!!
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(8, INPUT_PULLUP); //modifié de 1 à 8 !!!
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);
}