//email: smartlocker.suza@gmail.com
//password: suza@2024

//#include <SPI.h> 
//#include <MFRC522.h> 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DFRobotDFPlayerMini.h"
#include <Keypad.h>

#define  SS   5
#define  RST  4

const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {13, 12, 14, 27}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {26, 25, 33}; // connect to the column pinouts of the keypad

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 20, 4);
//MFRC522 scanner(SS,RST);
DFRobotDFPlayerMini myDFPlayer;

const uint8_t maximum=6;
//uint8_t index;
String tag[6]={"xx","xx","xx","xx","xx","xx"};
String password[6]={"xx","xx","xx","xx","xx","xx"};

void setup()
{
  Serial.begin(9600);
  Serial.println("setup in progress");
  lcd.init();
  lcd.backlight();
  welcomeDisplay();
  Serial2.begin(9600);
 
  //SPI.begin();
  //scanner.PCD_Init();

  if (!myDFPlayer.begin(Serial2)) {
    Serial.println(F("Not initialized:"));
    Serial.println(F("1. Check the DFPlayer Mini connections"));
    Serial.println(F("2. Insert an SD card"));
    //while (true);
  }
  Serial.println();
  Serial.println(F("DFPlayer Mini module initialized!"));
  // Initial settings
  myDFPlayer.volume(30);        // Volume 5
  myDFPlayer.play(5);
  welcomeDisplay();
  lcd.clear();
  Serial.println("setup done");
}

void loop()
{
  init_display();
  String tempTag=readTag();
  if(tempTag!="error")
  {
    uint8_t tempIndex=analyseTag(tempTag);
    if(tempIndex != 99)
    {
      tag[tempIndex]="xx";
      password[tempIndex]="xx";
      Serial.print(String(tempIndex+1));
      delay(7000);
    }
    else
    { 
        uint8_t tempIndex2=offer_room(tempTag);
        if(tempIndex2 != 99)
        {
          Serial.print(String(tempIndex2+1));
        }
    }
    lcd.clear();
  }
}

void init_display()
{
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("Scan to be Granted/");
  lcd.setCursor(0,2);
  lcd.print(" Unlock Locker Room ");
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");
}

String readTag()
{
   /* if(!scanner.PICC_IsNewCardPresent())
    {
      //Serial.println("no card present");
      return "error";
    }
    if(!scanner.PICC_ReadCardSerial())
    {
      //Serial.println("card not readable");
      return "error";
    }
    //save data and return output
    String myTag;
    for (int i = 0; i < scanner.uid.size; i++) 
    {
      myTag += String(scanner.uid.uidByte[i],HEX);
    }
    //Serial.print("THE TAG DETECTED IS:");
    //Serial.println(myTag);
    return myTag;*/
    if(Serial.available())
    {
      String myTag=Serial.readString();
      Serial.println(myTag);
      return myTag;
    }
    else
    {
      Serial.println("error");
      return "error";
    }   
}

unsigned int analyseTag(String tagId)
{
  Serial.println("now analysing");
  for(uint8_t i=0;i<6;i++)
  {
    if(tagId==tag[i])
    {
      String curpin=requestPIN();
      if(password[i]== curpin)
      {
        result1_display(i);
        return i; 
      }                                                                                                                                                                                                                                                                                                                                                                                                                                              
      else
      {
        denyDiplay();
      }
    }
  }
  result2_display();
  return 99;  
}

uint8_t offer_room(String tagId)
{
  for(uint8_t i=0;i<6;i++)
  {
    if(tag[i]=="xx")
    {
      tag[i]=tagId;
      String curpin=requestPIN();
      password[i]=curpin;
      result3_display(i);
      return i;       
    }
  }
  result4_display();
  return 99;   
}

void welcomeDisplay()
{
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SECURE ACCESS LOCKER"); 
     lcd.setCursor(0,1);
     lcd.print("       SYSTEM      "); 
     lcd.setCursor(0,2);
     lcd.print("SYSTEM INITIALIZE");
     lcd.setCursor(0,3);
     lcd.print("PLEASE WAIT");
     for(uint8_t i=11;i<20;i++)
     {
      lcd.setCursor(i,3);
      lcd.print("_");
      delay(500);
     }
}

void result1_display(uint8_t i)
{
  //myDFPlayer.play((i+7));
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("Take your belongings");
  lcd.setCursor(0,2);
  lcd.print("from room number:");
  lcd.setCursor(17,2);
  lcd.print(String(i+1));
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");
}

void result2_display()
{
  //myDFPlayer.play(13);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("Serching for Room in");
  lcd.setCursor(0,2);
  lcd.print("locker.Please wait..");
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");
  delay(3000);
}

void result3_display(uint8_t i)
{
  uint8_t num;
  if(i>=0 && i<=1){num=14+i;}
  else if(i>1 && i<6){num=i-1;}
  //myDFPlayer.play(num);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("Place ur belongings");
  lcd.setCursor(0,2);
  lcd.print("in room number:");
  lcd.setCursor(15,2);
  lcd.print(String(i+1));
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");
  delay(3000);
}

void result4_display()
{
  //myDFPlayer.play(6);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("Soory!,Locker Loaded");
  lcd.setCursor(0,2);
  lcd.print("Please Retry Later");
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");
  delay(6000);
}

void denyDiplay()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("SORRY, PIN DOES NOT ");
  lcd.setCursor(0,2);
  lcd.print("  MATCH. TRY AGAIN  ");
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");
  delay(2000);
}
String requestPIN() {
  String pin = "";
  Serial.println("Enter 4-digit PIN:");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--------<<>>--------");
  lcd.setCursor(0,1);
  lcd.print("ENTER YOUR PIN:");
  lcd.setCursor(0,2);
  lcd.print("                    ");
  lcd.setCursor(0,3);
  lcd.print("--------<<>>--------");

  while (pin.length() < 4) {
    char key = keypad.getKey();
    if (key) 
    {
      if (key == '*' || key == '#') 
      {
        Serial.println("Invalid character. Please use numbers.");
      } 
      else 
      {
        pin += key;
        Serial.print(key); // Echo the character
        lcd.setCursor((15+pin.length()),1);
        lcd.print("*");
      }
    }
  }
  lcd.setCursor(0,2);
  lcd.print("VERIFYING PIN.......");
  Serial.println(); // Move to the next line after entering the PIN
  return pin;
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
led1:A
led1:C
FIRE SENSOR
IOT BASED LOCKING SYSTEM WITH ACCESS CONTROL FOR M/MMOJA HOSPITAL
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
led2:A
led2:C
r2:1
r2:2
r4:1
r4:2
rfid-rc522Breakout
chip1:SS
chip1:SCK
chip1:MOSI
chip1:MISO
chip1:IRQ
chip1:GND
chip1:RST
chip1:VCC
mini-mp3-player-moduleBreakout
chip2:VCC
chip2:RX
chip2:TX
chip2:DAC_R
chip2:DAC_I
chip2:SPK_1
chip2:GND
chip2:SPK_2
chip2:BUSU
chip2:USB-
chip2:USB+
chip2:ADKEY_2
chip2:ADKEY_1
chip2:IO_2
chip2:GND
chip2:IO_1
keypad1:R1
keypad1:R2
keypad1:R3
keypad1:R4
keypad1:C1
keypad1:C2
keypad1:C3
keypad1:C4