/* REPLICA ENIGMA M3 M4 by double wrap April 2015 codec core by arduinoenigma.blogspot.it pin 0,1 tx,rx pin 2 led: lampeggia su codice remoto ricevuto pin 3,4,5,6,7,8 lcd pin 9 sensore ir pin 10,11,12,13 sd card */ #define STR_EXPAND(tok) #tok #define STR(tok) STR_EXPAND(tok) #ifndef INT16U #define INT16U unsigned short #endif #include #include #include #include byte led=2; // led su pin 2 LiquidCrystal lcd(4,3,5,6,7,8); // lcd su pin RS,E,D4,D5,D6,D7 byte RECV_PIN = 9; // sensore IR su pin 9 const int chipSelect=10; // sd card su pin 10 e SPI su pin 11,12,13 //================================================================================ //http://arduinoenigma.blogspot.it/2014/10/source-code-for-implementation-of.html //================================================================================= // ABCDEFGHIJKLMNOPQRSTUVWXYZ #define ROTOR1 R-EKMFLGDQVZNTOWYHXUSPAIBRCJ #define ROTOR2 F-AJDKSIRUXBLHWTMCQGZNPYFVOE #define ROTOR3 W-BDFHJLCPRTXVZNYEIWGAKMUSQO #define ROTOR4 K-ESOVPZJAYQUIRHXLNFTGKDCMWB #define ROTOR5 A-VZBRGITYUPSDNHLXAWMJQOFECK #define ROTOR6 ANJPGVOUMFYQBENHZRDKASXLICTW #define ROTOR7 ANNZJHGRCXMYSWBOUFAIVLPEKQDT #define ROTOR8 ANFKQHTLXOCBJSPDZRAMEWNIUYGV #define ROTORB --LEYJVCNIXWPBQMDRTAKZGFUHOS #define ROTORG --FSOKANUERHMBTIYCWLQPZXVGJD #define ETW --ABCDEFGHIJKLMNOPQRSTUVWXYZ #define UKWA --EJMZALYXVBWFCRQUONTSPIKHGD #define UKWB --YRUHQSLDPXNGOKMIEBFZCWVJAT #define UKWC --FVPJIAOYEDRZXWGCTKUQSBNMHL #define UKWBD --ENKQAUYWJICOPBLMDXZVFTHRGS #define UKWCD --RDOBJNTKVEHMLFCWZAXGYIPSUQ const __FlashStringHelper * WHEELSF; const __FlashStringHelper * UHRSF; const __FlashStringHelper * UHRPLUGSF; char EffSTECKER[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; byte WHEELPOS[4] = {'A', 'A', 'A', 'A'}; char KeyPressed = 0; char EncodedKey = 0; byte SerialSetWheels = 0; // segnala se Enigma I/M3 o enigma M4 struct enigmaData_t{ byte SerialFunction; byte Uhr; char PAIRS[27]; char STECKER[27]; byte WHEELTYPE[6]; byte WHEELPOS[4]; byte ROTORPOS[4]; } EnigmaData; //================================================================================= //http://arduinoenigma.blogspot.it/2014/10/source-code-for-implementation-of.html //================================================================================= //variabili per display lcd const char sep1='*'; const char sep2='-'; const char blank=' '; const byte num_space=4; // spaziatore caratteri 5 per Enigma I e 4 per Enigma M3 ed M4// contatore per spaziatura blocchi byte num_car=1; char data[17]=" "; // buffer scorrevole del display 16 caratteri char schermo_0[17]; // buffer per configurazione riga 0 char schermo_1[17]; // buffer per configurazione riga 1 const int curs_rot_c=6; //colonna lettere rotori const int curs_rot_r=0; //riga lettere rotori byte rot0=1; byte rot1=1; byte rot2=2; byte rot3=3; // variabili per SD card File Dati; byte wheel_mem[4]; // memoria lettere esterne // codici del telecomando bravo B308 codifica RC5 const int KUP= 12; const int KDN= 13; const int KOK= 58; // ^ , v , > const int KLD= 16; const int KSV= 17; const int KRE= 53; //load , save , reset const int KVI= 54; // visualizza configurazione char tastiera[66]="X PAQ YSW H-- L-- JN M B ED - ZUI VKGOC T - - R F@"; //codici unita 01234567890123456789012345678901234567890123456789012345678901234 //codici decine 0 1 2 3 4 5 6 6 // variabili per ricevitore IR IRrecv irrecv(RECV_PIN); decode_results results; boolean flag1=false; boolean flag2=false; int codice=64; int codice_old=64; char tasto; //========================================================== void setup() { pinMode(led,OUTPUT); lcd.begin(16, 2); lcd.setCursor(0,0); for (int kk=15;kk>=0;kk--) lcd.print(sep1); lcd.setCursor(0,1); for (int kk=15;kk>=0;kk--) lcd.print(sep1); delay(500); lcd.clear(); Serial.begin(9600); irrecv.enableIRIn(); Wire.begin(); if (!SD.begin(chipSelect)){ lcd.setCursor(3,1); lcd.print("NO SD ALT!"); while(true) {}//blocca tutto } if (!SD.exists("enigma.txt")) { lcd.setCursor(3,1); lcd.print("NO FILE ALT!"); while(true) {} //blocca tutto } //================================================================================ //http://arduinoenigma.blogspot.it/2014/10/source-code-for-implementation-of.html //================================================================================= WHEELSF = F(STR(ROTOR1) STR(ROTOR2) STR(ROTOR3) STR(ROTOR4) STR(ROTOR5) STR(ROTOR6) STR(ROTOR7) STR(ROTOR8) STR(ROTORB) STR(ROTORG) STR(ETW) STR(UKWA) STR(UKWB) STR(UKWC) STR(UKWBD) STR(UKWCD)); UHRSF = F("\x06\x1F\x04\x1D\x12\x27\x10\x19\x1E\x17\x1C\x01\x26\x0B\x24\x25\x1A\x1B\x18\x15\x0E\x03\x0C\x11\x02\x07\x00\x21\x0A\x23\x08\x05\x16\x13\x14\x0D\x22\x0F\x20\x09"); UHRPLUGSF = F("\x06\x00\x07\x05\x01\x08\x04\x02\x09\x03"); //initEnigma(); // inizializzazione del codice open source, sostituita la leggi_sd() //================================================================================ //http://arduinoenigma.blogspot.it/2014/10/source-code-for-implementation-of.html //================================================================================= leggi_sd(); for (byte i = 0; i < 4; i++) wheel_mem[i]=WHEELPOS[i]; //inizializza la memoria //ShowRotors(); } // close setup //========================================================== void loop() { Out_rotor(WHEELPOS[0],WHEELPOS[1],WHEELPOS[2],WHEELPOS[3]); flag1=false; if(irrecv.decode(&results)){ digitalWrite(led,LOW); delay(50); digitalWrite(led,HIGH); codice=results.value; irrecv.resume(); if(codice!=codice_old) flag1=true; else flag1=false; codice_old=codice; } if (codice>2047) codice-=2048; // elimina il bit 12 del protocollo RC5 if(flag1){ if(codice==KUP || codice==KDN)upd_from_sensor(curs_rot_c, curs_rot_r); else if(codice==KLD || codice==KSV || codice==KRE || codice==KVI)do_funzione(codice); else { // --> il codice non è un comando tasto=tastiera[codice]; // converte i codici del telecomando in caratteri if ((tasto > 'A' - 1) && (tasto < 'Z' + 1)) { MoveWheels(); // RUOTA I ROTORI tasto= EncodeKey(tasto); // CODIFICA IL CARATTERE //Serial.print(tasto); scorri_dsp(tasto); // fa scorrere la riga inferiore del display num_car++; // spazia ogni num_space caratteri if (num_car>num_space){ tasto=blank; scorri_dsp(tasto); num_car=1; } } //close if tasto >A } //chiude else codice= carattere } // chiude flag1 delay(100); } // CLOSE LOOP //================================================================= void scorri_dsp(char carattere){ for (int kk=16;kk>=0;kk--) data[kk+1]=data[kk]; data[0]=carattere; lcd.setCursor(0,1); for (int kk=15;kk>=0;kk--) lcd.print(data[kk]); } //------------------------------------- void upd_from_sensor(int x,int y){ if(SerialSetWheels==4){ rot0=WHEELPOS[0]; rot0 = read_sensor(rot0,x,y); WHEELPOS[0] = rot0; } rot1=WHEELPOS[1]; rot1 = read_sensor(rot1,x+1,y); WHEELPOS[1] = rot1; rot2=WHEELPOS[2]; rot2 = read_sensor(rot2,x+2,y); WHEELPOS[2] = rot2; rot3=WHEELPOS[3]; rot3 = read_sensor(rot3,x+3,y); WHEELPOS[3] = rot3; } //------------------------ int read_sensor(int wk, int col, int rg){ unsigned int code_value; const int mx_Value=26+64; const int min_Value=1+64; while (true){ lcd.setCursor(col,rg); lcd.blink(); if (irrecv.decode(&results)) { digitalWrite(led,LOW); code_value = results.value; if (code_value>2047) code_value-=2048; delay(100); digitalWrite(led,HIGH); irrecv.resume(); if (code_value == KUP) wk ++; if (code_value == KDN) wk --; if (wk > mx_Value) wk = min_Value; if (wk < min_Value) wk = mx_Value; lcd.write(wk); if (code_value == KOK) { lcd.noBlink(); return wk; } } // chiude if riceve } // chiude while } // chiude funzione //-------------------------------- void Out_rotor(char r0, char r1,char r2, char r3){ lcd.setCursor(curs_rot_c,curs_rot_r); if(SerialSetWheels==4) lcd.write(r0); // 4^ruota lcd.setCursor(curs_rot_c+1,curs_rot_r); lcd.write(r1); // sin lcd.write(r2); // mid lcd.write(r3); // dx } //-------------------------------- void do_funzione(int Key){ lcd.setCursor(0,1); for (int kk=1;kk<17;kk++) lcd.print(blank); if (Key==KLD){ //load from memory lcd.setCursor(6,1); lcd.print("load" ); delay(1000); for (int kk=0;kk<17;kk++) data[kk]=blank; lcd.setCursor(0,1); for (int kk=1;kk<17;kk++) lcd.print(blank); for (byte kk = 0; kk < 4; kk++) WHEELPOS[kk] = wheel_mem[kk]; lcd.setCursor(0,1); for (int kk=15;kk>=0;kk--) lcd.print(data[kk]); num_car=1; // azzera lo spaziatore } if (Key==KSV){ // save to memory lcd.setCursor(6,1); lcd.print("save"); delay(1000); //for (int kk=0;kk<17;kk++) data[kk]=' '; lcd.setCursor(0,1); for (int kk=1;kk<17;kk++) lcd.print(blank); for (byte kk = 0; kk < 4; kk++) wheel_mem[kk]=WHEELPOS[kk]; lcd.setCursor(0,1); for (int kk=15;kk>=0;kk--) lcd.print(data[kk]); } if (Key==KRE){ //read SD again lcd.setCursor(6,1); lcd.print("read"); delay(1000); for (int kk=0;kk<17;kk++) data[kk]=blank; lcd.setCursor(0,1); for (int kk=1;kk<17;kk++) lcd.print(blank); leggi_sd(); // rilegge la sd //for (byte kk = 0; kk < 4; kk++) wheel_mem[kk]=WHEELPOS[kk]; num_car=1; // azzera lo spaziatore } //************************************** if(Key==KVI){ //mostra configurazione boolean flag3=true; lcd.clear(); schermo_0[0]=EnigmaData.WHEELTYPE[5]+64; //riflettore schermo_0[1]=EnigmaData.WHEELTYPE[4]+64; // 4^ ruota if (schermo_0[1]==0) schermo_0[1]=sep2; schermo_0[2]=EnigmaData.WHEELTYPE[3]+48; // rotore sinistro schermo_0[3]=EnigmaData.WHEELTYPE[2]+48; // rotore centrale schermo_0[4]=EnigmaData.WHEELTYPE[1]+48; // rotore destro schermo_0[5]=sep2; // blank lcd.setCursor(0,0); for(int kk=0;kk<16;kk++) lcd.print(schermo_0[kk]); schermo_1[0]=sep2; //spazio per riflettore sopra schermo_1[1]=EnigmaData.ROTORPOS[0]+64; // 4^ ruota schermo_1[2]=EnigmaData.ROTORPOS[1]+64; // rotore sinistro schermo_1[3]=EnigmaData.ROTORPOS[2]+64; // rotore centrale schermo_1[4]=EnigmaData.ROTORPOS[3]+64; // rotore destro schermo_1[5]=sep2; // blank lcd.setCursor(0,1); for(int kk=0;kk<16;kk++) lcd.print(schermo_1[kk]); do { // aspetta KVI per uscire if (irrecv.decode(&results)) { tasto = results.value; if (tasto>2047) tasto-=2048; if (tasto==KVI) flag3=false; delay(100); irrecv.resume(); } } while(flag3); lcd.clear(); lcd.setCursor(0,1); for (int kk=15;kk>=0;kk--) lcd.print(data[kk]); } //chiude KVI //******************************** } //----------------------------------- void leggi_sd(){ // settaggio in caso si usi la vecchia init.Enigma() open source EnigmaData.SerialFunction = 2; //only coded //EnigmaData.SerialFunction = 1; // debug monitor su seriale byte carattere,plug1,plug2; Dati=SD.open("enigma.txt"); //nome del file di configurazione int num_dati=Dati.size(); if (Dati.size()!=44) { lcd.clear(); lcd.setCursor(4,1); lcd.print("FILE KO!"); while(true) {} //blocca su errore } carattere=Dati.read(); // sep //Rotor Types DA SINISTRA : UKV- 4^ - SN - MID - DX EnigmaData.WHEELTYPE[5] = Dati.read()-64; // REFLECTOR 12,13=B,14=C, thin 15=B,16=C 12 NON USATO MAI EnigmaData.WHEELTYPE[4] = Dati.read()-64; //??? // ADDITIONAL WHEEL (M4 only) 0,9,10 0 //selettore macchina I-M3 o M4 //EnigmaData.WHEELTYPE[4] =0; EnigmaData.WHEELTYPE[3] = Dati.read()-48; // LEFT ROTOR 1-8 EnigmaData.WHEELTYPE[2] = Dati.read()-48; // MIDDLE ROTOR 1-8 EnigmaData.WHEELTYPE[1] = Dati.read()-48; // RIGHTMOST ROTOR 1-8 EnigmaData.WHEELTYPE[0] = 11; // ENTRY CONTACTS: (ETW) fix 11 //Wheel Positions LETTERE ESTERNE INIZIALI if (EnigmaData.WHEELTYPE[4]==0) EnigmaData.WHEELPOS[0]=0; else EnigmaData.WHEELPOS[0] = 'A'; //lettera 4 ruota M4 EnigmaData.WHEELPOS[1] = 'A'; // LEFTMOST LETTER ON M3 A EnigmaData.WHEELPOS[2] = 'A'; // MIDDLE LETTER A EnigmaData.WHEELPOS[3] = 'A'; // RIGHTMOST LETTER A carattere=Dati.read(); // sep //Ring Settings LETTERE INTERNE DEI ROTORI EnigmaData.ROTORPOS[0] = Dati.read()-64; // LEFTMOST ROTOR SETTING ON M4 0 //EnigmaData.ROTORPOS[0] =0; //----------------------- EnigmaData.ROTORPOS[1] = Dati.read()-64; // LEFTMOST ROTOR SETTING ON M3 EnigmaData.ROTORPOS[2] = Dati.read()-64; // MIDDLE ROTOR SETTING EnigmaData.ROTORPOS[3] = Dati.read()-64; // RIGHTMOST ROTOR for (byte i = 0; i < 4; i++) {WHEELPOS[i] = EnigmaData.WHEELPOS[i]; } carattere=Dati.read(); // sep int num_plug=Dati.read()-64; // 10 =J numero di plugs carattere=Dati.read(); // sep; RemoveAllPlugs(); // azzera tutti i plug for (int i=6;i<16;i++){ schermo_0[i]='@'; schermo_1[i]='@'; } for (int i=0; i < num_plug; i++){ plug1=Dati.read(); plug2=Dati.read(); schermo_0[6+i]=plug1; schermo_1[6+i]=plug2; carattere=Dati.read(); // sep; AddPlug(plug1,plug2); } Dati.close(); if (EnigmaData.WHEELTYPE[4]==0){ //NON E' una M4 EnigmaData.WHEELPOS[0]=0; EnigmaData.ROTORPOS[0]=0; SerialSetWheels = 3; } else SerialSetWheels = 4; // è una M4 EnigmaData.Uhr = 0; // LASCIARE A ZERO CalculateUhrStecker(); } //================================================================= //================================================================= // // qui inizia il codice originale open source: ci sono le funzioni che vengono richiamate // initEnigma(), void ShowRotors(), void SerialMonitor(char k) NON LE HO USATE // void MoveWheels(), char EncodeKey(char key), bool IsCarry(byte wheelType, byte wheelPos) // void RemoveAllPlugs(), void AddPlug(char PlugKey1, char PlugKey2), // void CalculateUhrStecker(), byte SteckerPairs() // http://arduinoenigma.blogspot.it/2014/10/source-code-for-implementation-of.html // //================================================================= void initEnigma() { // set to 1 to monitor or 2 to display encoded character only EnigmaData.SerialFunction = 2; //ALL THE STEPS SHOWN BELOW MUST BE DONE TO INITIALIZE THE MACHINE //Rotor Types for an M4 machine, see more examples above EnigmaData.WHEELTYPE[0] = 11; // ENTRY CONTACTS: ETW EnigmaData.WHEELTYPE[1] = 3; // RIGHTMOST ROTOR EnigmaData.WHEELTYPE[2] = 2; // MIDDLE ROTOR EnigmaData.WHEELTYPE[3] = 1; // LEFT ROTOR EnigmaData.WHEELTYPE[4] = 0; // ADDITIONAL WHEEL (M4 only) EnigmaData.WHEELTYPE[5] = 13; // REFLECTOR: UKW B //Wheel Positions EnigmaData.WHEELPOS[0] = 0; // LEFTMOST LETTER ON M4 EnigmaData.WHEELPOS[1] = 'A'; // LEFTMOST LETTER ON M3 EnigmaData.WHEELPOS[2] = 'A'; // MIDDLE LETTER EnigmaData.WHEELPOS[3] = 'A'; // RIGHTMOST LETTER //Ring Settings EnigmaData.ROTORPOS[0] = 0; // LEFTMOST ROTOR SETTING ON M4 EnigmaData.ROTORPOS[1] = 'A'-64; // LEFTMOST ROTOR SETTING ON M3 EnigmaData.ROTORPOS[2] = 'A'-64; // MIDDLE ROTOR SETTING EnigmaData.ROTORPOS[3] = 'A'-64; // RIGHTMOST ROTOR SETTING for (byte i = 0; i < 4; i++) { WHEELPOS[i] = EnigmaData.WHEELPOS[i]; } //Initialize stecker with no plugs RemoveAllPlugs(); //ADD ANY PLUG PAIRS HERE USING THE AddPlug function //AddPlug('E', 'Q'); //AddPlug('N', 'R'); //AddPlug('I', 'S'); //AddPlug('G', 'T'); //AddPlug('M', 'U'); //AddPlug('A', 'V'); // set the UHR (non zero values used only if 10 plug pairs are installed) EnigmaData.Uhr = 0; CalculateUhrStecker(); } //--------------------------------------------------------------- byte SteckerPairs() { byte c = 0; for (byte i = 0; i < 26; i++) { if (EnigmaData.STECKER[i] != (65 + i)) { c++; } } return (c / 2); } //---------------------------------------------------- void RemoveAllPlugs() { for (byte i = 0; i < 27; i++) { EnigmaData.PAIRS[i] = 0; } strcpy(EnigmaData.STECKER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); EnigmaData.Uhr = 0; } //--------------------------------------------------- void AddPlug(char PlugKey1, char PlugKey2) { if ((SteckerPairs() < 13) && (PlugKey1 != PlugKey2)) { EnigmaData.PAIRS[SteckerPairs() * 2] = PlugKey1; EnigmaData.PAIRS[SteckerPairs() * 2 + 1] = PlugKey2; } EnigmaData.STECKER[PlugKey1 - 65] = PlugKey2; EnigmaData.STECKER[PlugKey2 - 65] = PlugKey1; } //------------------------------------------------------ void CalculateUhrStecker() { const char PROGMEM *uhrptr = (const char PROGMEM *)UHRSF; const char PROGMEM *uhrplugptr = (const char PROGMEM *)UHRPLUGSF; byte ndx = 0; if (SteckerPairs() == 10) { for (byte i = 0; i < 26; i++) { EffSTECKER[i] = 65 + i; } for (byte i = 0; i < 10; i++) { byte pin = 0; byte pinright = 0; byte pinleft = 0; pin = EnigmaData.Uhr + i * 4; if (pin > 39) { pin -= 40; } for (byte j = 0; j < 40; j++) { if (pgm_read_byte(uhrptr + j) == pin) { pinleft = j; } } pinright = pgm_read_byte(uhrptr + pin); //these two need to be signed, see <0 below //char is signed -127..+128 char plugright; char plugleft; plugright = (pinright - (EnigmaData.Uhr + 2)); if (plugright < 0) { plugright += 40; } plugright = plugright / 4; plugleft = (pinleft - (EnigmaData.Uhr + 2)); if (plugleft < 0) { plugleft += 40; } plugleft = plugleft / 4; EffSTECKER[EnigmaData.PAIRS[i * 2] - 65] = EnigmaData.PAIRS[pgm_read_byte(uhrplugptr + plugright) * 2 + 1]; EffSTECKER[EnigmaData.PAIRS[pgm_read_byte(uhrplugptr + i) * 2 + 1] - 65] = EnigmaData.PAIRS[plugleft * 2]; } } else { for (byte i = 0; i < 26; i++) { EffSTECKER[i] = EnigmaData.STECKER[i]; } } if (EnigmaData.SerialFunction == 1) { Serial.println(F("Stecker/Uhr:")); Serial.println(EffSTECKER); } } //---------------------------------------------------------------- void MoveWheels() { byte i = 4; bool carry = true; do { i--; if (carry) { WHEELPOS[i]++; if (i > 1) { carry = IsCarry(EnigmaData.WHEELTYPE[4 - i], WHEELPOS[i]); } else { carry = false; } } else { // double stepping on second wheel if (i == 2) { byte w2 = WHEELPOS[2] + 1; if (w2 > 'Z') { w2 = 'A'; } if (IsCarry(EnigmaData.WHEELTYPE[2], w2)) { WHEELPOS[2]++; carry = true; } } } if (WHEELPOS[i] > 'Z') { WHEELPOS[i] = 'A'; carry = IsCarry(EnigmaData.WHEELTYPE[4 - i], WHEELPOS[i]) || carry; if (i == 1) { carry = false; } } } while (i > 0); } //------------------------------------------------------------- void ShowRotors() { const char PROGMEM *charptr = (const char PROGMEM *)WHEELSF; char k; INT16U wheeltype; if (EnigmaData.SerialFunction == 1) { Serial.println(F("Rotors:")); for (byte i = 0; i < 6; i++) { if (EnigmaData.WHEELTYPE[i] != 0) { switch (i) { case 0: { Serial.println(F("ETW")); break; } case 1: case 2: case 3: case 4: { Serial.print(F("R")); Serial.println((char)('0' + i)); break; } case 5: { Serial.println(F("UKW")); break; } } wheeltype = ((EnigmaData.WHEELTYPE[i] - 1) * 28) + 2; for (byte i = 0; i < 26; i++) { k = pgm_read_byte(charptr + wheeltype + i); Serial.print(k); } Serial.println(F("")); } } } } //------------------------------------------------ byte SerialMonitorStatus; //------------------------------------------------ void SerialMonitor(char k) { if (k == 0) { SerialMonitorStatus = 0; } else { if (EnigmaData.SerialFunction == 1) // monitor { SerialMonitorStatus++; //skip R4 if a three wheel machine if (((EnigmaData.WHEELTYPE[5] > 11) && (EnigmaData.WHEELTYPE[5] < 15)) && ((SerialMonitorStatus == 6) || (SerialMonitorStatus == 8))) { SerialMonitorStatus++; } Serial.print(k); switch (SerialMonitorStatus) { case 1: case 13: { Serial.print(F(">Stecker>")); break; } case 2: case 12: { Serial.print(F(">ETW>")); break; } case 3: case 11: { Serial.print(F(">R1>")); break; } case 4: case 10: { Serial.print(F(">R2>")); break; } case 5: case 9: { Serial.print(F(">R3>")); break; } case 6: case 8: { Serial.print(F(">R4>")); break; } case 7: { Serial.print(F(">UKW>")); break; } default: { Serial.println(F("")); } } } } } //--------------------------------------------------------------- bool IsCarry(byte wheelType, byte wheelPos) { const char PROGMEM *charptr = (const char PROGMEM *)WHEELSF; INT16U wheeltype = (wheelType - 1) * 28; byte k1 = pgm_read_byte(charptr + wheeltype); byte k2 = pgm_read_byte(charptr + wheeltype + 1); bool v = false; if ((wheelPos == k1) || (wheelPos == k2)) { v = true; } return v; } //------------------------------------------------------------- char EncodeKey(char key) { const char PROGMEM *charptr = (const char PROGMEM *)WHEELSF; char k, k1; INT16U wheeltype; SerialMonitor(0); SerialMonitor(key); k = EffSTECKER[key - 'A']; SerialMonitor(k); for (byte i = 0; i < 6; i++) { if (EnigmaData.WHEELTYPE[i] != 0) { if ((i > 0) && (i < 5)) { byte p = WHEELPOS[4 - i] - (EnigmaData.ROTORPOS[4 - i] - 1); if (p < 'A') { p += 26; } k = k + (p - 'A'); } if (k > 'Z') { k = k - ('Z' + 1); } else { k = k - 'A'; } wheeltype = ((EnigmaData.WHEELTYPE[i] - 1) * 28) + k + 2; k = pgm_read_byte(charptr + wheeltype); if ((i > 0) && (i < 5)) { byte p = WHEELPOS[4 - i] - (EnigmaData.ROTORPOS[4 - i] - 1); if (p < 'A') { p += 26; } k = k - (p - 'A'); } if (k < 'A') { k = k + 26; } SerialMonitor(k); } } //after reflector for (byte i = 0; i < 5; i++) { if (EnigmaData.WHEELTYPE[4 - i] != 0) { if (i < 4) { byte p = WHEELPOS[i] - (EnigmaData.ROTORPOS[i] - 1); if (p < 'A') { p += 26; } k = k + (p - 'A'); } if (k > 'Z') { k = k - 26; } wheeltype = (EnigmaData.WHEELTYPE[4 - i] - 1) * 28; for (byte j = 0; j < 26; j++) { if ((pgm_read_byte(charptr + wheeltype + j + 2)) == k) { k1 = 'A' + j; } } k = k1; if (i < 4) { byte p = WHEELPOS[i] - (EnigmaData.ROTORPOS[i] - 1); if (p < 'A') { p += 26; } k = k - (p - 'A'); } if (k < 'A') { k = k + 26; } SerialMonitor(k); } } for (byte j = 0; j < 26; j++) { if (EffSTECKER[j] == k) { k1 = 'A' + j; } } k = k1; SerialMonitor(k); return k; } //================================================================= //http://arduinoenigma.blogspot.it/2014/10/source-code-for-implementation-of.html //=================================================================