/*
*Arduino Bomb wireless 2 way transmittion code
* Lucas Dahl
*/

// ARDUINO FOR BOMB ONE BY ROUND TABLE

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#include "Arduino.h"
#include "Keypad.h"
    
    byte pipeNum = 0;
int buzzer = A10;
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] = {26, 25, 24, 23}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {29, 28, 27}; //connect to the column pinouts of the keypad
int timers = 0;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

RF24 radio(7, 8); // CE, CSN
const byte address[][6] = {"00001","00002","00003","00004"};

int timer = 0;
int newtimer = 0;
//variables for buttons and their pin outputs
// the 4 small sqare buttons and their input states
int squareButton[] = {0,0,0,0,0};
int squarecheck = 0;
int othercheck = 0;
int largeSquares[] = {30,31,32,33,34};
int largecount = 0;

// the small square buttons and their pins
int squareBut[] = {0,0,0,0};
int test = 0;
int smallSquares[] = {37,35,38,36};
int smallcheck = 0;
int smallcount = 0;
int othersmall = 0;

int lift = 0;

//---------------------------------motion stuff
int motion = 39;
int motionsensor = 0;
int pirstate = LOW;
int motiontimer = 0;

//button states are the signals from both bombs, if a button is pressed
// the button is multiplied by a prime number and the other bomb reads
// the signal
long buttonStates = 0;
long buttonState = 0;
  int buttonStatet = 0;



// count is an array that will keep counts for when things are solved
int count[] = {0,0,0,0,0};



//the array to check when everything is satisfied
int finish[] = {0,0,0,0,0,0,0};
//the true or false state for the large and small buttons
int butState[] ={0,0,0,0,0,0,0,0,0,0,0};
int lastbutState[] ={0,0,0,0,0,0,0,0,0,0,0};


//----------------------------------------------------hold stuff
// pin values for the hold and number large buttons
int hold = 41;
// hold state reads if button is held
int holdState[] = {0,0};


//-------------------------------mic stuff
int mic = A0;
int micsensor = 0;
int miccount[] = {0,0};

//--------------------------- random led stuff
int randone =0;
int randtwo = 0;
int randleds[] = {11, 12, 13, A1, A2};
int randint = 0;
int placeholder = 0;

//------------------------------number button stuff
int counterleds[] = {49,53,2,5,4,3,10,9,6};
int countertimer= 0;
int countercount =0;
int num = 40;
// reads if the number is read correctly.
int numstate[] = {0,0};
int numcheck[] = {LOW,HIGH,0};

//------------------------------password stuff
int k = 0;
int password[4];
//password for 1 9 7 9
int pass[4] = {49,57,55,56};
int dummy = 0;

//------------------------------final stuff
int finalleds[] ={42,43,44,45,46,47,48};
int finalcount = 0;
int finalcheck = 0;
int timertwo = 0;
int timerthree =0;
int randtest=0;
int i = 0;

//analog pin for the lift relays
int lifter = A5;

//--------------------------------------------------------------------------SETUP-----------------------------------------------------------------------
void setup() {

  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer,HIGH);
  for (int i=0; i<10; i++){
  pinMode(randleds[i], OUTPUT);
  }
  pinMode(12, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(hold, INPUT);
  pinMode(num, INPUT);
  for(int j = 0;j<4;j++){
  pinMode(smallSquares[j], INPUT);
  }
    for(int j = 0;j<10;j++){
  pinMode(counterleds[j], OUTPUT);
  digitalWrite(counterleds[j],LOW);
  }
      for(int j = 0;j<7;j++){
  pinMode(finalleds[j], OUTPUT);
  digitalWrite(finalleds[j],LOW);
  }
  for(int j = 0;j<4;j++){
  pinMode(largeSquares[j], INPUT);
  }
  pinMode(motion, INPUT);
  pinMode(hold, INPUT);
  pinMode(num,INPUT);
  Serial.begin(9600);
  radio.begin();
  //opens up the channel to communicate between radios
  radio.openWritingPipe(address[3]);
  //reads from master room and sends tosafety send
  radio.openReadingPipe(0, address[0]);

     
  radio.setPALevel(RF24_PA_MIN);

 
  
}
//=================reads from back room sends to safety revieve
//============================================================================================LOOP=====================================================================================
void loop() {
//Serial.println(buttonStates);
//**********************************SENDING RADIO HERE*******************************************
   delay(5);
   radio.stopListening();

   
   
 //----------------------------------------------------------------Rand LEDS CODE----------------------------------------------------------------------------------
   numstate[0] = digitalRead(num);
   //Serial.println(numstate[0]);
   timertwo = millis();
   if ((timertwo - randtest) > 50){
    digitalWrite(randleds[placeholder],LOW);
    randtest = millis();
    randint = random(0,5);
    digitalWrite(randleds[randint],HIGH);
    placeholder = randint;
   }

   //-----------------------------------------------------------part 2 number button test-------------------------------------------------------------------------
   if (bitRead(buttonStates, 2) != 1){
      numstate[0] = digitalRead(num);
      //Serial.println(countercount);
      if(countercount == 1  && numstate[0] == 1 && numcheck[2]==0){
         numcheck[0]=HIGH;
         numcheck[1]=LOW;
         numcheck[2]=1;
         countercount = 1;
         for (int i=0; i<10; i++){
           digitalWrite(counterleds[i],LOW);
         }
         numstate[0]=0;
         Serial.println("yup");
       }
       if(numcheck[2] == 1 && countercount > 7 ){
         numcheck[2] =2;
       }        
       if(numcheck[2]==2 && countercount %2 != 0 && numstate[0]==1){
         //Serial.println("led 1 set");
         finalcount++;
         Serial.println("number");
         bitWrite(buttonStates, 2, 1);
         for (int i=0; i<10; i++){
            digitalWrite(counterleds[i],LOW);
         }
       }
       if(countercount%2!=0 && numstate[0]==1 && bitRead(buttonStates,2) != 1 && numcheck[2] !=3 && numcheck[2] !=1){
         numcheck[0]=LOW;
         numcheck[1]=HIGH;
         numcheck[2]=3;
         countercount = 0;
         for (int i=0; i<10; i++){
            digitalWrite(counterleds[i],HIGH);
         }
         numstate[0]=0;
         Serial.println("nope");
       } 
       if(numcheck[2] == 3 && countercount > 7 ){
         numcheck[2] =0;
       } 
   }
   //----------------------------------------------------------------Part 2 Number button counter-------------------------------------------------------------------------------
   if ((timertwo - countertimer) > 1000 && bitRead(buttonStates,2) != 1){
    digitalWrite(counterleds[countercount],numcheck[1]);
    digitalWrite(counterleds[countercount - 1],numcheck[0]);
    countercount++;
    if(countercount == 1){
      digitalWrite(counterleds[8],numcheck[0]);
    }
   //Serial.println(countercount);
    
    if(countercount > 8){
      countercount =0;
    }
    countertimer = timertwo;
   }

// Serial.println("key");
   //--------------------------------------------------------------part 5 keypad-------------------------------------------------------------------------------------------------
   if(bitRead(dummy,5) != 1){
      char key = keypad.getKey();
      if(key)  // Check for a valid key.
      {
        password[k]= key;
        k++;
        
        //Serial.print(key);
      if(k>3)
      {
         for (int j=0;j<4;j++){
          Serial.println(password[j]);
          Serial.print(pass[j]);
          if (password[j] == pass[j]){
            count[2]++;
          }
          else{
            count[2]=0;
             k =0;
             smallbeep();
          }
         }
         }
       if(count[2] == 4){
          bitWrite(dummy, 5, 1);
          finalcount++;
          Serial.println("Keypad");  
          //Serial.println(count[2]);
          //Serial.println("keypad");      
       }
      }
   }
  
 //Serial.println("small");
//----------------------------------------------------------------part 6 small buttons-------------------------------------------------------------------------------------------
if(bitRead(buttonStates,6)!=1){
 for (int m=0;m<4;m++){
      squareBut[m] = digitalRead(smallSquares[m]);
    //Serial.print(m);
    //Serial.print(":");
    //Serial.println(squareBut[m]);
     }
   if(smallcheck == 0){
   //tests each button except for the button that is next in the sequence and if any are pressed it will restart largecount
   for (int m=0;m<4;m++){
      if (m != smallcount){
        //skip so it doesn't check the button it is on 
        if (squareBut[m]==1){
          //if any fail it will reset the smallbutton section
          smallcount =0;
          smallcheck =0;
          bitWrite(buttonStates,10,1);
           bitWrite(buttonStates,9,0);
          //Serial.println("fail here");
          othersmall = 0;
        }
      }
      //if it is the button that is next it will skip it in the sequence, make sure this is at the end of the loop or it will test outside of the array
      if(m == smallcount){
        m++;
      }
    }
    //Serial.println(bitRead(buttonState,9));
    //makes sure the other room checked the next button
    if(bitRead(buttonState,9)==1 && othersmall ==0){
      othersmall++;
      bitWrite(buttonStates,9,0);
      //Serial.println("otherroom pass");
    }    
    //if the next button is pressed, if it is the first button, and tests only if the other room past
    if(squareBut[smallcount]==1 && othersmall == 1){
      smallcount++;
      beep();
      bitWrite(buttonStates,9,1);
      bitWrite(buttonStates,10,0);
     // Serial.println(smallcount);
      smallcheck =1;
      othersmall =0;
      //Serial.println("passed");
    }

    //if the other room fails it resets everything including the fail test for this room
    if(bitRead(buttonState,10)==1){
      smallcount =0;
      smallcheck =0;
      bitWrite(buttonStates,10,0);
      bitWrite(buttonStates,9,0);
      //Serial.println("otherroom failed");

    }
  }
  //this is what resets the smallcheck when the button is released
  if(smallcount == 0 || (smallcheck == 1 && squareBut[smallcount -1] == 0)){
    smallcheck =0;
    bitWrite(buttonStates,10,0);
    //Serial.println("zeroed");
  }
  //when it reaches the last button in the series it activates
  if(smallcount > 3){
    finalcount ++;
    bitWrite(buttonStates, 6,1);
    Serial.println("Small Square");
  }
 
 
  if(bitRead(buttonState,6) == 1 && squareBut[3] ==1){
    finalcount ++;
    bitWrite(buttonStates, 6,1);
    Serial.println("Small Square");
  }
}


// Serial.println("large");
//-----------------------------------------------------------------------------------Large Button-------------------------------------------------------------------
 
// This if statement shuts off the large buttons when it is completed
if(bitRead(buttonStates,7)!=1){
  //Reads the five buttons if they are pushed or not, there is also a serial print incase an individual button needs to be identified
  for (int m=0;m<5;m++){
    squareButton[m] = digitalRead(largeSquares[m]);
    //Serial.print(m);
    //Serial.print(":");
    //Serial.println(squareButton[m]);
  }
  //the squarecheck function makes sure that the button is released before it checks again or else it will trigger again.
  if(squarecheck == 0){
   //tests each button except for the button that is next in the sequence and if any are pressed it will restart largecount
   for (int m=0;m<5;m++){
      if (m != largecount){
        //skip so it doesn't check the button it is on 
        if (squareButton[m]==1){
          //if any fail it will reset the largebutton section
          largecount =0;
          squarecheck =0;
          bitWrite(buttonStates,14,1);
           bitWrite(buttonStates,13,0);
         // Serial.println("fail here");
          othercheck = 0;
        }
      }
      //if it is the button that is next it will skip it in the sequence, make sure this is at the end of the loop or it will test outside of the array
      if(m == largecount){
        m++;
      }
    }
    //Serial.println(bitRead(buttonState,13));
    //makes sure the other room checked the next button
    if(bitRead(buttonState,13)==1 && othercheck ==0){
      othercheck++;
      bitWrite(buttonStates,13,0);
      //Serial.println("otherroom pass");
    }    
    //if the next button is pressed, if it is the first button, and tests only if the other room past
    if(squareButton[largecount]==1 && othercheck == 1){
      largecount++;
      beep();
      bitWrite(buttonStates,13,1);
      bitWrite(buttonStates,14,0);
      //Serial.println(largecount);
      squarecheck =1;
      othercheck =0;
      //Serial.println("passed");
    }

    //if the other room fails it resets everything including the fail test for this room
    if(bitRead(buttonState,14)==1){
      largecount =0;
      squarecheck =0;
      bitWrite(buttonStates,14,0);
      bitWrite(buttonStates,13,0);
      //Serial.println("otherroom failed");

    }
  }
  //this is what resets the squarecheck when the button is released
  if(largecount == 0 || (squarecheck == 1 && squareButton[largecount -1] == 0)){
    squarecheck =0;
    bitWrite(buttonStates,14,0);
    //Serial.println("zeroed");
  }
  //when it reaches the last button in the series it activates
  if(largecount > 4 || bitRead(buttonState, 7)==1 ){
    finalcount ++;
    bitWrite(buttonStates, 7,1);
    Serial.println("Big Square");
  }
}

 //Serial.println("motionSensor");
//--------------------------------------------------------------------------------part 3 motion sensor-------------------------------------------------------------------------- 
  if( bitRead(buttonStates,3) != 1){
    //Serial.println(motiontimer);
     motionsensor = digitalRead(motion);  // read input value
     //Serial.println(motionsensor);
     if (motionsensor == HIGH) {            // check if the input is HIGH
       if (pirstate == LOW) {
         pirstate = HIGH;
         motiontimer = timertwo;
         count[1] =0;
         //Serial.println("deteckted");
       }
     } else {
       if (pirstate == HIGH){
         pirstate = LOW;
         //Serial.println("busted");
         count[1] = 0;
       }
       if (pirstate == LOW && timertwo - motiontimer > 3000){
        count[1]++;
        motiontimer = timertwo;
        //Serial.println(count[1]);
       }
       if (count[1] >90){
          bitWrite(buttonStates, 3, 1);
          finalcount++;
          Serial.println("motionsensor");
       }    
     }
  }
//----------------------------------------------------------------------------------part 4 nock knnock----------------------------------------------------------------------------------
if(timertwo > 5000){
  timers = 1;
}
 if(bitRead(buttonStates,4) != 1 && timers == 1){
     micsensor = analogRead(mic);
     Serial.println(micsensor);

     if(micsensor < 150 && miccount[1] == 0){
        miccount[0]++;
        miccount[1] = 1;
        Serial.println(miccount[0]);
         timer = millis();
     }
    if(micsensor < 150 && miccount[1] == 1){
        miccount[0]++;
        miccount[1] = 1;
        //Serial.println(miccount[0]);

     }

     if(miccount[1] == 1 && (timertwo - timer  < 30000) && miccount[0] > 15){
         bitWrite(buttonStates, 4, 1);
         finalcount++;
         Serial.println("Knock Knock");
     }
     if(miccount[1] ==1 && timertwo - timer > 30000){
      miccount[0] =0;
      miccount[1]= 0;
      timer = millis();
     }
 }
 //----------------------------------------------------------------------------------------part 1 hold--------------------------------------------------------------------------------------
 if(bitRead(buttonState,1)==1){
  bitWrite(buttonStates,1,1);
 }
 if(bitRead(buttonStates,1)!=1){
 holdState[0] = digitalRead(hold);
 if (holdState[0] == HIGH ){
  if(bitRead(buttonStates,8)!=1){
  bitWrite(buttonStates, 8, 1);
  }
 }
 else{
  holdState[1] = timertwo;
  if(bitRead(buttonStates,8)==1){
   bitWrite(buttonStates, 8, 0);
  }
 }
 if ( (holdState[0]== HIGH && bitRead(buttonState,8)==1 && timertwo - holdState[1] > 30000) || bitRead(buttonState, 1) ==1){
    Serial.println("HOLD");
    bitWrite(buttonStates,1,1);
    finalcount++;
 }
}

 //-------------------------------------------------------------------------------------------final leds------------------------------------------------------------------------------------
if (finalcount >0){
  digitalWrite(finalleds[finalcheck],HIGH);
  finalcount = finalcount -1;
  beep();
  finalcheck++;
}
if (finalcheck >6){
  bitWrite(buttonStates,12,1);
}
else{
  bitWrite(buttonStates,12,0);
}
 //Serial.println(bitRead(buttonStates,15));
 radio.write(&buttonStates, sizeof(buttonStates));
 //Serial.println("goodbye");
 //chennel 3
//****************************************LISTENING HERE******************************************  
 

  radio.startListening();
   
  
    if (radio.available()){ 
     radio.read(&lift, sizeof(lift));
     //Serial.print("address[0]:  ");
     //Serial.println(lift);
     buttonState = lift;
  }
  //Serial.println(buttonState);
  if(bitRead(lift,15) == 1){
  bitWrite(buttonStates,15,1);
      analogWrite(lifter,1000);
  
  }
  if(bitRead(lift,15)==0){
    bitWrite(buttonStates,15,0);
    analogWrite(lifter,000);
    for (int m=0;m<18;m++){
      bitWrite(buttonStates,m,0);
      bitWrite(buttonState,m,0); 
      finalcheck=0;    
      digitalWrite(finalleds[m],LOW);
      numcheck[2]=0;
      countercount =0;
      numstate[0]=0;
      k = 0;
      smallcheck =0;
      smallcount =0;
      squarecheck =0;
      largecount =0;
      count[1] = 0;
      miccount[0] =0;
      miccount[1]= 0;
      timer = millis();
      dummy = 0;
 }
  }
Serial.println(bitRead(lift,5));
Serial.println("Hello");

  if(bitRead(lift,5) == 1 && bitRead(dummy,2) == 0){
    Serial.println("countEr");
    bitWrite(buttonStates,5,1);
    finalcount++;
    bitWrite(dummy,2,1);
  }
  
  if(bitRead(lift,5) ==0){
    bitWrite(buttonStates,5,0);
    bitWrite(dummy,2,0);
  }
  
  }
  
void beep(){
  digitalWrite(buzzer,LOW);
  delay(70);
  digitalWrite(buzzer,HIGH);
}
void smallbeep(){
    digitalWrite(buzzer,LOW);
  delay(5);
  digitalWrite(buzzer,HIGH);
}
