//               Elektronická kontrola vstupu
//                    Hlavný program

//  Obsah => [CTLR+L]  zadávaný riadok je vždy prým riadkom vyhľadávaného kódu

//  Komunikačné rozhrania ................... 53
//  Knižnice periférií ...................... 59
//  Definície pinov ......................... 69
//  Bindovanie periférií .................... 79
//  Príkazy pre shift-reg ................... 93
//  Definície premenných ................... 110
//  void setup ............................. 187
//  Definícia vstupov/výstupov ............. 189
//  Naštartovanie rozhraní ................. 209
//  Verifikácia funkčnosti ................. 317
//  Načítanie dát z EEPROM ................. 384
//  Uvítanie ............................... 441
//  Void loop .............................. 461
//  Hlavné menu ............................ 483
//  Deň,dátum a čas ........................ 516
//-----------------------------------------------
//  Priloženie Smartbuttonu ................ 558
//  Priloženie prstu ....................... 575
//  Priloženie RFID karty .................. 581
//  Overenie RFID karty .................... 601
//  Zadanie hesla .......................... 695
//  Mazanie hesla .......................... 745
//  Odhalenie hesla ........................ 755
//  Potvrdenie hesla ....................... 767
//  Minutie pokusov ........................ 831
//  Nepovolená práca s terminálom .......... 866
//  Nastavenia ............................. 888
//  Voľba spôsobu alarmu ................... 982
//  Prepis kariet ......................... 1059
//  Pridanie odtlačku prsta ............... 1117
//  Ukázanie hesla ........................ 1033
//  Odchodové tlačidlo .................... 1249
//  Spánkový režim ........................ 1303
//  Alarm ................................. 1363
//  Uvítanie .............................. 1470
//  Funkcia pre rozpoznanie Ibuttonu ...... 1537
//  Funkcia pre overenie odtlačku prsta.... 1647
//  Funkcia pre snímanie odtalčku prsta ... 1813
//  Funkcia pre zápis do EEPROM ........... 1905
//  Funkcia pre čítania z EEPROM .......... 1917
//  Funkcia pre poslanie SMS .............. 1929
//  Funkcia pre vytočenie tel.čísla ....... 1953
//  Funkcia pre zavesenie volania ......... 1960

//-----------------------------------------------------

// Zahrnutie komunikačných rozhraní
#include <SoftwareSerial.h>// UART
#include <Wire.h>          // I2C
#include <SPI.h>           // SPI
#include <OneWire.h>       // IBUTTON komunikácia

// Zahrnutie knižníc pre ovládanie periférií:
#include <EEPROM.h>                // Interná pamäť MCU
#include <SD.h>                    // Modul SD karty
#include <Keypad.h>                // Klávesnica
#include <MFRC522.h>               // RFID čítačka
#include <LiquidCrystal_I2C.h>     // LCD   
#include <Servo.h>                 // Servo motor
#include <Adafruit_Fingerprint.h>  // Snímač odtlačku prsta
#include <RTClib.h>

// Definície konštantných pinov
#define EXIT  14         // Odchodové tlačítko
#define PIR   1          // Pohybový senzor
#define LOCK  15         // Koncový spínač zamknutia
#define MDD   13         // Detektor otvorenia dverí
#define buzz  0          // Buzčiak
#define data  21         // SHIFT-reg DATA
#define latch 22         // SHIFT-reg LATCH
#define clk   23         // SHIFT-reg CLOCK

// Bindovanie pinov pre ovládanie periférií
OneWire  ds(2);                      // Smartbutton
Servo servo;                         // inicializácia serva
LiquidCrystal_I2C lcd(0x27, 20, 4);  // LCD  20x4
MFRC522 mfrc522(4, 20);              // RFID ->  SS_PIN, RST_PIN
SoftwareSerial GSMserial(18, 19);   // GSM modul -> 1.RX to TX & 2.TX to RX
SoftwareSerial FGRserial(11, 10);    // Fingerprint senzor -> 1.RX to RX  & 2.TX to TX
RTC_DS1307 rtc;

Sd2Card card;       // SD karta potrebnosti
SdVolume volume;    //        -||-
SdFile root;        //        -||-
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&FGRserial); // Inicializovanie Fingerprintu na sériový port.


//      SHIFT-register rozpis príkazov v Hexadecimálnej sústave

//              1.Znak                                 2.Znak

//  | FGPRNT -> OFF  | FGPRNT -> ON |        |-------------------------|
//  ---------------------------------        |Servo     | D | [ALL oFF]|
//  R |   6   |[ALL!]|   7   |[FING]|        |Ele.zámok | 1 |          |
//  G |   C   |  E   |   D   |  F   |        |Alarm     | 7 |    5     |
//  B |   A   |      |   B   |      |        |IButton   | 4 |          |
//  ---------------------------------        |-------------------------|
//      LED > ON         LEDS > ON

//  Príklad:
//               digitalWrite(latch, LOW);
//               shiftOut(data, clk, LSBFIRST , 0xE5);    // Základný stav, všetko vypnuté.
//               digitalWrite(latch, HIGH);

char uvitanie0[] = ("!WELCOME!");
char uvitanie1[] = ("DOOR SECURITY SYSTEM");
char uvitanie2[] = ("ANDREJ MARIAN DRUGDA");

char daysOfTheWeek[7][12] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; //Dni v týždni pre RTC

char password[6];
char initial_password[] = "195375";

String tag = "";
String tag1 = "";
String tag2 = "";
String tag3 = "";
String tag4 = "";

int tony_cdur[] = {131, 147, 165, 175, 196, 220, 247, 262};       //tóny pre buzzer
int tony_adur[] = {440, 494, 554, 587, 659, 740, 831, 880};

byte keybut[5][8] = {{0x1, 0x69, 0x9F, 0x11, 0x1, 0x0, 0x0, 0xAC},     //Kódovanie pre farebné knoflíkové čipy Smartbutton + 1x úložné pole. R,G,B,Y,BL
  {0x1, 0xE, 0x83, 0x14, 0x1, 0x0, 0x0, 0x36},
  {0x1, 0x67, 0x76, 0x11, 0x1, 0x0, 0x0, 0x96},
  {0x1, 0x1A, 0x6F, 0x14, 0x1, 0x0, 0x0, 0x4A},
  {0x1, 0xB9, 0xAF, 0x8, 0x1, 0x0, 0x0, 0x47}
};
byte addr[8];

byte fajka[] = {0b11111,
                0b00001,
                0b11101,
                0b10101,
                0b10101,
                0b10101,
                0b10001,
                0b11111,
               };

int br, bc = 0;    // Overovacie premenné správneho knoflíka  -  riadok a stlpec poľa
uint8_t id;       //ID odtlačku prsta


const int chipSelect = 3;                  // CS pin pre SD kartu

unsigned long RTCmil;                      // časovač pre RTC menu
unsigned long casterm;                     // časovač pre neprekročenie doby na jednotlivých termináloch


//čas-RFID     KEYmenu      KÓD       RFID menu    FGPRNT menu  developer   sleepy mode
bool smen = 1, kmen = 1, kodmen = 1 , rfidmen = 1, figmen = 1,  devmen = 1, sleepy = 1;   // Premazanie a výpis displeja 1x pri prepnutí termu.


// KEY-PAD inicializácia
const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {           // Definícia číselného poľa
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'#', '0', '*', 'D'}
};

byte rowPins[ROWS] = {A4, A5, A6, A7};    // Nabindovanie pinov MCU
byte colPins[COLS] = {A0, A1, A2, A3};

Keypad KEYPAD = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);  //Namapovanie číselného poľa do MCU

int count_key = 0;                         // Počítadlo pre opakujúce sa deje (voľná premenná)   Počet zadaných číslic na KEYPADE
char keypres = 0;                          // Signalizacia stlačenia klávesnice
int vybterm = 0;                           // Výber terminálu na autentizáciu
int pokus = 3;                             // Počet chýb zadania hesla  3-pokusy
int odkryvac = 2;                          // Zobrazenie číselného hesla na vyžiadanie (****) -> (1234)
int karter = 0;                            // Prepínač karty na rewrite
bool ALARM = 0;                            // Tichý / Hlučný
bool ELE;   // Moja vychytávka



void setup() {
  // Definícia výstupov
  pinMode(buzz, OUTPUT);
  pinMode(data, OUTPUT);
  pinMode(latch, OUTPUT);
  pinMode(clk,  OUTPUT);

  // Definícia vstupov
  pinMode(EXIT, INPUT);
  pinMode(MDD, INPUT);
  pinMode(LOCK, INPUT);
  pinMode(PIR, INPUT);

  digitalWrite(data, LOW);
  digitalWrite(clk,  LOW);
  digitalWrite(latch, LOW);
  shiftOut(data, clk, LSBFIRST , 0xE5);     //Štartovacie nastavenie shift registra   dec:229   bin: 0b11100101 hex:E5
  digitalWrite(latch, HIGH);
  delay(2000);

  GSMserial.begin(9600);
  Wire.begin();
  lcd.init();                 //zaevidovanie LCD
  lcd.backlight();            //zapnutie podsvietenia
  //PR:   lcd.setBacklight(HIGH or LOW);

  SPI.begin();                // Initiate  SPI bus
  mfrc522.PCD_Init();         // Initiate MFRC522

  servo.attach(12);           // Nabindovanie serva

  RTCmil = millis() + 10; //+1000 pre plynulý začiatok bez seku
  //rtc.adjust(DateTime(2023, 5, 22, 14, 55, 0));  // Nastavenie oficiálnych parametrov. (po nastavení dať do komentu aby sa to už neprestavovalo)
  //rok, mesiac, deň, hodiny, minuty, sekundy
  casterm = millis();

  lcd.createChar(0, fajka);


  delay(2000);

  lcd.clear();
  lcd.setCursor(4, 1);
  lcd.print("BC.A   ELE.B");

  while (!keypres) {

    keypres = KEYPAD.getKey();

    if (keypres == 'A') {
      ELE = 0;
    }
    if (keypres == 'B') {
      ELE = 1;
    }
  }

  lcd.clear();
  lcd.setCursor(1, 1);
  lcd.print("SYSTEM IS STARTING");
  delay(1500);        // ZMEŇ na => 2!!!!!!!!!

  for (int j = 0; j <= 5; j++) {

    lcd.setCursor(1, 2);

    for (int x = 0; x <= 17; x++) {
      lcd.print("_");
      tone(buzz, x + 50);
      delay(30);
      noTone(buzz);
      delay(25);
    }
    lcd.setCursor(1, 2);
    noTone(buzz);
    lcd.print("                  ");
  }

  lcd.clear();                                   // Inicializácia internej EEPROM?    (Veľkosť, čítanie/mazanie hodnôt)
  lcd.setCursor(3, 0);  lcd.print("SIZE OF EEPROM:");
  lcd.setCursor(7, 2);  lcd.print(EEPROM.length()); lcd.print(" B");
  delay(2000);



  if (EEPROM[0] < 60) {                     //Uzavretie Fingerprint pri ponechanom otvorenom

    lcd.clear();
    lcd.setCursor(3, 1);  lcd.print("SERVO POSITION");
    lcd.setCursor(8, 2); lcd.print(EEPROM[0]);

    digitalWrite(latch, LOW);
    servo.write(51);
    shiftOut(data, clk, LSBFIRST , 0xED);
    digitalWrite(latch, HIGH);
    delay(1000);

    for (int x = EEPROM[0]; x <= 144; x++) {
      lcd.setCursor(8, 2); lcd.print(x);
      servo.write(x);
      delay(30);
    }
    EEPROM[0] = 144;                        //Zápis trvá 3,3 ms!!!
    delay(5);
    digitalWrite(latch, LOW);
    shiftOut(data, clk, LSBFIRST , 0xE5);
    digitalWrite(latch, HIGH);
    delay(1000);
  }


  lcd.clear();
  lcd.setCursor(3, 1);
  lcd.print("CLOSE THE DOOR!");
  while (digitalRead(MDD) == HIGH);

  lcd.clear();
  lcd.setCursor(2, 1);
  lcd.print("UNLOCK THE DOOR!");
  while (digitalRead(LOCK) == HIGH);
  lcd.clear();


  delay(50);
  digitalWrite(latch, LOW);
  shiftOut(data, clk, LSBFIRST , 0xF5);         // Zapnutie snímaču odtlačkov
  digitalWrite(latch, HIGH);
  delay(50);


  // Verifikácia funkčnosti

  finger.begin(57600);               // Fingerprint senzor?

  if (finger.verifyPassword()) {
    lcd.setCursor(3, 1);
    lcd.print("Fingerprint ok!");
    tone(buzz, 200);
    delay(100);
    tone(buzz, 300);
    delay(200);
    noTone(buzz);
  } else {
    lcd.setCursor(0, 1);
    lcd.print("FinGsen not working!");
    while (1) {
      delay(1);
    }
  }

  delay(50);
  digitalWrite(latch, LOW);
  shiftOut(data, clk, LSBFIRST , 0xE5);
  digitalWrite(latch, HIGH);
  delay(2000);


  lcd.clear();
  if (! rtc.begin()) {                   // RTC?
    lcd.setCursor(1, 1);   lcd.print("Couldn't find RTC");
    while (1);
  } else {
    lcd.setCursor(3, 1);  lcd.print("RTC is working");
    tone(buzz, 200);
    delay(100);
    tone(buzz, 300);
    delay(200);
    noTone(buzz);
  }
  if (! rtc.isrunning()) {
    lcd.setCursor(0, 2);  lcd.print("RTC is NOT running!");
  }
  delay(2000);


  lcd.clear();                              //SD karta?

  lcd.setCursor(1, 1);  lcd.print("SD CARD DETECTION");
  delay(2000);

  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    lcd.clear();
    lcd.setCursor(2, 0);  lcd.print("CARD NOT FOUND");
    lcd.setCursor(0, 1);  lcd.print("PLEASE SHUT DOWN EEC");
    lcd.setCursor(1, 2);  lcd.print("AND INSERT SD CARD");
    while (1);
  } else {

    lcd.clear();
    lcd.setCursor(0, 1);  lcd.print("SD CARD IS IN PLACE");
    tone(buzz, 200);
    delay(100);
    tone(buzz, 300);
    delay(200);
    noTone(buzz);
  }

  if (EEPROM[10] != 0) {
    tag1 = EEPstr(10);
    delay(5);
  }

  if (EEPROM[25] != 0) {
    tag2 = EEPstr(25);
    delay(5);
  }

  if (EEPROM[40] != 0) {
    tag3 = EEPstr(40);
    delay(5);
  }

  if (EEPROM[55] != 0) {
    tag4 = EEPstr(55);
    delay(5);
  }


  delay(3000);

  delay(50);
  digitalWrite(latch, LOW);
  shiftOut(data, clk, LSBFIRST , 0xA5);
  digitalWrite(latch, HIGH);
  delay(50);

  lcd.clear();
  lcd.setCursor(2, 1); lcd.print("INITIALIZING GSM");

  for (int j = 0; j <= 3; j++) {

    lcd.setCursor(1, 2);

    for (int x = 0; x <= 17; x++) {
      lcd.print(".");
      delay(100);
    }
    lcd.setCursor(1, 2);
    lcd.print("                  ");
  }

  delay(50);
  digitalWrite(latch, LOW);
  shiftOut(data, clk, LSBFIRST , 0xE5);
  digitalWrite(latch, HIGH);
  delay(50);


  delay(1000);
  lcd.clear();
  lcd.setCursor(3, 1); lcd.print("EUROTEL PRAHA");
  delay(2000);


  if (ELE == 0) {                  // Uvítanie
    welcome();
  }
  else if (ELE == 1) {
    lcd.clear();
    lcd.setCursor(5, 1);
    lcd.print("!WELCOME!");
    tone(buzz, 400);
    delay(100);
    tone(buzz, 500);
    delay(200);
    noTone(buzz);
    delay(1700);
    lcd.clear();
    delay(100);
  }


}

void loop() {


  if (digitalRead(MDD) == LOW) {

    if (digitalRead(LOCK) == LOW) {

      if (sleepy == 0) {

        lcd.clear();
        lcd.setCursor(3, 1); lcd.print("DOOR UNLOCKED");
        lcd.display();
        delay(100);
        lcd.setBacklight(HIGH);
        delay(1000);
        lcd.clear();
        sleepy = 1;
      }

      if (digitalRead(EXIT) == LOW) {


        if (vybterm == 0) {                     // Úvodná obrazovka s čítaním RFID knoflíkov

          if ((millis() - RTCmil) <= 17000)           //MENU - Názov.dátum.čas.deň
          {
            if ((millis() - RTCmil) >= 15000 && (millis() - RTCmil) <= 17000) {     // Prepínanie medzi attch your card a zobrazením úvodnej obrazovky -> Zobrazí sa medzi 15-17 s.
              while (smen == 0) {

                digitalWrite(latch, LOW);
                shiftOut(data, clk, LSBFIRST , 0xE4);
                delay(5);
                lcd.clear();
                digitalWrite(latch, HIGH);

                lcd.setCursor(7, 1);  lcd.print("PLEASE");
                lcd.setCursor(1, 2);  lcd.print("ATTACH YOUR BUTTON");

                smen = 1;
              }
            }
            else {
              DateTime now = rtc.now();

              while (smen == 1) {
                lcd.clear();
                lcd.setCursor(0, 0);  lcd.print("DOOR SECURITY SYSTEM");

                digitalWrite(latch, LOW);
                shiftOut(data, clk, LSBFIRST , 0xE5);
                digitalWrite(latch, HIGH);
                delay(5);
                smen = 0;
              }

              if (now.hour() > 9) {                   // Zobrazenie hodín, dátumu a dňa na úvodnej obrazovke pomocou RTC.
                lcd.setCursor(15, 2);
                lcd.print(now.hour(), DEC);
              }
              else
              {
                lcd.setCursor(15, 2);
                lcd.print("0");
                lcd.print(now.hour(), DEC);
              }

              lcd.print(":");

              if (now.minute() > 9) {
                lcd.setCursor(18, 2);
                lcd.print(now.minute(), DEC);
              }
              else
              {
                lcd.setCursor(18, 2);
                lcd.print("0");
                lcd.print(now.minute(), DEC);
              }

              lcd.setCursor(0, 2);
              lcd.print(now.day(), DEC);
              lcd.print('.');
              lcd.print(now.month(), DEC);
              lcd.print(".");
              lcd.print(now.year(), DEC);

              lcd.setCursor(8, 3);
              lcd.print("[");
              lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
              lcd.print("]");

            }

          } else {
            RTCmil = millis();
          }

          if (ds.search(addr)) {                //overenie správnosti Smartbuttonu

            for (int bc = 0; bc < 8; bc++) {

              if (addr[bc] != keybut[br][bc]) {
                bc = 0;
                br++;
              }
            }

            butonchose(br);
            bc = br = 0;

            ds.reset_search();
          }
        }

        if (vybterm  == 1) {
          getFingerprintID();
        }



        if (vybterm == 2) {

          if (rfidmen == 1) {
            lcd.clear();
            lcd.setCursor(2, 1); lcd.print("ATTACH YOUR CARD");
            lcd.setCursor(4, 3); lcd.print("ATTEPMTS < >");
            lcd.setCursor(14, 3); lcd.print(pokus);
            RTCmil = millis();
            casterm = millis();
            rfidmen = 0;
          }

          if ((millis() - RTCmil) <= 30000) {

            if ((millis() - casterm) >= 1000) {
              lcd.setCursor(18, 0); lcd.print((millis() - RTCmil) / 1000);
              casterm = millis();
            }


            if ( ! mfrc522.PICC_IsNewCardPresent() or ! mfrc522.PICC_ReadCardSerial())
            {
              return;
            }
            tag = "";
            for (byte j = 0; j < mfrc522.uid.size; j++)
            {
              tag.concat(String(mfrc522.uid.uidByte[j] < 0x10 ? " 0" : " "));
              tag.concat(String(mfrc522.uid.uidByte[j], HEX));
            }
            tag.toUpperCase();

            if (tag.substring(1) == "16 E7 CF 5C" || tag.substring(1) == tag1 || tag.substring(1) == tag2 || tag.substring(1) == tag3 || tag.substring(1) == tag4) {

              lcd.clear();
              lcd.setCursor(3, 1); lcd.print("CARD ACCEPTED");
              vybterm = pokus = 3;
              kmen = kodmen = 1;
              digitalWrite(latch, LOW);
              shiftOut(data, clk, LSBFIRST , 0xC5);
              digitalWrite(latch, HIGH);
              tone(buzz, 500);
              delay(200);
              tone(buzz, 700);
              delay(300);
              noTone(buzz);
              delay(500);
              digitalWrite(latch, LOW);
              shiftOut(data, clk, LSBFIRST , 0xE5);
              digitalWrite(latch, HIGH);
              RTCmil = millis();
              casterm = millis();

            } else {

              lcd.clear();
              lcd.setCursor(3, 1); lcd.print("CARD REJECTED");
              rfidmen = 1;
              pokus--;
              digitalWrite(latch, LOW);
              shiftOut(data, clk, LSBFIRST , 0x65);
              digitalWrite(latch, HIGH);
              for (int x = 0; x < 3; x++) {
                tone(buzz, 300);
                delay(150);
                noTone(buzz);
                delay(150);
              }
              digitalWrite(latch, LOW);
              shiftOut(data, clk, LSBFIRST , 0xE5);
              digitalWrite(latch, HIGH);

              if (pokus >= 1) {

                lcd.clear();
                lcd.setCursor(4, 1);  lcd.print("ATTACH AGAIN");
                lcd.setCursor(4, 2);  lcd.print("CORRECT CART");
                delay(2000);

              } else {
                vybterm = 0;
                pokus = 3;
                rfidmen = smen = 1;
                lcd.clear();
                lcd.setCursor(3, 1); lcd.print("ATTEMPTS ENDED");
                SendMessage();
                delay(5000);
                RTCmil = millis();
              }
            }

          } else {
            vybterm = 0;
            smen = rfidmen = 1;
            pokus = 3;
            lcd.clear();
            lcd.setCursor(0, 1); lcd.print("THE TERMINAL DIDN'T");
            lcd.setCursor(1, 2); lcd.print("RECEIVE A RESPONSE");

            for (int x = 7; x >= 0; x--) {
              tone(buzz, tony_cdur[x]);
              delay(30);
              noTone(buzz);
              delay(20);
            }
            SendMessage();
            delay(5000);
            RTCmil = millis();
          }

        }



        if (vybterm == 3) {               //Zadávanie hesla

          if (kmen == 1) {
            enterpsw();
            kmen = 0;
          }

          if ((millis() - RTCmil) <= 31000) {

            if ((millis() - casterm) >= 1000) {
              lcd.setCursor(18, 0); lcd.print((millis() - RTCmil) / 1000);
              casterm = millis();
            }

            if (kodmen == 1) {
              if (odkryvac % 2 == 1) {

                lcd.setCursor(8, 2);
                for (int x = 0; x < count_key; x++) {
                  lcd.print(password[x]);
                }

              } else {

                lcd.setCursor(8, 2);
                for (int x = 0; x < count_key; x++) {
                  lcd.print("*");
                }
              }

              kodmen = 0;
            }

            keypres = KEYPAD.getKey();


            if (keypres) {
              delay(5);        //debouncer

              if (keypres != 'A' && keypres != 'B' && keypres != 'C' && keypres != 'D' && keypres != '#' && keypres != '*')
              {
                if (count_key <= 5) {
                  tone(buzz, 3000, 100);
                  password[count_key++] = keypres;               // Ukladanie hesla do poľa
                  kodmen = 1;
                }
              }

              if (count_key > 0) {

                if (keypres == 'D') {                      //D-delete => mazacia funkcia
                  lcd.setCursor(count_key + 7, 2);
                  lcd.print(" ");
                  count_key -= 1;
                  kodmen = 1;
                  tone(buzz, 400, 15);
                }
              }


              if (keypres == 'C')  //Odkrývač zašifrovaných čísel
              {
                tone(buzz, 100, 30);
                odkryvac++;
                kodmen = 1;

                if (odkryvac == 3) {
                  odkryvac = 1;
                }
              }


              if (keypres == '*') {

                if (count_key == 6) {                      // Ak je zadaný správny počet číslic 4

                  if (!(strncmp(password, initial_password, 6)))
                  {
                    lcd.clear();
                    lcd.setCursor(2, 1); lcd.print("PASSWORD CORRECT");
                    lcd.setCursor(5, 2); lcd.print("DOOR OPEN");
                    vybterm = count_key = 0;
                    pokus = 3;
                    smen = 1;
                    casterm = millis();

                    digitalWrite(latch, LOW);                           // Zapnutie elektrického zámku
                    shiftOut(data, clk, LSBFIRST , 0xC1);
                    digitalWrite(latch, HIGH);

                    for (int x = 0; x <= 7; x++) {
                      tone(buzz, tony_adur[x]);
                      delay(50);
                    }
                    noTone(buzz);
                    while ((millis() - casterm) <= 3000 && digitalRead(MDD) == LOW);  // Podmienka 3s alebo otvorenia dverí pre vypnutie EL.zámku.
                    delay(200);
                    digitalWrite(latch, LOW);                           // Vypnutie elektrického zámku
                    shiftOut(data, clk, LSBFIRST , 0xE5);
                    digitalWrite(latch, HIGH);
                    delay(200);

                    while (digitalRead(MDD) == HIGH);
                    delay(200);
                  } else {

                    lcd.clear();
                    lcd.setCursor(1, 1);  lcd.print("PASSWORD INCORRECT");
                    pokus--;
                    digitalWrite(latch, LOW);
                    shiftOut(data, clk, LSBFIRST , 0x65);
                    digitalWrite(latch, HIGH);

                    for (int x = 0; x < 3; x++) {
                      tone(buzz, 300);
                      delay(150);
                      noTone(buzz);
                      delay(150);
                    }
                    digitalWrite(latch, LOW);
                    shiftOut(data, clk, LSBFIRST , 0xE5);
                    digitalWrite(latch, HIGH);

                    delay(100);

                    if (pokus >= 1) {
                      lcd.clear();
                      delay(100);
                      lcd.setCursor(0, 1);  lcd.print("ENTER PASSWORD AGAIN");
                      count_key = 0;
                      kmen = kodmen = 1;
                      RTCmil = millis();
                      casterm = millis();
                      delay(2000);
                    }

                    if (pokus == 0) {
                      pokus = 3;
                      vybterm = count_key = 0;
                      smen = kmen = kodmen = 1;

                      lcd.clear();
                      lcd.setCursor(3, 1); lcd.print("ATTEMPTS ENDED");
                      SendMessage();
                      delay(5000);
                      RTCmil = millis();
                    }
                  }
                } else {                   // Ak nie je zadaných 6 číslic

                  lcd.clear();
                  lcd.setCursor(0, 1);  lcd.print("PASSWORD INCOMPLETE!");
                  kmen = kodmen = 1;
                  digitalWrite(latch, LOW);
                  shiftOut(data, clk, LSBFIRST , 0x65);
                  digitalWrite(latch, HIGH);

                  for (int x = 0; x < 3; x++) {
                    tone(buzz, 300);
                    delay(150);
                    noTone(buzz);
                    delay(150);
                  }
                  digitalWrite(latch, LOW);
                  shiftOut(data, clk, LSBFIRST , 0xE5);
                  digitalWrite(latch, HIGH);

                  delay(1000);
                }
              }
            }
          } else {
            vybterm = count_key = 0;
            smen = kmen = kodmen = 1;
            pokus = 3;

            lcd.clear();
            lcd.setCursor(0, 1); lcd.print("THE TERMINAL DIDN'T");
            lcd.setCursor(1, 2); lcd.print("RECEIVE A RESPONSE");

            for (int x = 7; x >= 0; x--) {
              tone(buzz, tony_cdur[x]);
              delay(30);
              noTone(buzz);
              delay(20);
            }
            SendMessage();
            delay(5000);
            RTCmil = millis();
          }
        }


        if (vybterm == 4) {

          if (devmen == 1) {
            lcd.clear();
            lcd.setCursor(4, 1); lcd.print("QUICK SETUPS");
            delay(1500);
            lcd.clear();
            lcd.setCursor(0, 0); lcd.print("REWRITE CARD     A");
            lcd.setCursor(0, 1); lcd.print("ADD FINGER       B");
            lcd.setCursor(0, 2); lcd.print("ALARM METHOD     C");
            lcd.setCursor(0, 3); lcd.print("PASSWORD         D");
            devmen = 0;
          }

          keypres = KEYPAD.getKey();

          if (keypres) {

            if (keypres == 'A') {                           //  Prepis karty
              keypres = 0;
              tone(buzz, 700);
              lcd.setCursor(15, 0); lcd.print(">");
              delay(100);
              noTone(buzz);
              delay(900);
              lcd.clear();
              lcd.setCursor(1, 0); lcd.print("SELECT THE NUMBER");
              lcd.setCursor(4, 1); lcd.print("OF CARD TO");
              lcd.setCursor(5, 2); lcd.print("OWERWRITE");
              delay(1500);
              lcd.clear();
              lcd.setCursor(0, 0);  lcd.print("Card #1");
              lcd.setCursor(0, 1);  lcd.print("Card #2");
              lcd.setCursor(0, 2);  lcd.print("Card #3");
              lcd.setCursor(0, 3);  lcd.print("Card #4");
              lcd.setCursor(9, 0); lcd.print(tag1);
              lcd.setCursor(9, 1); lcd.print(tag2);
              lcd.setCursor(9, 2); lcd.print(tag3);
              lcd.setCursor(9, 3); lcd.print(tag4);

              while (!keypres) {
                keypres = KEYPAD.getKey();

                if (keypres == '1') {
                  karter = 1;
                  vybterm = 5;
                  lcd.clear();
                  lcd.setCursor(2, 1); lcd.print("ATTACH RFID CARD");
                }

                if (keypres == '2') {
                  karter = 2;
                  vybterm = 5;
                  lcd.clear();
                  lcd.setCursor(2, 1); lcd.print("ATTACH RFID CARD");
                }

                if (keypres == '3') {
                  karter = 3;
                  vybterm = 5;
                  lcd.clear();
                  lcd.setCursor(2, 1); lcd.print("ATTACH RFID CARD");
                }

                if (keypres == '4') {
                  karter = 4;
                  vybterm = 5;
                  lcd.clear();
                  lcd.setCursor(2, 1); lcd.print("ATTACH RFID CARD");
                }



                if (keypres == '#') {
                  vybterm = 4;
                  devmen = 1;
                }

              } keypres = 0;
            }


            if (keypres == 'B') {                         // Pridanie odtlačku prsta
              vybterm = 6;
              figmen = 1;
              keypres = 0;
              tone(buzz, 700);
              lcd.setCursor(15, 1); lcd.print(">");
              delay(100);
              noTone(buzz);
              delay(900);
            }


            if (keypres == 'C') {                           // Nastavenie Alarmu

              keypres = 0;

              tone(buzz, 700);
              lcd.setCursor(15, 2); lcd.print(">");
              delay(100);
              noTone(buzz);
              delay(900);
              lcd.clear();
              lcd.setCursor(4, 1); lcd.print("LOUD       A");
              lcd.setCursor(4, 2); lcd.print("SILENT     B");

              while (!keypres) {
                keypres = KEYPAD.getKey();

                if (keypres == 'A') {
                  ALARM = 0;
                  lcd.setCursor(13, 1); lcd.print(">");
                  delay(700);

                  lcd.clear();
                  lcd.setCursor(3, 1); lcd.print("LOUD ALARM SET");
                  tone(buzz, 300);
                  delay(100);
                  tone(buzz, 400);
                  delay(200);
                  tone(buzz, 300);
                  delay(100);
                  tone(buzz, 500);
                  delay(400);
                  noTone(buzz);
                  delay(1000);
                }

                if (keypres == 'B') {
                  ALARM = 1;
                  lcd.setCursor(13, 2); lcd.print(">");
                  delay(1000);
                  lcd.clear();
                  lcd.setCursor(2, 1); lcd.print("SILENT ALARM SET");

                  delay(1500);
                }
              }
              devmen = 1;
              vybterm = 4;
              keypres = 0;
            }


            if (keypres == 'D') {                                 // Ukážka hesla
              devmen = 1;
              tone(buzz, 700);
              lcd.setCursor(15, 3); lcd.print(">");
              delay(100);
              noTone(buzz);
              delay(900);

              lcd.clear();
              lcd.setCursor(0, 0); lcd.print("PASSWORD:");
              lcd.setCursor(7, 2); lcd.print(initial_password);
              delay(2000);
            }


            if (keypres == '#') {
              vybterm = 0;
              smen = 1;
              devmen = 1;
            }
          }
        }




        if (vybterm == 5) {

          if ( ! mfrc522.PICC_IsNewCardPresent() or ! mfrc522.PICC_ReadCardSerial())
          {
            return;
          }
          tag = "";
          for (byte j = 0; j < mfrc522.uid.size; j++)
          {
            tag.concat(String(mfrc522.uid.uidByte[j] < 0x10 ? " 0" : " "));
            tag.concat(String(mfrc522.uid.uidByte[j], HEX));
          }
          tag.toUpperCase();

          if (karter == 1) {
            tag1 = tag.substring(1);
            vybterm = 4;
            devmen = 1;
            strEEP(10, tag1);

          }

          if (karter == 2) {
            tag2 = tag.substring(1);
            vybterm = 4;
            devmen = 1;
            strEEP(25, tag2);
          }


          if (karter == 3) {
            tag3 = tag.substring(1);
            vybterm = 4;
            devmen = 1;
            strEEP(40, tag3);
          }


          if (karter == 4) {
            tag4 = tag.substring(1);
            vybterm = 4;
            devmen = 1;
            strEEP(55, tag4);
          }

          lcd.clear();
          lcd.setCursor(4, 1); lcd.print("CARD CHANGED");
          tone(buzz, 500);
          delay(200);
          tone(buzz, 700);
          delay(300);
          noTone(buzz);
          delay(500);
        }




        if (vybterm == 6) {

          if (figmen == 1) {
            lcd.clear();
            lcd.setCursor(4, 0); lcd.print("!ATTENTION!");
            lcd.setCursor(3, 2); lcd.print("FINGER SENZOR");
            lcd.setCursor(4, 3); lcd.print("IS EXTENDED");
            for (int x = 0; x < 3; x++) {
              tone(buzz, 300);
              delay(300);
              noTone(buzz);
              delay(200);
            }
            delay(1300);

            digitalWrite(latch, LOW);
            servo.write(144);
            shiftOut(data, clk, LSBFIRST , 0xED);
            digitalWrite(latch, HIGH);
            delay(100);

            for (int x = 144; x >= 51; x--) {
              servo.write(x);
              delay(30);
            }

            EEPROM[0] = 51;
            delay(100);
            digitalWrite(latch, LOW);
            shiftOut(data, clk, LSBFIRST , 0xF5);
            digitalWrite(latch, HIGH);
            delay(200);

            figmen = 0;
          }

          lcd.clear();
          lcd.setCursor(0, 1); lcd.print("CHOOSE FINGER TO ADD");
          lcd.setCursor(7, 2); lcd.print("<1-9>");

          while (!keypres) {
            keypres = KEYPAD.getKey();

            if (keypres == '1') {
              karter = 1;
            }
            if (keypres == '2') {
              karter = 2;
            }
            if (keypres == '3') {
              karter = 3;
            }
            if (keypres == '4') {
              karter = 4;
            }

            if (keypres == '5') {
              karter = 5;
            }
            if (keypres == '6') {
              karter = 6;
            }
            if (keypres == '7') {
              karter = 7;
            }
            if (keypres == '8') {
              karter = 8;
            }
            if (keypres == '9') {
              karter = 9;
            }
          }
          keypres = 0;

          lcd.setCursor(0, 2); lcd.print("READY TO ENROLL ID#");  lcd.print(karter);
          delay(2000);


          while (!getFingerprintEnroll(karter));

          lcd.clear();

          lcd.setCursor(2, 0); lcd.print("YOU WANT TO ADD");
          lcd.setCursor(2, 1); lcd.print("ANOTHER FINGER?");
          lcd.setCursor(0, 3); lcd.print("YES >A<       NO >B<");

          while (!keypres)
          { keypres = KEYPAD.getKey();

            if (keypres == 'A') {
              vybterm = 6;
              karter =  0;
            }


            if (keypres == 'B') {

              lcd.clear();
              lcd.setCursor(4, 0); lcd.print("!ATTENTION!");
              lcd.setCursor(0, 2); lcd.print("FINGER SENZOR CLOSES");
              for (int x = 0; x < 3; x++) {
                tone(buzz, 300);
                delay(300);
                noTone(buzz);
                delay(200);
              }
              delay(1300);

              digitalWrite(latch, LOW);
              servo.write(51);
              shiftOut(data, clk, LSBFIRST , 0xED);
              digitalWrite(latch, HIGH);
              delay(200);

              for (int x = 51; x <= 144; x++) {
                servo.write(x);
                delay(30);
              }
              EEPROM[0] = 144;
              delay(100);
              digitalWrite(latch, LOW);
              shiftOut(data, clk, LSBFIRST , 0xE5);
              digitalWrite(latch, HIGH);
              delay(200);
              vybterm = 4;
              devmen = figmen = 1;
              karter =  0;
              delay(1000);
            }
          } keypres = 0;
        }

      } else {

        if (EEPROM[0] < 60) {

          lcd.clear();
          lcd.setCursor(4, 0); lcd.print("!ATTENTION!");
          lcd.setCursor(0, 2); lcd.print("FINGER SENZOR CLOSES");
          for (int x = 0; x < 3; x++) {
            tone(buzz, 300);
            delay(400);
            noTone(buzz);
            delay(300);
          }

          delay(1300);

          digitalWrite(latch, LOW);
          servo.write(51);
          shiftOut(data, clk, LSBFIRST , 0xED);
          digitalWrite(latch, HIGH);
          delay(200);

          for (int x = 51; x <= 144; x++) {
            servo.write(x);
            delay(30);
          }
          EEPROM[0] = 144;
          delay(5);


        }
        smen = kmen = kodmen =  rfidmen = figmen =  devmen = 1;
        count_key = keypres = vybterm = karter = 0;
        pokus = 3;
        odkryvac = 2;
        bc = br = 0;

        digitalWrite(latch, LOW);                           // Zapnutie elektrického zámku
        shiftOut(data, clk, LSBFIRST , 0xE1);
        digitalWrite(latch, HIGH);

        for (int x = 0; x < 6; x++) {
          tone(buzz, 440);
          delay(500);
          noTone(buzz);
          delay(500);
        }

        digitalWrite(latch, LOW);                           // Zapnutie elektrického zámku
        shiftOut(data, clk, LSBFIRST , 0xE5);
        digitalWrite(latch, HIGH);
        delay(20);
      }

    } else {

      if (sleepy == 1) {
        lcd.clear();
        lcd.setCursor(4, 1); lcd.print("!DOOR LOCKED!");
        delay(1500);
        lcd.clear();
        lcd.setCursor(2, 1); lcd.print("SYSTEM GOES INTO");
        lcd.setCursor(4, 2); lcd.print(">SLEEP MODE<");


        if (EEPROM[0] < 60) {                     //Uzavretie Fingerprint pri ponechanom otvorenom

          lcd.clear();
          lcd.setCursor(3, 1);  lcd.print("SERVO POSITION");
          lcd.setCursor(8, 2); lcd.print(EEPROM[0]);

          digitalWrite(latch, LOW);
          servo.write(51);
          shiftOut(data, clk, LSBFIRST , 0xED);
          digitalWrite(latch, HIGH);
          delay(1000);

          for (int x = EEPROM[0]; x <= 144; x++) {
            lcd.setCursor(8, 2); lcd.print(x);
            servo.write(x);
            delay(30);
          }
          EEPROM[0] = 144;                        //Zápis trvá 3,3 ms!!!
          delay(5);

          digitalWrite(latch, LOW);
          shiftOut(data, clk, LSBFIRST , 0xE5);
          digitalWrite(latch, HIGH);
          delay(1000);
        }
        delay(2000);
        digitalWrite(latch, LOW);
        shiftOut(data, clk, LSBFIRST , 0xE5);
        digitalWrite(latch, HIGH);
        delay(100);

        smen = kmen = kodmen =  rfidmen = figmen =  devmen = 1;
        count_key = keypres = vybterm = karter = 0;
        pokus = 3;
        odkryvac = 2;
        bc = br = 0;

        lcd.noDisplay();
        lcd.setBacklight(LOW);
        sleepy = 0;
      }

      if (digitalRead(PIR) == HIGH) {
        SendMessage1();
        delay(20000);
      }

    }

  } else {

    while (br != 4) {
      br = bc  = 0;

      if (ALARM == 0) {
        if (devmen == 1) {
          lcd.clear();
          lcd.setCursor(0, 1); lcd.print("!!WARNING BURGLARY!!");
          digitalWrite(latch, LOW);
          shiftOut(data, clk, LSBFIRST , 0x67);
          digitalWrite(latch, HIGH);
          delay(50);
          devmen = 0;
        }
      } else if (ALARM == 1) {
        if (devmen == 1) {
          MakeCall();
          delay(5000);
          devmen = 0;
        }
      }

      if (ds.search(addr)) {                //overenie správnosti Smartbuttonu

        for (int bc = 0; bc < 8; bc++) {

          if (addr[bc] != keybut[br][bc]) {
            bc = 0;
            br++;
          }
        }
        ds.reset_search();
      }
    }

    lcd.clear();
    lcd.setCursor(3, 1); lcd.print("MASTER BUTTON");
    lcd.setCursor(6, 2); lcd.print("DETECTED");

    digitalWrite(latch, LOW);
    shiftOut(data, clk, LSBFIRST , 0xE5);
    digitalWrite(latch, HIGH);

    HangupCall();

    for (int x = 0; x < 3; x++) {
      delay(200);
      tone(buzz, 600);
      delay(200);
      noTone(buzz);
      delay(200);
    }
    if (EEPROM[0] < 60) {                     //Uzavretie Fingerprint pri ponechanom otvorenom

      lcd.clear();
      lcd.setCursor(3, 1);  lcd.print("SERVO POSITION");
      lcd.setCursor(8, 2); lcd.print(EEPROM[0]);

      digitalWrite(latch, LOW);
      servo.write(51);
      shiftOut(data, clk, LSBFIRST , 0xED);
      digitalWrite(latch, HIGH);
      delay(1000);

      for (int x = EEPROM[0]; x <= 144; x++) {
        lcd.setCursor(8, 2); lcd.print(x);
        servo.write(x);
        delay(30);
      }
      EEPROM[0] = 144;                        //Zápis trvá 3,3 ms!!!
      delay(5);

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xE5);
      digitalWrite(latch, HIGH);
      delay(1000);
    }

    lcd.clear();
    lcd.setCursor(3, 1);
    lcd.print("CLOSE THE DOOR!");
    while (digitalRead(MDD) == HIGH);

    smen = kmen = kodmen =  rfidmen = figmen =  devmen = 1;
    count_key = keypres = vybterm = karter = 0;
    pokus = 3;
    odkryvac = 2;
    bc = br = 0;
    delay(200);
  }
}




void enterpsw() {           // Zadanie hesla zobrazenie pre LCD
  lcd.clear();
  lcd.setCursor(3, 0);  lcd.print("ENTER PASSWORD");
  lcd.setCursor(7, 2);  lcd.print("(      )");
  lcd.setCursor(0, 2); lcd.print("TRY");
  lcd.setCursor(0, 3); lcd.print("< >");
  lcd.setCursor(1, 3); lcd.print(pokus);
}



void welcome() {             // UVÍTACIA ČASŤ:

  lcd.clear();
  lcd.setCursor(0, 1);


  for (int x = 8; x >= 0; x--) {
    lcd.setCursor(0, 1);
    for (int j = x; j <= 8; j++) {
      lcd.print(uvitanie0[j]);
      delay(10);
    }
  }
  for (int x = 1; x <= 6; x++) {
    lcd.setCursor(x - 1, 1);
    lcd.print(" ");
    lcd.setCursor(x, 1);
    lcd.print(uvitanie0);
    delay(60);
  }


  delay(2000);
  lcd.clear();
  lcd.setCursor(6, 0);
  lcd.print("THIS IS");
  delay(800);
  lcd.setCursor(2, 1);
  lcd.print("BACHELOR THESIS");
  delay(800);
  lcd.setCursor(2, 2);
  lcd.print("ON THE TOPIC OF");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 1);
  delay(200);
  for (int x = 0; x <= sizeof(uvitanie1) - 2; x++) {
    lcd.print(uvitanie1[x]);
    delay(40);
  }
  delay(2500);

  lcd.clear();
  lcd.setCursor(7, 0);
  lcd.print("AUTHOR:");
  delay(1000);
  lcd.setCursor(0, 2);
  for (int x = 0; x <= sizeof(uvitanie2) - 2; x++) {
    lcd.print(uvitanie2[x]);
    delay(40);
  }
  delay(760);
  lcd.setCursor(0, 3);
  lcd.print("VUT-BRNO");
  delay(800);
  lcd.setCursor(12, 3);
  lcd.print("FEEC");
  delay(800);
  lcd.setCursor(16, 3);
  lcd.print("/MET");
  delay(2000);
  lcd.clear();
  delay(100);

}


void butonchose(int Butcollor) {

  switch (Butcollor) {

    case 0:
      lcd.clear();
      lcd.setCursor(5, 1); lcd.print("RED BUTTON");
      lcd.setCursor(6, 2); lcd.print("DETECTED");

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0x65);
      digitalWrite(latch, HIGH);

      tone(buzz, 400);
      delay(250);
      tone(buzz, 600);
      delay(250);
      noTone(buzz);

      vybterm = figmen = 1;
      delay(1000);
      break;

    case 1:
      lcd.clear();
      lcd.setCursor(4, 1); lcd.print("GREEN BUTTON");
      lcd.setCursor(6, 2); lcd.print("DETECTED");

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xC5);
      digitalWrite(latch, HIGH);

      tone(buzz, 400);
      delay(250);
      tone(buzz, 600);
      delay(250);
      noTone(buzz);

      vybterm = figmen = 1;
      delay(1000);
      break;

    case 2:
      lcd.clear();
      lcd.setCursor(4, 1); lcd.print("BLUE BUTTON");
      lcd.setCursor(6, 2); lcd.print("DETECTED");

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xA5);
      digitalWrite(latch, HIGH);

      tone(buzz, 400);
      delay(250);
      tone(buzz, 600);
      delay(250);
      noTone(buzz);

      vybterm = figmen = 1;
      delay(1000);
      break;

    case 3:
      lcd.clear();
      lcd.setCursor(3, 1); lcd.print("YELLOW BUTTON");
      lcd.setCursor(6, 2); lcd.print("DETECTED");

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xC5);
      digitalWrite(latch, HIGH);

      tone(buzz, 400);
      delay(250);
      tone(buzz, 600);
      delay(250);
      noTone(buzz);

      vybterm = figmen = 1;
      delay(1000);
      break;


    case 4:
      lcd.clear();
      lcd.setCursor(3, 1); lcd.print("MASTER BUTTON");
      lcd.setCursor(6, 2); lcd.print("DETECTED");

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xC5);
      digitalWrite(latch, HIGH);

      tone(buzz, 400);
      delay(300);
      tone(buzz, 600);
      delay(350);
      noTone(buzz);

      vybterm = 4;
      devmen = 1;

      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xE5);
      digitalWrite(latch, HIGH);
      delay(2000);
      break;
  }
}




int getFingerprintID() {

  if (figmen == 1) {
    lcd.clear();
    lcd.setCursor(4, 0); lcd.print("!ATTENTION!");
    lcd.setCursor(3, 2); lcd.print("FINGER SENZOR");
    lcd.setCursor(4, 3); lcd.print("IS EXTENDED");

    for (int x = 0; x < 3; x++) {
      tone(buzz, 300);
      delay(300);
      noTone(buzz);
      delay(200);
    }

    delay(1300);

    digitalWrite(latch, LOW);
    servo.write(144);
    shiftOut(data, clk, LSBFIRST , 0xED);
    digitalWrite(latch, HIGH);
    delay(100);

    for (int x = 144; x >= 51; x--) {
      servo.write(x);
      delay(30);
    }

    EEPROM[0] = 51;
    delay(100);
    digitalWrite(latch, LOW);
    shiftOut(data, clk, LSBFIRST , 0xF5);
    digitalWrite(latch, HIGH);
    delay(200);
    lcd.clear();
    lcd.setCursor(7, 1); lcd.print("PLEASE");
    lcd.setCursor(1, 2); lcd.print("ATTACH YOUR FINGER");
    RTCmil = millis();
    casterm = millis();
    figmen = 0;
  }


  if ((millis() - RTCmil) <= 30000) {

    if ((millis() - casterm) >= 1000) {
      lcd.setCursor(18, 0); lcd.print((millis() - RTCmil) / 1000);
      casterm = millis();
    }

    uint8_t p = finger.getImage();

    if (p != FINGERPRINT_OK)  return -1;

    p = finger.image2Tz();
    if (p != FINGERPRINT_OK)  return -1;

    p = finger.fingerFastSearch();
    if (p != FINGERPRINT_OK)  return -1;


    if (finger.fingerID) {

      lcd.clear();
      lcd.setCursor(0, 0);  lcd.print("FINGER ID #");  lcd.print(finger.fingerID);
      lcd.setCursor(0, 1);  lcd.print("ACCURACY:");  lcd.print(finger.confidence);
      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xC5);
      digitalWrite(latch, HIGH);
      delay(10);
      tone(buzz, 500);
      delay(200);
      tone(buzz, 600);
      delay(300);
      noTone(buzz);
      delay(1000);
      lcd.clear();
      lcd.setCursor(3, 1);
      lcd.print("REMOVE FINGER");
      delay(2000);

      lcd.clear();
      lcd.setCursor(4, 0); lcd.print("!ATTENTION!");
      lcd.setCursor(0, 2); lcd.print("FINGER SENZOR CLOSES");
      for (int x = 0; x < 3; x++) {
        tone(buzz, 300);
        delay(300);
        noTone(buzz);
        delay(200);
      }

      delay(1300);

      digitalWrite(latch, LOW);
      servo.write(51);
      shiftOut(data, clk, LSBFIRST , 0xED);
      digitalWrite(latch, HIGH);
      delay(200);

      for (int x = 51; x <= 144; x++) {
        servo.write(x);
        delay(30);
      }
      EEPROM[0] = 144;
      delay(100);
      digitalWrite(latch, LOW);
      shiftOut(data, clk, LSBFIRST , 0xE5);
      digitalWrite(latch, HIGH);
      delay(200);

      vybterm = 2;
      figmen = rfidmen = 1;
      delay(1000);
    }
    // return finger.fingerID;
  } else {
    vybterm = 0;
    smen = figmen = 1;

    lcd.clear();
    lcd.setCursor(0, 1); lcd.print("THE TERMINAL DIDN'T");
    lcd.setCursor(1, 2); lcd.print("RECEIVE A RESPONSE");

    for (int x = 7; x >= 0; x--) {
      tone(buzz, tony_cdur[x]);
      delay(30);
      noTone(buzz);
      delay(20);
    }

    SendMessage();
    delay(5000);

    lcd.clear();
    lcd.setCursor(4, 0); lcd.print("!ATTENTION!");
    lcd.setCursor(0, 2); lcd.print("FINGER SENZOR CLOSES");

    for (int x = 0; x < 3; x++) {
      tone(buzz, 300);
      delay(300);
      noTone(buzz);
      delay(200);
    }

    delay(1300);

    digitalWrite(latch, LOW);
    servo.write(51);
    shiftOut(data, clk, LSBFIRST , 0xED);
    digitalWrite(latch, HIGH);
    delay(200);

    for (int x = 51; x <= 144; x++) {
      servo.write(x);
      delay(30);
    }
    EEPROM[0] = 144;
    delay(5);
    digitalWrite(latch, LOW);
    shiftOut(data, clk, LSBFIRST , 0xE5);
    digitalWrite(latch, HIGH);
    delay(200);
    RTCmil = millis();
  }
}

uint8_t getFingerprintEnroll(int id) {

  int p = -1;
  lcd.clear();
  lcd.setCursor(1, 0); lcd.print("WAITING FOR FINGER");
  lcd.setCursor(6, 2); lcd.print("ID #"); lcd.print(id);

  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
      case FINGERPRINT_OK:
        lcd.setCursor(4, 1);  lcd.print("IMAGE TAKEN "); lcd.write(byte(0));
        break;
    }
  }
  delay(2000);
  // OK success!

  p = finger.image2Tz(1);
  switch (p) {
    case FINGERPRINT_OK:
      lcd.setCursor(2, 2); lcd.print("IMAGE  CONVERTED");
      break;
  }
  delay(2000);

  lcd.clear();
  lcd.setCursor(3, 1); lcd.print("REMOVE  FINGER");
  delay(2000);
  p = 0;

  while (p == FINGERPRINT_NOFINGER) {
    p = finger.getImage();
  }


  //
  //  p = -1;
  //  lcd.clear();
  //  lcd.setCursor(1, 1); lcd.print("PLACE SAME FINGER");
  //  lcd.setCursor(7, 2); lcd.print("AGAIN");
  //
  //  while (p != FINGERPRINT_OK) {
  //    p = finger.getImage();
  //
  //    switch (p) {
  //      case FINGERPRINT_OK:
  //        lcd.clear();
  //        lcd.setCursor(4, 1);  lcd.print("IMAGE TAKEN"); lcd.write(byte(0));
  //        break;
  //    }
  //    delay(2000);
  //  }
  //
  //  // OK success!
  //
  //  p = finger.image2Tz(2);
  //  switch (p) {
  //    case FINGERPRINT_OK:
  //      lcd.setCursor(2, 2); lcd.print("IMAGE  CONVERTED");
  //      break;
  //  }
  //  delay(2000);
  //                          // OK converted!


  lcd.clear();
  lcd.setCursor(3, 1); lcd.print("CREATING MODEL");
  lcd.setCursor(5, 2); lcd.print("FOR ID#"); lcd.print(id);
  delay(2000);

  lcd.clear();
  p = finger.createModel();
  if (p == FINGERPRINT_OK) {
    lcd.setCursor(3, 1); lcd.print("PRINTS MATCHED");
  }
  delay(500);
  p = finger.storeModel(id);
  if (p == FINGERPRINT_OK) {
    lcd.setCursor(0, 3); lcd.print("......!STORED!......");

    for (int x = 0; x <= 7; x++) {
      tone(buzz, tony_cdur[x]);
      delay(20);
      noTone(buzz);
      delay(20);
    }
  }
  delay(2000);
}


void strEEP(int address, String str) {      // Zápis do EEPROM
  byte len = str.length();  
  EEPROM.write(address, len);
  delay(5);

  for (int i  = 0; i < len; i++) {
    EEPROM.update(address + 1 + i, str[i]);
    delay(5);
  }

}

String EEPstr(int address) {              // Čítanie z EEPROM
  int len = EEPROM.read(address);
  char DAT[len + 1];

  for (int i  = 0; i < len; i++) {
    DAT[i] = EEPROM.read(address + 1 + i);
  }
  DAT[len] = '\0';
  return String(DAT);
}


void SendMessage()
{
  GSMserial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  GSMserial.println("AT+CMGS=\"+421907369777\""); // Replace x with mobile number
  delay(1000);
  GSMserial.println("!Unauthorized handling of the terminal!");// The SMS text you want to send
  delay(100);
  GSMserial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

void SendMessage1()
{
  GSMserial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  GSMserial.println("AT+CMGS=\"+421907369777\""); // Replace x with mobile number
  delay(1000);
  GSMserial.println("!Unauthorized movement in the room!");// The SMS text you want to send
  delay(100);
  GSMserial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

void MakeCall()
{
  GSMserial.println("ATD+421907369777;"); // ATDxxxxxxxxxx; -- watch out here for semicolon at the end!!
  delay(1000);
}


void HangupCall()
{
  GSMserial.println("ATH");
  delay(200);
}

void gsmupdate()
{
  delay(500);
  while (GSMserial.available())
  {
    lcd.write(GSMserial.read());//Forward what Software Serial received to Serial Port
  }
  delay(500);
}
