// 11Sep2022 - v0.1

#include <Adafruit_Fingerprint.h>
#include <Adafruit_GFX.h>       // include Adafruit graphics library
#include <Adafruit_ILI9341.h>   // include Adafruit ILI9341 TFT library
#include <Servo.h>

SoftwareSerial mySerial(2, 3);
Servo ServoMotor;

char Incoming_value = '1';      //Initialized variable to store recieved data
int Door_stat = 1 , Bypass_stat = 1,  Servo_position = 0;
uint8_t p;

unsigned long previousMillis_Waiting = 0;
unsigned long currentMillis_Waiting ;

#define RELAY_PIN            4
#define ACCESS_DELAY         3000         // Keep lock unlocked for 3 seconds 
#define DOOR_SW              A5           // Door status to check if the door is really open or closed
#define BYPASS_BIOMETRIC     A4           // To bypass biometric switch / remote switch for manual unlock
#define SERVO_PIN            A3


#define TFT_CS    10      // TFT CS  pin is connected to arduino pin 10
#define TFT_RST   9       // TFT RST pin is connected to arduino pin 9
#define TFT_DC    8       // TFT DC  pin is connected to arduino pin 8

// initialize library
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

void setup() {

  // Uncomment to enable fingerprint scanner
  // Setup_fingerprint_sensor();
 

  // Begin the Serial at 9600 Baud
  Serial.begin(9600);

  pinMode(DOOR_SW, INPUT_PULLUP);
  pinMode(BYPASS_BIOMETRIC, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, HIGH);   // Switch off relay initially. Relay is LOW level triggered relay so we need to write HIGH.
  ServoMotor.attach(SERVO_PIN);
  ServoMotor.write(0);             // Locked position

  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  //tft_diagnostics();
  tft.setRotation(1);

  boot_screen();
  delay(3000);

  tft.fillScreen(ILI9341_BLACK);
}

void loop() {

  Door_stat = digitalRead(DOOR_SW);
  Bypass_stat = digitalRead(BYPASS_BIOMETRIC);

  tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);

  // Door closed
  if (Door_stat == 1)
  {

    tft.setCursor(20, 200);
    tft.setTextSize(3);

    tft.print("Status: Closed");

  }

  // Door opened
  if (Door_stat == 0)
  {
    tft.setCursor(20, 200);
    tft.setTextSize(3);

    tft.print("Status: Opened");
    currentMillis_Waiting = millis();
    if (currentMillis_Waiting - previousMillis_Waiting > 10000)
    {
      previousMillis_Waiting = currentMillis_Waiting;

      tft.setCursor(20, 75);
      tft.setTextSize(4);
      tft.setTextColor(ILI9341_YELLOW);
      tft.print("Door opened");
      
    }

  }

  if (Serial.available() > 0)
  {
    Incoming_value = Serial.read();
    Serial.print(Incoming_value);
    Serial.print("\n");
  }

     if (Incoming_value == '1' && Bypass_stat == 1)
    {   
      p = finger.fingerSearch();

        if (p == FINGERPRINT_NOTFOUND)
        {
          Serial.println("Did not find a match");
          tft.setCursor(0, 75);
          tft.setTextSize(4);
          tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
          tft.print(" Not Match   ");
        }

//        if (p == FINGERPRINT_PACKETRECIEVEERR)
//        {
//          Serial.println("Communication error");
//          tft.setCursor(0, 75);
//          tft.setTextSize(4);
//          tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
//          tft.print("    ERROR   ");
//        }
        
      currentMillis_Waiting = millis();
      if (currentMillis_Waiting - previousMillis_Waiting > ACCESS_DELAY)
      {
        previousMillis_Waiting = currentMillis_Waiting;
       
       
        tft.setCursor(0, 75);
        tft.setTextSize(4);
        tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
        tft.print("              ");

        digitalWrite(RELAY_PIN, HIGH);
        ServoMotor.write(0);                    // Locked position
      }
    }

    // Make sure the door is closed
    else if ((Incoming_value == '0' || Bypass_stat == 0 || p == FINGERPRINT_OK)  && Door_stat == 1)
    {
      Serial.println("Door unlocked...");  
      tft.setCursor(0, 75);
      tft.setTextSize(4);
      tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
      tft.print("Door unlocked");

      digitalWrite(RELAY_PIN, LOW);
      ServoMotor.write(180);                    // Unlock position
    }

//  delay(50);            //Add some delay before next scan.

  
}

void boot_screen()
{
  //  320*240
  //  --------------------
  //  -     BIOMETRIC    -
  //  -       DOOR       -
  //  -      LOCKING     -
  //  -      SYSTEM      -
  //  --------------------

  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(5);
  tft.setCursor(15, 25);
  tft.println("BIOMETRIC");
  tft.setCursor(90, 75);
  tft.println("DOOR");
  tft.setCursor(45, 125);
  tft.println("LOCKING");
  tft.setCursor(60, 175);
  tft.println("SYSTEM");

}

void tft_diagnostics()
{
  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
}

void Setup_fingerprint_sensor()
{

  // set the data rate for the sensor serial port
  finger.begin(57600);
  delay(5);
  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) {
      delay(1);
    }
  }
}
lcd1:VCC
lcd1:GND
lcd1:CS
lcd1:RST
lcd1:D/C
lcd1:MOSI
lcd1:SCK
lcd1:LED
lcd1:MISO
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
led1:A
led1:C
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
r4:1
r4:2
r5:1
r5:2
r6:1
r6:2
r7:1
r7:2
r8:1
r8:2
r9:1
r9:2
r10:1
r10:2
r11:1
r11:2
sw1:1
sw1:2
sw1:3
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
servo1:GND
servo1:V+
servo1:PWM
esp1:VIN
esp1:GND.2
esp1:D13
esp1:D12
esp1:D14
esp1:D27
esp1:D26
esp1:D25
esp1:D33
esp1:D32
esp1:D35
esp1:D34
esp1:VN
esp1:VP
esp1:EN
esp1:3V3
esp1:GND.1
esp1:D15
esp1:D2
esp1:D4
esp1:RX2
esp1:TX2
esp1:D5
esp1:D18
esp1:D19
esp1:D21
esp1:RX0
esp1:TX0
esp1:D22
esp1:D23
r12:1
r12:2
r13:1
r13:2
r14:1
r14:2
r15:1
r15:2