#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include<Servo.h>
Servo myservo;
Servo maindoorservo;
int pos = 0;

int led = 13;

int ledpanelred = 30;
int ledpanelyellow = 29;
int ledpanelgreen1 = 28;
int ledpanelgreen2 = 27;
int ledpanelblue = 26;
int ledpanelgreen3 = 25;

int buzzer = 50;
int changemotor = 44; //activated when the change machine need to give change in 10p pieces
float change = 0; //holds the variable for the amount of change to return
int vendmotor1 =12;    //the motor to vend from the top row left/h/f selction
int vendmotor2 = 11;    //the motor to vend from the top row centre selction
int vendmotor3 = 2;    //the motor to vend from the top row right/h/f selction
int vendmotor4 = 3;     //the motor to vend from the middle row left/h/f selction  selction
int vendmotor5 = 8;     //the motor to vend from the middle row centre selction
int vendmotor6 =4;      //the motor to vend from the  middle row right/h/f selction
int vendmotor7 = 5;     //the motor to vend from the bottom row left/h/f selction
int vendmotor8 = 6;     //the motor to vend from the bottom row centre selction
int vendmotor9 = 7;     //the motor to vend from the top row right/h/f selction

float counter = 0; //counts up the coins for he credit
int ledPin = 22; //lights up when a coin is inserted and counted
int switchPin10p = A1; //reads pin for a coin from the 10p slot that has been seen by the sensor
int currentState10p = 0;  //states for reading the 10p coin sensor (current)
int previousState10p = 0;  // state for reading the 10p coin sensor (previous)
int val10p = 0; //variable for reading the switch pin for 10p coin
int switchPin50p = A0; // reads pin for a coin from the 50p sensor
int currentState50p = 0; // states for reading the 50p coin sensor (current)
int previousState50p = 0;  // state for reading the 50p coin sensor (previous)
int val50p = 0; //variable for reading the switch pin for 50p coin
int switchPin20p = A2; //reads pin for a coin from the 20p slot that has been seen by the sensor
int currentState20p = 0;  //states for reading the 20p coin sensor (current)
int previousState20p = 0;  // state for reading the 20p coin sensor (previous)
int val20p = 0; //variable for reading the switch pin for 20p coin
int slotVal =0; //variable for reading the switch pin for a coin entering the slot
int coinSlotSensorPin = 31; // reads a coin on this pin for a coin entering the machine
int coinSorterMotor = 52; // pin connected to the coinsorter
float totalTaken = 0;
int sensor1 = A3; // orange wire
int sensor2 = A4;  //pink wire
int sensor3 = A5; //yellow wire
int sensor4 = A7; // pink wire
int sensor5 = A8;  //yellow wire
int sensor6 = A9;  // orange wire
int sensor7 = A6; //yellow
int sensor8 = A10;
int sensor9 = A12;
//int coinSorterMotorState = LOW;
unsigned long slotSwitchActiveMillis;
unsigned long coinSorterMotorOnAt;
unsigned long turnOnDelay = 10;
unsigned long turnOffDelay = 11000;
bool motorReady = false;
bool motorState = false;
//int coinSlotTime = 6000; //duration for the coin counter motor to turn
int slotDelay = 0;
#define Password_Lenght 6 // Give enough room for four chars + NULL char

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
char Data[Password_Lenght]; // 6 is the number of chars it can hold + the null char = 7
char choice1[Password_Lenght] = "1111#"; 
char choice2 [Password_Lenght] = "2222#";
char choice3 [Password_Lenght] = "3333#";
char choice4 [Password_Lenght] = "4444#";
char choice5[Password_Lenght] = "5555#"; 
char choice6 [Password_Lenght] = "6666#";
char choice7 [Password_Lenght] = "7777#";
char choice8 [Password_Lenght] = "8888#";
char choice9 [Password_Lenght] = "9999#";
char total [Password_Lenght] = "A123#";  // DISPLAYS TOTAL MONEY TAKEN
char frontdoorlocked [Password_Lenght] = "AAAAA"; //locks front door
char frontdoorunlocked [Password_Lenght] = "BBBBB"; //unlockslocks front door
char addCredit50p [Password_Lenght] = "CCCCC";
byte data_count = 0, master_count = 0;
//byte data_count1 = 0, slave_count = 0;
bool Pass_is_good;
char customKey;

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {
  38,37,36,35}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  34,33,32,42}; //connect to the column pinouts of the keypad

Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad 

void setup()
{
 lcd.begin(16, 2);
 Serial.begin (9600);
 lcd.setCursor(0,0);
  lcd.print("System Check");

  maindoorservo.attach(46);
 maindoorservo.write (60);

  pinMode (led,OUTPUT);
  pinMode (buzzer, OUTPUT);
  tone (buzzer,3000, 30);
  delay (500);
   lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("buzzer OK ");
  pinMode (changemotor, OUTPUT);
  lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Coin Motor OK ");
    delay (200);
  pinMode (ledpanelred, OUTPUT);
  pinMode (ledpanelyellow, OUTPUT);
  pinMode (ledpanelgreen1, OUTPUT);
  pinMode (ledpanelgreen2, OUTPUT);
  pinMode (ledpanelblue, OUTPUT);
  pinMode (ledpanelgreen3, OUTPUT);
  digitalWrite (ledpanelred, HIGH);
  digitalWrite (ledpanelyellow, HIGH);
  digitalWrite (ledpanelgreen1, HIGH);
  digitalWrite (ledpanelgreen2, HIGH);
  digitalWrite (ledpanelblue, HIGH);
  digitalWrite (ledpanelgreen3, HIGH);  
  pinMode (vendmotor1, OUTPUT);
  pinMode (vendmotor2, OUTPUT);
  pinMode (vendmotor3, OUTPUT);
  pinMode (vendmotor4, OUTPUT);
  pinMode (vendmotor5, OUTPUT);
  pinMode (vendmotor6, OUTPUT);
  pinMode (vendmotor7, OUTPUT);
  pinMode (vendmotor8, OUTPUT);
  pinMode (vendmotor9, OUTPUT);
  pinMode (coinSlotSensorPin, INPUT);
  pinMode (coinSorterMotor, OUTPUT);
  digitalWrite (coinSorterMotor, HIGH);
  delay (1000);
  digitalWrite (coinSorterMotor, LOW);
  lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Coin Motor OK ");
  pinMode (switchPin10p, INPUT);
  
  pinMode (switchPin50p, INPUT);
  pinMode (switchPin20p, INPUT);
  pinMode (sensor1, INPUT);
  pinMode (sensor2, INPUT);
  pinMode (sensor3, INPUT);
  pinMode (sensor4, INPUT);
  pinMode (sensor5, INPUT);
  pinMode (sensor6, INPUT);
  pinMode (sensor7, INPUT);
  pinMode (sensor8, INPUT);
  pinMode (sensor9, INPUT);
  //DIAGNOSTICS
  sensor1 = analogRead(A3); // read input value
if (sensor1 > 700 ) { // check if the input is HIGH (button released)
lcd.clear ();
lcd.setCursor (0,0);
lcd.print ("sensor1 ok");
delay (500);
}
else {
  lcd.print ("SENSOR1 FAULT");
  delay (2000);
}

  lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("system check ");
    lcd.setCursor(0,1);
    lcd.print ("complete");
    delay (1000);
  tone (buzzer,3000, 30);
  delay (500);
  tone (buzzer,2000, 30);
  delay (500);
  tone (buzzer,4000, 30);
  delay (500);
  tone (buzzer,3000, 30);
  delay (500);
   myservo.attach(9);
  myservo.write (90);
  lcd.clear();
  digitalWrite (ledpanelred, LOW);
  delay (500);
  digitalWrite (ledpanelyellow, LOW);
  delay (500);
  digitalWrite (ledpanelgreen1, LOW);
  delay (500);
  digitalWrite (ledpanelgreen2, LOW);
  delay (500);
  digitalWrite (ledpanelblue, LOW);
  delay (500);
  digitalWrite (ledpanelgreen3, LOW);
}

void loop()
{
 digitalWrite (ledpanelgreen3, HIGH); 
 // Serial.println (sensor6);
 
 //********************************************************************************************** 
  lcd.setCursor(5,1);
lcd.print ("credit");
lcd.setCursor (12,1);
lcd.print (counter);
//********************************************************************************************** 
//coin slot 
unsigned long currentMillis = millis();
//check the button
if (digitalRead (coinSlotSensorPin)== HIGH){
  slotSwitchActiveMillis = currentMillis;
 motorReady = true;
  
}
if (motorReady) {
  if ((unsigned long) (currentMillis - slotSwitchActiveMillis) >= turnOnDelay) {
    digitalWrite (coinSorterMotor, HIGH);
    digitalWrite (ledpanelyellow, HIGH);
    motorState = true;
    coinSorterMotorOnAt = currentMillis;
    motorReady = false;
  }
}
 if (motorState) {
  if ((unsigned long) (currentMillis - coinSorterMotorOnAt) >= turnOffDelay) {
    motorState = false;
    digitalWrite (coinSorterMotor, LOW);
    digitalWrite (ledpanelyellow, LOW);
  }
 }

//********************************************************************************************** 
 
  val10p = analogRead(switchPin10p); // read input value
if (val10p < 500) { // check if the input is HIGH (button released)
digitalWrite(ledPin, HIGH); // turn LED on

currentState10p = 1;
}
else {
digitalWrite(ledPin, LOW); // turn LED off                     //THIS AREA IS COUNTING THE 10P
currentState10p = 0;
}
if(currentState10p != previousState10p){
if(currentState10p == 1){
counter = counter + 0.10;
tone (buzzer,4000, 30);
totalTaken = totalTaken + 0.10;

}
}
previousState10p = currentState10p;

//****************************************************************************************************
  val50p = analogRead(switchPin50p); // read input value
if (val50p < 800) { // check if the input is HIGH (button released)
digitalWrite(ledPin, HIGH); // turn LED on
currentState50p = 1;
}
else {
digitalWrite(ledPin, LOW); // turn LED off                     //THIS AREA IS COUNTING THE 50P
currentState50p = 0;
}
if(currentState50p != previousState50p){
if(currentState50p == 1){
counter = counter + 0.50;
tone (buzzer,4000, 30);
totalTaken = totalTaken + 0.50;

}
}
previousState50p = currentState50p;
  
//****************************************************************************************************
  val20p = analogRead(switchPin20p); // read input value
if (val20p < 700) { // check if the input is HIGH (button released)
digitalWrite(ledPin, HIGH); // turn LED on
currentState20p = 1;
}
else {
digitalWrite(ledPin, LOW); // turn LED off                     //THIS AREA IS COUNTING THE 20P
currentState20p = 0;
}
if(currentState20p != previousState20p){
if(currentState20p == 1){
counter = counter + 0.20;
tone (buzzer,4000, 30);
totalTaken = totalTaken + 0.20;

}
}
previousState20p = currentState20p;
if (counter >= 0.10) {
  digitalWrite (ledpanelgreen2, HIGH);
}
  else if (counter <= 0.10){
    digitalWrite (ledpanelgreen2, LOW);
  }

//****************************************************************************************************  
  lcd.setCursor(0,0);
  lcd.print("Insert Coins");

  customKey = customKeypad.getKey();
  if (customKey) // makes sure a key is actually pressed, equal to (customKey != NO_KEY)
  {
    tone (buzzer,3000, 30);
    Data[data_count] = customKey; // store char into data array
    lcd.setCursor(data_count,1); // move cursor to show each new char
    lcd.print(Data[data_count]); // print char at said cursor
    data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
  }

  if(data_count == Password_Lenght-1) // if the array index is equal to the number of expected chars, compare data to master
  {
   // lcd.clear();
   // lcd.setCursor(0, 0);
   // lcd.print("Thank You ");
  
    if (!strcmp(Data, total)){
      lcd.clear ();
      lcd.setCursor (0,0);
      lcd.print ("Total Taken");
      lcd.setCursor (0,1);
      lcd.print (totalTaken);
      delay (2000);
      lcd.clear();
    }

    if(!strcmp(Data, addCredit50p)){
      counter = counter + 0.50;
    }
     
    if(!strcmp(Data, frontdoorlocked)){ // equal to (strcmp(Data, Master) == 0)
      maindoorservo.write (175);  //locks door
      lcd.clear ();
  lcd.print("DOOR UNLOCKED");
  delay (2000);
  digitalWrite (ledpanelred, HIGH);
    }

    if(!strcmp(Data, frontdoorunlocked)){ // equal to (strcmp(Data, Master) == 0)
      maindoorservo.write (60);  //unlockslocks door
      lcd.clear ();
  lcd.print("DOOR LOCKED");
  delay (2000);
  digitalWrite (ledpanelred, LOW);
    }
      
      if(!strcmp(Data, choice1)&& (counter >= 0.10)){ // equal to (strcmp(Data, Master) == 0)

  analogWrite (vendmotor1, 180);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
      
      }
     else if(!strcmp(Data,choice2) && (counter >= 0.10)){ // equal to choice 2 code (2222#
  
  analogWrite (vendmotor2, 230);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print ("enjoy your food");
      }
      else if (!strcmp(Data,choice3) && (counter >= 0.10)){ // equal to choice3 password
  analogWrite (vendmotor3, 160);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
      else if (!strcmp(Data,choice4) && (counter >= 0.10)){ // equal to choice4 password
  analogWrite (vendmotor4, 100);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
      else if (!strcmp(Data,choice5) && (counter >= 0.10)){ // equal to choice5 password
  analogWrite (vendmotor5, 120);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
      else if (!strcmp(Data,choice6) && (counter >= 0.10)){ // equal to choice6 password
  analogWrite (vendmotor6, 135);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
      else if (!strcmp(Data,choice7) && (counter >= 0.10)){ // equal to choice7 password
  analogWrite (vendmotor7, 130);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
      else if (!strcmp(Data,choice8) && (counter >= 0.10)){ // equal to choice8 password
  analogWrite (vendmotor8, 150);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
      else if (!strcmp(Data,choice9) && (counter >= 0.10)){ // equal to choice9 password
  analogWrite (vendmotor9, 150);
  digitalWrite (ledpanelblue, HIGH);
  counter = counter - 0.10;
  lcd.print("enjoy your food");      
      }
  else
  {    
      lcd.print("No credit");
      }

    delay(5);// added 1 second delay to make sure the password is completely shown on screen before it gets cleared.
    lcd.clear();

   clearData();   
  }

  sensor1 = analogRead(A3); // read input value
if (sensor1 < 800 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor1, 0); // turn LED on
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
  lcd.print("crisp 1");
  delay (2000);

  

}
  sensor2 = analogRead(A4); // read input value
if (sensor2 < 800 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor2, 0); // turn LED on
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
  lcd.print("crisp 2");
  delay (2000);

}
  sensor3 = analogRead(A5); // read input value
if (sensor3 < 850 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor3, 0); // turn LED on
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
  lcd.print("crisp 3");
  delay (2000);

}
sensor4 = analogRead(A7); // read input value
if (sensor4 < 800 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor4, 0); // turn LED on
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
  lcd.print("KITKAT 4");
  delay (2000);

}
 sensor5 = analogRead(A8); // read input value
if (sensor5 < 700 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor5, 0); // turn LED on
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
  lcd.print("KITKAT 5");
  delay (2000);

}
 sensor6 = analogRead(A9); // read input value
if (sensor6 < 500 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor6, 0); // turn LED on
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
 lcd.print("KITKAT 6");
  delay (2000);

}
sensor7 = analogRead(A6); // read input value
if (sensor7 < 28 ) { // check if the input is HIGH (button released)
analogWrite(vendmotor7 , 0); // turn LED on
analogWrite(vendmotor8 , 0);
analogWrite(vendmotor9 , 0);
digitalWrite (ledpanelblue, LOW);
lcd.clear ();
  lcd.print("COKE");
  delay (2000);
}

//sensor7 = analogRead(A6); // read input value
//if (sensor7 < 5 ) { // check if the input is HIGH (button released)
//analogWrite(vendmotor8, 0); // turn LED on
//lcd.clear ();
 // lcd.print("COKE");
 // delay (2000); 

//}
//sensor7 = analogRead(A6); // read input value
//if (sensor7 < 5 ) { // check if the input is HIGH (button released)
//analogWrite(vendmotor9, 0); // turn LED on
//lcd.clear ();
  //lcd.print("COKE");
  //delay (2000);

//}

Serial.println (sensor7);
}

void clearData()
{
  while(data_count !=0)
  {   // This can be used for any array size, 
    Data[data_count--] = 0; //clear array for new data
  }
  return;

  }