#include <EEPROM.h>         // INCLUDE THE EEPROM LIBRARY SO THAT WE CAN STORE AND READ BACK DATA FROM MEMORY AFTER POWER OFF
#include <RF24Network.h>    // INCLUDE THE FOLLOWING THREE LIBRARIES
#include <RF24.h>           // ONCE DOWNLOADED, INCLUDE THIS LIBRARY AS WELL
#include <SPI.h>            // INCLUDE THE SPI COMMUNICATIONS LIBRARY
// LET'S SET UP THE NRF24L01+ WIRELESS TRANCEIVER
RF24 radio(7,8);                        //  NRF24L01(+) RADIO CONNECTIONS (GPIO PINS 7 AND 8)
RF24Network network(radio);             // THIS IS A LIBRARY COMMAND THAT CALLS THE 24L01+ NETWORK "RADIO"
const uint16_t this_node = 00;          // THIS BOARD (EPOCH) IS 00 (this_node)
const uint16_t other_node = 01;         // THIS IS THE ADDRESS OF THE SHIELD/TRANSMITTER (other_node).  THESE SETTINGS ARE THE OPPOSITE OF THE SHIELD
struct payload_t {                      // THIS IS THE STRUCTURE OF OUR PAYLOAD - SEE THE NOTES SECTION, AS THIS VARIES A LITTLE BIT FROM THE TRANSMITTER
unsigned long addressz;                 // WE'LL RECEIVE THE DATA FROM OUR SHIELD AND PLACE IT INTO THESE TWO INTEGERS
unsigned long instructionz;           
};

// NOW LET'S SET UP THE SD CARD
#include <SD.h>       // INCLUDE THE SD CARD LIBRARY.  IF YOU DON'T HAVE IT, IMPORT IT FROM GITHUB
File myFile;          // WE'RE GOING TO MAKE THIS DECLARATION FOR THE SD CARD READER/WRITER.  YOU ARE NAMING YOUR FILE.  YOU CAN CALL IT (File MrRogers) if you want.  Just leave it as myFile for now, though.

// LET'S SET UP THE LCD
#include "LiquidCrystal.h"         // INCLUDE THE LIBRARY THAT HELPS TO DRIVE THE LCD.
LiquidCrystal lcd(6,4,17,9,10,11); // LCD pins RS/E/D4/D5/D6/D7 connected to UNO pins 6,4,17,9,10,11 Respectively.  USING THE LCD QUICK-CONNECT DIP SWITCH DOES ALL OF THIS FOR YOU ON CHIP-A

// LET'S SET UP THE COMPUTER KEYBOARD
#include <PS2Keyboard.h>        // INCLUDE THE PS2 KEYBOARD LIBRARY.  IF YOU DON'T HAVE IT, YOU CAN GET IT FROM GitHub
const int DataPin = 2;          // THIS IS THE DATA PIN FOR THE KEYBOARD
const int IRQpin =  3;          // THIS IS THE CLOCK PIN FOR THE KEYBOARD
PS2Keyboard keyboard;           // THE NAME OF OUR KEYBOARD IS GOING TO BE REFERRED TO AS "keyboard"

// LET'S SET UP THE DS3231 REAL TIME CLOCK
#include "RTClib.h"   // INCLUDE THE RTC LIBRARY
RTC_DS3231 rtc;       // DECLARE THE DS3231 RTC
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};   // THIS IS AN ARRAY.  WE'LL TALK MORE ABOUT ARRAYS LATER, BUT THEY ARE A VERY USEFUL WAY TO POINT TO/HAVE CONTROL OVER MANY INTEGERS ALL AT ONCE

// THE FOLLOWING SECTION CONSISTS OF A BUNCH OF DIFFERENT SETS OF LISTS
//
// LET'S PUT TOGETHER A SET OF WORD LISTS THAT WE'LL USE TO LATER CALL OUR PROGRAMS:
int emptycode[] = {0 ,0 ,0 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //
int cmd1[] = {121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // yes "y"  
int cmd2[] = {110 ,0 ,0 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // no "n"
int cmd3[] = {100, 105, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // dir
int cmd4[] = {109, 97, 116, 114, 105, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // matrix
int cmd5[] = {114, 101, 115, 101, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // reset
int cmd6[] = {97, 108, 97, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // alarm
int cmd7[] = {115, 108, 101, 101, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // sleep
int cmd8[] = {108, 101, 100, 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ledtest
int cmd9[] = {98, 117, 122, 122, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // buzzer
int cmd10[] = {98, 108, 117, 101, 116, 111, 111, 116, 104, 0, 0, 0, 0, 0, 0, 0}; // bluetooth
int cmd11[] = {115, 99, 114, 101, 97, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // scream
int cmd12[] = {114, 101, 100, 32, 97, 108, 101, 114, 116, 0, 0, 0, 0, 0, 0, 0}; // red alert
int cmd13[] = {101, 120, 105, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // exit
int cmd14[] = {115, 111, 117, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // sound
int cmd15[] = {100, 97, 116, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // date
int cmd16[] = {100, 97, 116, 101, 115, 112, 101, 97, 107, 0, 0, 0, 0, 0, 0, 0}; // datespeak
int cmd17[] = {116, 105, 109, 101, 115, 112, 101, 97, 107, 0, 0, 0, 0, 0, 0, 0}; // timespeak
int cmd18[] = {108, 105, 103, 104, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // light
int cmd19[] = {110, 111, 105, 115, 101, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // noises
int cmd20[] = {110, 101, 116, 119, 111,114, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // network
int cmd21[] = {112, 114, 111, 103, 114, 97, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // program
int cmd22[] = {105, 109, 112, 101, 114, 105, 97, 108, 0, 0, 0, 0, 0, 0, 0, 0}; // imperial
int cmd23[] = {102, 108, 97, 115, 104, 109, 111, 111, 100, 0, 0, 0, 0, 0, 0, 0}; // flashmood
int cmd24[] = {109, 121, 109, 111, 111, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // mymood
int cmd25[] = {102, 108, 97, 115, 104, 109, 111, 111, 100, 9, 0, 0, 0, 0, 0, 0}; // flashmood
// int cmd26[] = {0 ,0 ,0 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // You create your new word!


// THIS LIST IS USED FOR BLUETOOTH PROGRAMS
int btread[] = {0 ,0 ,0 ,0, 0, 0};

// THIS LIST HOLDS A FOUR DIGIT SECURITY CODE THAT WE'LL ENTER TO GAIN ACCESS TO THE BUTLER
int securitycode[] = {0 ,0 ,0 ,0};

// THE FOLLOWING LIST WILL HOLD OUR ENTERED MOOD LOGGINGS OVER TIME.  WE'LL READ EEPROM MEMORY AND STORE THE SAVED VALUES INTO THIS LIST
int mymood[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; // LOG MOOD OVER 30 DAYS
int pointer = 0;  // THE FOLLOWING FOUR INTEGERS ARE ALL USED SPECIFICALLY FOR MOOD LOGGING PURPOSES
int divisor = 0;
int moodval = 0;
long moodadder = 0;
//
int buttonnum1 = 0;   // When using the on-board keyboard as opposed to external computer keyboard
//
// THE FOLLOWING LISTS ARE USED IN THE TIMESPEAK AND DATESPEAK PROGRAMS.  ALL OF THE VALUES IN EACH OF THE LISTS ARE ACTUALLY AUDIO POINTERS
// FOR ISNTANCE, int months[2] is 27, and points to the word "March" in the audio library
int months[] = {25 ,26 ,27 ,28, 29, 30, 31, 32, 33, 34, 35, 36}; // January to December
int days1[] = {55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73}; // days 1 to 19 
int hourz[] = {55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66}; // 1-12AM/1-12PM // 54 = 0
int day = 0;    // WE ARE GOING TO STORE REAL-TIME-CLOCK (RTC) DATA INTO THE FOLLOWING FIVE INTEGERS.  WHEN WE READ THE RTC, WE'LL STORE THE RETURNED INFO HERE
int month = 0;
int year = 0;
int hour = 0;
int minute = 0;

// THE FOLLOWING SECTION IS GEARED TOWARDS DEDICATIING CHIP I/O PINS TO THE DIP SWITCHES.  WE'RE CURRENTLY ONLY USING 3 OF 8 AVAILABLE SWIITCHES
#define GenderDIP 28    // DIP SWITCH CHANNEL-C ON DIP SWITCH-B (GPIO PIN#28).  STATE DETERMINES WHETHER THE BUTLER REFERS TO YOU AS SIR OR MA'AM 
#define TIMEDIP 29      // DIP SWITCH CHANNEL-D ON DIP SWITCH-B (GPIO PIN#29).  USED FOR REAL TIME CLOCK MANUAL TIME SETTING.  REAL TIME CLOCK = RTC
#define FlashDIP 27     // DIP SWITCH CHANNEL-B ON DIP SWITCH-B (GPIO PIN#27).  FLASHES/ERASES YOUR SAVED MOOD DATA 
#define keyDIP 26
//
// THE FOLLOWING PIN DEFINITIONS ARE DEDICATED TO THE FOUR ON-BOARD AUDIO CHIPS.  BELOW THE PIN DEFINIATIONS ARE SOME AUDIO RELATIED INTEGER DECLARATIONS.
#define cs 32          // These are the chip-select pins for SPI. They control chips 1-4
#define cs2 15
#define cs3 14
#define cs4 39
#define csstop 34      // These are the chip-select pins for SPI. They control chips 1-4
#define cs2stop 33
#define cs3stop 12
#define cs4stop 16
int del=200;           // short 200ms delay
int value1 = 0x98;     // play command - This value never changes
int value2 = 0;        // voice address - when you place a hex value in this integer and call the "readout()" function, that specific word will play
int value3 = 0xA8;     // COUT ramp up - This value never changes
int value4 = 0xB8;     // COUT ramp down - This value never changes

// LET'S DEFINE THE RED, GREEN, AND YELLOW LED GPIO PINS (22, 23, AND 24)
#define RLED 22
#define GLED 23
#define YLED 24

// THE lcden PIN WILL BE DEDICATED TO GPIO 5, AND WILL CONTROL THE LCD BACKIGHT
#define lcden 5

// THE FOLLOWING ARE ALL LED-MATRIX DECLATATIONS.  THESE 16 LED CONTROL PINS ARE X AND Y AXIS CONTROL PINS.
#define x1 41
#define x2 47
#define x3 46
#define x4 30
#define x5 44
#define x6 38
#define x7 36
#define x8 35
#define y1 31
#define y2 37
#define y3 42
#define y4 40
#define y5 49
#define y6 43
#define y7 48
#define y8 45

// THE xarray AND yarray LISTS ALLOW FOR US TO CONTROL THE LED MATRIX EASILY.  THE LISTS CONSIST OF ALL LED ARRAY OUTPUTS LINES!
int xarray[] = {x1, x2 ,x3 ,x4, x5, x6, x7, x8}; 
int yarray[] = {y1, y2 ,y3 ,y4, y5, y6, y7, y8}; 

// DEDICATE THE BUZZER TO GPIO PIN#25
#define buzzer 25

// THE FOLLOWING ARE COMMONLY USED INTEGERS THAT ARE USED IN MANY DIFFERENT PROGRAMS AND FUNCTIONS.  
int hold = 0;
int hold2 = 0;
int hold3 = 0;
int counter = 0;

// THE FOLLOWING INTEGERS ARE KEYBOARD RELATED.  THEY ARE ONLY USED FOR KEYBOARD FUNCTIONS.
int letternum = 0; // keyboard
int state = 0;     // keyboard
int charnum = 0;   // keyboard

// code IS THE INTEGER THAT HOLD THE VALUE ASSOCIATED WITH A MATCHED WORD WHEN WE TYPE A WORD INTO THE COMMAND PROMPT
int code = 0;

// THE BELOW STRINGS AND INTEGERS ARE DEDICATED TO BLUETOOTH PROGRAMS
String command = ""; // Stores response from HC-06
int btint = 0;
int bstate = 0;
int btcode[] = {0 ,0 ,0 ,0};
int btcode2[] = {110 ,102 ,99 ,100}; // THIS IS A SECURITY CODE THAT WE'LL SEE LATER ON

// THE FOLLOWING INTEGERS ARE USED FOR OUR "Kitt" AUDIO APPLICATION, WHICH ACTS AS A VOLTAGE METER WHEN THE BUTLER SPEAKES.
// DON'T WORRY.  YOU'RE NOT EXPECTED TO KNOW WHAT ALL OF THESE DO RIGHT NOW. THEY ARE EXPLAINED LATER.
int adcsamples = 0;
int adcsamplea = 0;
int adcsampleb = 0;
int adcsamplec = 0;
int adcsampled = 0;
int adcsamplee = 0;
int adcsamplef = 0;
int adcsampleg = 0;
int adcsampleh = 0;
int holdadc = 0;

// THE FOLLOWING FOUR DIGIT CODE (9,8,2,3) IS YOUR SKELETON KEY CODE.  IF YOU WANT TO CHANGE THIS CODE, FEEL FREE.  THIS IS CODE GAINS YOU ENTRY INTO THE DIRECTORY
const int mastercode1 = 9; // CONSTANT INTs mastercide1-4 ARE YOUR SKELETON KEY.  CHANGE THESE NUMBERS AS YOU SEE FIT.  THIS IS NOT YOUR OWN PERSONAL SECURITY PASSWORD.  THIS IS A BACKUP CODE THAT WILL ALWAYS ALLOW YOU ACCESS TO THE BUTLER'S PROGRAMS.
const int mastercode2 = 8;
const int mastercode3 = 2;
const int mastercode4 = 3;

// WE'RE NOW ALL DONE DECLARING EVERYTHING.  I'LL STRESS IT AGAIN THAT YOU DON'T NEED TO UNDERSTAND ALL OF THIS, AND YOU CERTAINLY DON'T NEED TO MEMORIZE ANY OF IT.  
// EVERYTHING HAS ITS PURPOSE.  
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// NOW WE NEED TO SET UP OUR INPUTS AND OUTPUTS, START SPI AND I2C COMMUNCATIONS, ETC
void setup() {
Serial.begin(9600);                      // START THE SERIAL MONITOR WITH A 9600 BAUD RATE
Serial1.begin(9600);                     // START SERIAL1, WHICH IS DEDICATED TO THE HC-06 BLUETOOTH TRANCEIVER
pinMode(TIMEDIP,INPUT);                  // CHANNEL-A DIP SWITCH IS AN INPUT
pinMode(GenderDIP,INPUT);                // CHANNEL-B DIP SWITCH IS AN INPUT
pinMode(FlashDIP,INPUT);                 // CHANNEL-C DIP SWTICH (NOT CURRENTLY IN USE) 
pinMode(keyDIP,INPUT);                   // SELECTS BETWEEN ON BOARD KEYPAD AND EXTERNAL KEYBOARD
pinMode(A11,OUTPUT);                     // !!! A11 is used to control the relay in the "network()" function.  You can change this as you see fit.
delay(100);                              // 100ms SECOND DELAY
Serial.print("Initializing SD card..."); // PRINT THIS TO THE SERIAL MONITOR
if (!SD.begin(53)) {                     // "!Serial" means NOT serial.  GPIO4 is the chip select line.  THIS MEANS, IF NO COMMS IS FOUND WHEN WE TALK TO THE SD CARD, THEN PRINT THE FOLLOWING TO THE SERIAL MONITOR
Serial.println("SD Card FAULTY or NOT installed!"); // PRINT THIS TO THE LCD.  NO SD CARD FOUND.  THIS IS BAD...  REMEMBER THAT THE "ln" MEANS "GO TO THE NEXT LINE/ PRESS ENTER"
}
else
{
  Serial.println("initialization done.");// IF THE CARD IS THERE, AND ALL IS WELL, YOU'LL SEE THIS ON THE SERIAL MONITOR
}

// YOU CAN LEAVE THIS IN, OR CUT IT OUR OF THE PROGRAM.  IF YOU HAVE THE SERIAL MONTIOR OPEN ON POWER UP, YOU WILL SEE THE FOUR DIGIT SECURITY CODE 
// WRITTEN TO THE SCREEN.  WE CAN CHANGE THIS CODE AT ANY TIME IN THE COMMAND PROMPT, AS THERE IS A PGRAM THAT ALLOWS FOR YOU TO CHANGE IT.
Serial.print(EEPROM.read(0));   // READ EEPROM ADDRES 0, AND PRINT IT TO THE LCD
Serial.print(EEPROM.read(1));   // SEE ABOVE
Serial.print(EEPROM.read(2));
Serial.println(EEPROM.read(3));

// CHECK TO SEE IF THE REAL TIME CLOCK IS OPERATIONAL
if (! rtc.begin()) {                      // START/OPEN THE RTC.  SEE IF IT IS DETECTED.  IF IT ISN'T, PRINT THE FOLLOWING:
Serial.println("Couldn't find RTC");      // PRINT THIS TO THE SERIAL MONITOR
}

// CHANGE THE CURRENT DATE AND TIME IN THE RTC IF YOU WANT USING THE FOLLOWING CODE:
if(digitalRead(TIMEDIP) == HIGH)        // IF TIMEDIP IS SET TO ON/HIGH, SET THE TIME TO OCTOBER 9TH, 2020 - 10:44:00 AM
{
rtc.adjust(DateTime(2021, 03, 19, 14, 55, 0)); // 2020 = YEAR, 3 = MONTH (OCTOBER), 9 = DAY, 10 = HOUR, 44 = MINUTES, 0 = SECONDS (CHANGE THIS TO YOUR CURRENT DATE/TIME)
}

// TIME TO SET UP THE KEYBOARD INPUT
  keyboard.begin(DataPin, IRQpin);    // THIS IS A LIBRARY COMMAND. IT BASICALLY MEANS - START THE KEYBOARD INPUT, AND SET UP THE CLOCK AND DATA PINS
  pinMode(A2,OUTPUT);                 // SET ANALOG PIN TO TO WORK AS AN OUTPUT AS OPPOSED TO INPUT  A2 CONTROLS POWER TO THE EXTERNAL KEYBOARD
  delay(100);                         // WAIT 100ms
  digitalWrite(A2,HIGH);              // TURN ON KEYBOARD POWER
   
// DECLARE ALL 8X8 LED ARRAY PINS AS OUTPUTS
 pinMode(x1,OUTPUT);
 pinMode(x2,OUTPUT);
 pinMode(x3,OUTPUT);
 pinMode(x4,OUTPUT);
 pinMode(x5,OUTPUT);
 pinMode(x6,OUTPUT);
 pinMode(x7,OUTPUT);
 pinMode(x8,OUTPUT);
 pinMode(y1,OUTPUT);
 pinMode(y2,OUTPUT);
 pinMode(y3,OUTPUT);
 pinMode(y4,OUTPUT);
 pinMode(y5,OUTPUT);
 pinMode(y6,OUTPUT);
 pinMode(y7,OUTPUT);
 pinMode(y8,OUTPUT);

 matrixset();            // CALL THE matrixset() FUNCTION TO SET UP THE 8X8 LED MATRIX PINS 
 pinMode(RLED,OUTPUT);   // DECLARE THE RED, GREEN, AND YELLOW LED IO PINS AS OUTPUTS
 pinMode(GLED,OUTPUT);
 pinMode(YLED,OUTPUT);
 pinMode(lcden,OUTPUT);  // SET THE lcden PIN AS AN OUTPUT.  REMEMBER, THIS PIN TURNS THE LED BACKLIGHT ON AND OFF
 pinMode(buzzer,OUTPUT); // DECLARE THE buzzer PIN AS AN OUTPUT
 lcd.begin(16,02);       // THIS SETS UP THE LCD, WHICH CAN SHOW 16 CHARACTERS ACROSS TWO LINES
 lcd.clear();            // CLEAR THE LCD
 //
 SPI.begin();            // TURN ON SPI COMMUNICATIONS
 radio.begin();          // TURN THE NRF24L01+ RADIO ON
 network.begin(/*channel*/ 90, /*node address*/ this_node);   // SET UP THE RADIO 
 //
 pinMode(A7,OUTPUT);
 pinMode(A11,OUTPUT);
 //
 SPI.setClockDivider(SPI_CLOCK_DIV32);  // low frequency SPI
 pinMode(cs,OUTPUT);     // Chip select pins is an output
 pinMode(cs2,OUTPUT);    // Chip select pins is an output
 pinMode(cs3,OUTPUT);    // Chip select pins is an output
 pinMode(cs4,OUTPUT);    // Chip select pins is an output
 pinMode(csstop,INPUT);  // Chip select pins is an output
 pinMode(cs2stop,INPUT); // Chip select pins is an output
 pinMode(cs3stop,INPUT); // Chip select pins is an output
 pinMode(cs4stop,INPUT); // Chip select pins is an outpu
 digitalWrite(cs,HIGH);  // Set chip select to be HIGH (5v) by default.  The chip on the shield is selected when this line is brought low. 
 digitalWrite(cs2,HIGH); // Set chip select to be HIGH (5v) by default.  The chip on the shield is selected when this line is brought low.
 digitalWrite(cs3,HIGH); // Set chip select to be HIGH (5v) by default.  The chip on the shield is selected when this line is brought low.
 digitalWrite(cs4,HIGH); // Set chip select to be HIGH (5v) by default.  The chip on the shield is selected when this line is brought low.
 SPI.setBitOrder(MSBFIRST);   // OTP requires MSB first
 SPI.setDataMode(SPI_MODE0);  // Use MODE0, as all other modes to not work
 value2 = 0x00; // Start at voice group 0
 delay(1000);   // One second delay
 // Run Dignostics by pressing and holding any button on the on-board keypad.
 sample();      // Call the sample() function to sample and average the volume on the audio line.  Check this function out to see how it works!
 value2 = 0;    // THIS STARTS THE POINTER AT WORD 0
 digitalWrite(lcden,HIGH);      // Turn the LCD backlight on
 delay(100);
 if(analogRead(14) > 600){
  diagnostics();
}
else if(analogRead(14) > 25){
  audiolibrary();
}
else{}
 lcd.print("THE BUTLER V1.01"); // PRINT THIS TO THE TOP LINE OF THE LCD
 lcd.setCursor(0,1);            // SET THE LCD CURSOR TO THE SECOND LINE
 lcd.print("SYSTEMCHECK.EXE");  // PRINT THIS TO THE BOTTOM LINE OF THE LCD
 hold = 70;     // Audio pointer: "The Butler..."        
 readout();     // Call the readout() function to play the audio bite pointed to above
 delay(1500);   // Wait 1.5 seconds
 hold = 47;     // Audio pointer: "I am programmed to serve you"
 readout();     // Play the audio bite
 if(digitalRead(GenderDIP) == LOW){  // SIR OR MA'AM SELECTION BASED ON GenderDIP DIP SWITCH SETTINGS
 hold = 36;   // Audio pointer: "Ma'am"
 }
 else {
 hold = 58;   // Audio pointer: "Sir"
 }
 delay(100);  // Wait 100ms
 readout();   // Play audio bite!
 delay(1000); // Wait 1 second

 // The verifcode() function tells you to enter in a 4 digit combination into the ADC keypad.  If the entered code doesn't match either the
 // Master code, or your own sercurity code, then the code cannot progress past this point.  Only when you enter in a correct code will the code move on
 verifycode(); // Call the verifycode() function
 delay(1000);  // Wait one second
 mood();       // Call the mood() function.  This program asks you to enter in your mood.  If you don't want to, wait 4 seconds and the code will progress.
}



// Everything is now set up and ready to go!  Ready do create and run some programs?
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/* 
void loop() is our main program loop.  It will loop over and over.  As you can see, there are a few functions that are commented out.  I left those there
to show you that I had been experimenting with a few functions that I wanted to call right out of the gate.  I commented them out, but can easily
bring them back in.  This is an easy way for you to test out your programs before adding them to the program directory.  As you can see, the main program 
in void loop() looks really small.  That is because the getword() and statemachine() functions act to do just about everything.  getword() waits for a word to be 
entered into the keyboard, comparies it against all of the words in our word lists, and then returns a number in the "code" integer that corresponds to the matched
word.  If the entered word matches no words in our words lists, then code will return 0.  In any case, when getword() is done executing, and code returns a value, 
then the statemachines() function is called.  IT acts to call and execute the program corresponding to the code value... If code returned a 0, then no program
is executed. When a program is done executing, void loop() starts over, and getword() is called again.  It is one big loop!
*/
void loop() {
  getword();        // The getword() function is located at the bottom of this code.  All keyboard related code is located at the bottom of this program.  
  statemachines();  // This function executes programs based on the returned "code" value determined in the getword() function.  
} // THIS IS THE END OF void loop()

void audiolibrary(){
  hold = 0;
for(int i = 0 ; i < 44 ; i++){
  hold = i;
  readout3();
}
  hold = 0;
  for(int i = 0 ; i < 95 ; i++){
  hold = i;
  readout();
}
hold = 0;
for(int i = 0 ; i < 254 ; i++){
  hold = i;
  readout2();
}
hold = 0;
for(int i = 0 ; i < 254 ; i++){
  hold = i;
  readout4();
}
}


void statemachines(){ // Execute code based on results of entered codeword
if(code == 1){        // This function is simple as all heck.  You can replace how this function works by using a switch, if you'd like.
  state1();           // If the returned code after getword() is executed is 1, then you entered 'y' (the word from the cmd1 list).  IF so, call state1()
}else if(code == 2){  // state1() just blinks an LED.  The idea is that you can call any program or function that you'd like based on the word that you enter.
  state1();           // If getword() returned a value of 2 in 'code', then you'll again call state1(), which blinks an LED.  This word is "n" for no in the cmd2 list.
}else if(code == 3){  // If getword() returned a value of 3 in clude (Word = 'dir), then call the dir() function below.  "dir" = directory.
  dir();              
}else if(code == 4){  // I think you get the point.  Remember void compareword()?  This funciton ls called during the getword() function, and it...
  newmatrix();        // compares the word that you just entered against all of the other word lists at the top of this code.  When a match is made...
}else if(code == 5){  // the function returns a specific value in the 'code' integer.  Now we're using those values to call specific programs associated...
  rst();              // with those words.  Check out the directory function 'dir()' below. 
}else if(code == 6){
  alarm();
}else if(code == 7){  // IF you don't have a code for a specific word, just use state1() as a placeholder.  It turns an led on and off quickly.  That's all.
  state1();
}else if(code == 8){
  leds();
}else if(code == 9){  // Instead of calling a big function, you can execute the code right here.  As you can see, buzz() is called three times...
  buzz();
  delay(200);
  buzz();
  delay(200);
  buzz();
}else if(code == 10){
  bluetoothtest();
}else if(code == 11){
  scream();
}else if(code == 12){
  redalert();
}else if(code == 13){
  state1();
}else if(code == 14){
  soundmatrix();
}else if(code == 15){
rtccheck();  
}else if(code == 16){
  speakdate();
}else if(code == 17){
  timespeak();
}else if(code == 18){
  lighttest();
}else if(code == 19){
  mictest();
}else if(code == 20){
  rfnetwork();
}else if(code == 21){
  programcode();
}else if(code == 22){
  imperial();
}else if(code == 23){
  flashmem();
}else if(code == 24){
  getmood();
}else if(code == 25){   // Build this up as you add new words.  All you need to do is somc copy and paste. I'll show you an example just below.
  state1();
//}else if(code == 26){   // Add these two lines of code in when you want to add in a new word.  This is one of four things that you need to do when adding a new word.
//  Yournewprogram();
}else{}
} // THIS IS THE END OF THIS FUNCTION

// List of things to do when adding a new word to the directory:
// NOTE!!! - IF YOU DON'T WANT TO FOLLOW THIS LIST, SEE THE FUNDAMENTALS#3 VIDEO FOR A PLAY-BY-PLAY
// 1) First, create a new word.  Go to the top of this code, and find the word lists.  As you can see, the cmd26 list has been commented out.  Let's make a new word.
// Open the serial monitor, and enter in a new word of your choice when the LCD says "Enter command".  As soon as you press enter, you'll see a line of 16 characters.
// Say your word is "Remember", you're going to see 8x ASCII characters, as "Remember" is 8 characters, followed by 8 0s, as the word can be a maximum of 8 characters.
// Highlight the 8x ACCII values, and press CTRL-C to copy the highlighted text.  Now, go back to the code where the cmd26 list is.  
// Highlight the first 8x zeros in the list, and then press CTRL-V to paste the 8x ASCII values in.  You'll notice that there are no commas separating the pasted
// ASCII values.  Add them in one by one.  You need commas separating each value, or else you'll get compiling failures.
// That is the hard part, and really, it wasn't that hard, was it?
// 2) At the bottom of the statemachines() function (Literally just above), I added in a commented 2-line code sample at the end that looks like this:
// }else if(code == 26){
// yourprogram();
//
// Add those back in to the code by removing the comments (//).  You can change out yourprogram(); for leds(); if you want.  You don't need to create yor own...
// program just yet.  leds() just tests the on-board LEDs.  IF you have a program that you want to call, add the name of the funciton in place of Yournewprogram();
// Every time you add in a new word, add a new set of two lines just like I showed you above.  Remember to increment the code number.  The next will be 27.
// 3) Update the directory seen below 'dir()'.  Add the name of the word for Command#26, which is currently commented out, and a description of your program.
// 4) Go to the very last lines of this code to the end of the compareword() function.  You need to add in a couple of lines of code, and the instructions are 
// outlined there.  
// That's all. You might think that this is a lot.  You can do it in less than two minutes.  It is simply.  You do it once, you've done it a hundred time.
// Again, if you feel uptight about this, just follow me in the fundamentals#3 video.


void iotest(){
  for(int i = 0; i < 1000 ; i++){
    digitalWrite(A7,HIGH);
    digitalWrite(A11,HIGH);
    delay(1);
    digitalWrite(A7,LOW);
    digitalWrite(A11,LOW);
    delay(1);
  }
}



void diagnostics(){
  lcd.clear();
  lcd.print("TESTTESTTESTTEST");
  lcd.setCursor(0,1);
  lcd.print("TESTTNGTHELCD!!!");
  delay(1000);
  lcd.clear();
  lcd.print("OPN SER MONITOR");
  hold = 1;   // Play the first autio bite from each chip to test each chip
  readout();
  delay(100);
  readout2();
  delay(100);
  readout3();
  delay(100);
  readout4();
  lcd.clear();
  lcd.print("Testing IO");
  iotest();   // Test the externakl IO.  You won't see or hear anything, but you can probe the output lines to view activity
  lcd.clear();
  leds();     // Test the leds
  lcd.print("Type EXIT2EXIT");
  soundmatrix();
  newmatrix();
  rtccheck();
  SDcardtest();
}

void dir(){                     // This is the directory function.  It lays out the directory of words and programs used by the system when you type 'dir'
  lcd.clear();                  // Clear the LCD
  lcd.print("Open Serial");     // Print this to the LCD
  lcd.setCursor(0,1);           // SEt the LCD cursor to the second line
  lcd.print("Monitor 4 CMDLST");// Print this to the LCD  
  hold = 81;                    // Audio pointer:  "Open the serial montior'
  readout();                    // Play the audio bite
  Serial.println("");           // Start a new line on the serial monitor
  // Add your new program information and edit your directory when you have new programs to add to it.  Below is an example.  See Command#26...
  Serial.println("Program Directory:"); 
  Serial.println("Command#1 = 'y' - Description: Short for Yes.  Answers a question");
  Serial.println("Command#2 = 'n' - Description: Short for No.   Answers a question");
  Serial.println("Command#3 = 'dir' - Description: Directory - Pulls up command list on the serial monitor");
  Serial.println("Command#4 = 'matrix' - Resets Butler when in statemachines routine");
  Serial.println("Command#5 =  'reset' - Description: Resets butler when entered in 'statemachines' function");
  Serial.println("Command#6 =  'alarm' - Description: Plays the nuclear alarm sound bite");
  Serial.println("Command#7 =  'sleep' - Description: Enters low power sleep mode");
  Serial.println("Command#8 =  'flashmem' - Description: Erases Memory relating to logged mood");
  Serial.println("Command#9 =  'buzzer' - Description: Beeps the buzzer three times");
  Serial.println("Command#10 =  'bluetooth' - Description: Executes the Bluetooth subroutine");
  Serial.println("Command#11 =  'scream' - Description: Plays the Wilhelm scream sound bite");
  Serial.println("Command#12 =  'red alert' - Description: Plays the ST-TNG 'RED ALERT' sound bite");
  Serial.println("Command#13 =  'exit' - Description: Acts to exit from some functions/sub-routines");
  Serial.println("Command#14 =  'sound' - Description: Displays room sound level (volume) on the LCD matrix");
  Serial.println("Command#15 =  'date' - Description: Reads the RTC and displays the date on the serial monitor");
  Serial.println("Command#16 =  'datespeak' - Description: Audio command - Butler tells you the date");
  Serial.println("Command#17 =  'timespeak' - Description: Audio command - Butler tells you the time");
  Serial.println("Command#18 =  'light' - Description: Samples the light sensor and displays the digital value on the LCD & serial monitor");
  Serial.println("Command#19 =  'noises' - Description: Waits for a loud noise.  Tests microphone");
  Serial.println("Command#20 =  'network' - Description: Waits for a wireless communication from NRF24L01+ transmitter");
  Serial.println("Command#21 =  'program' - Description: Allow you to chance your sexurity access code in memory");
  Serial.println("Command#22 =  'imperial' - Description: Plays the imperial march Star Wars sound bite");
  Serial.println("Command#23 =  'flashmood' - Description: Calls the 'flashmem' function, which deletes memory settings relating to your mood");
  Serial.println("Command#24 =  'mymood' - Description: Compiles your logged mood data, and tells you how you've been doing mentally");
  Serial.println("Command#25 =  'Not yet added' - Description: Not yet used");
  //Serial.println("Command#26 = 'Your new word' - Description: Calls Yournewprogram")
}  // THIS IS THE END OF THIS FUNCTION

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Not we're getting more into the programs.  Feel free to add yours anywhere.  If you want to get rid of any of mine, you can comment them out, or you can
// simply delete them.  Remember to keep your directory updated.  

void rfnetwork(){  // This function works with the NRF24L01+ tranceiver.  You need another one to communicate with.  See "Transmitter Code" in Butler project page.
// This program waits for one transmission.  IF the transmission received is a value of 15, then the on-board relay turns on for 5 seconds before turning off.
// If the transmission doesn't equal 15, then this function ends.
  state = 0;                                    // Start by setting 'state' to 0.
  Serial.println("Awaiting Wireless Data...");  // Pring this to the serial monitor
  lcd.clear();                                  // Clear the LCD
  lcd.print("WAITING FOR DATA");                // Print this to the LCD
  delay(1000);
  while(state == 0){                            // Execute the following code until state changes from 0 to 1
    {     
    if (keyboard.available()){      // EXIT IF "EXIT" IS ENTERED   // Has someone pressed a button on the keyboard?  IF so, interrupt the program.
    getword();                       // And grab a word =)
    if(code == 13){                  // If the returned wood code was 13 (points to the word 'exit'), then exit this function by setting state to 1. 
    state = 1;                     // Set state to 1 
    }
    else{                             // Otherwise...
      lcd.clear();                    // CLear the LCD
      lcd.print("WAITING FOR DATA");  // Print this to the LCD
    }
    }
    if (analogRead(14) > 25){      // EXIT if any button on the keypad has been pressed
    buttonwait();                  // Wait for the user to remove their finger from the keypad button
    state = 1;                     // Set state to 1 and end this function
    }
    network.update();                   // Check the NRF24L01_ for updates
    while ( network.available() ) {     // Is there anything ready for us?  If not, wait for a communication from one of the transmitters
    RF24NetworkHeader header;           // If so, grab it and print it out
    payload_t payload;                
    network.read(header,&payload,sizeof(payload));  // Read the received data
    Serial.print("Received Address#");              // Print this message
    Serial.print(payload.addressz);                 // Print the received address (THIS WILL CHANGE AS YOU MESS WITH THE DIP SWITCH SETTINGS ON THE TRANSMITTER SHIELD)
    Serial.print("Received Instruction#");          // Print this message
    Serial.println(payload.instructionz);           // Print the received instruction
    delay(100);                         // Wait 100ms
    if(payload.addressz == 15){         // IF the received instruction was 15, then do the following:
      hold = 73;                        // Audio pointer:  'relay'
      readout();                        // Play audio bite
      delay(5);                         // 5ms delay
      hold = 229;                       // Audio pointer 'on'
      readout2();                       // Play the audio bite
      delay(500);                       // Wait half a second
      lcd.clear();                      // Clear the LCD
      lcd.print("RELAY ON");            // Print this t the LCD
      digitalWrite(A11,HIGH);           // Turn the relay on
      delay(5000);                      // For 5 seconds
      digitalWrite(A11,LOW);            // Turn the relay off
      lcd.clear();                      // Clear the LCD
      lcd.print("RELAY OFF");           // Print this to the LCD
      lcd.setCursor(0,1);               // Set the LCD cursor to the second line
      //lcd.print("EXITING...");        // Print this to the LCD
      delay(2000);                      // Wait 2 seconds
      //state = 1;                      // Set state to 1 to end this funciton (By quitting the while loop)  Commented out for the time being. 
      lcd.clear();                    // CLear the LCD
      lcd.print("WAITING FOR DATA");  // Print this to the LCD
    }
    else{                               // If the instruction wasn't 15, then do the following instead
      lcd.clear();                      // Clear the LCD
      lcd.print("INVALID DATA");        // Print this to the LCD
      lcd.setCursor(0,1);               // Set the LCD cursor to the second line of the LCD
      lcd.print("TRY AGAIN");           // Print this to the second line of the LCD
      delay(1000);                      // Wait 2 seconds
      lcd.clear();                    // CLear the LCD
      lcd.print("WAITING FOR DATA");  // Print this to the LCD
    }
  }
}
}
}  // THIS IS THE END OF THIS FUNCTION.  Play with it to make it yours.  



void timespeak(){                // THIS FUNCTION TAKES A READING FROM THE RTC, AND THE AUDIO CHIPS VERBALLY OUTPUT THE TIME
  DateTime now = rtc.now();      // ASK THE RTC FOR THE CURRENT DATE AND TIME
hour =(now.hour());              // PRINT THE YEAR IN DECIMAL (DEC)
minute = (now.minute());         // PRINT THE MONTH
minute = minute -1;              // DECREMENT 'minute' BY 1, AS 0 COUNTS AS THE FIRST NUMBER IN THE AUDIO LIST
hour = hour - 1;                 // DECREMENT 'hour' BY 1 FOR THE SAME REASON AS ABOVE
Serial.println(hour);            // PRINT THE NEW VALUES IN hour AND minute TO THE SERIAL MONITOR
Serial.println(minute);
hold = 242;                      // AUDIO POINTER: 'THE'
readout2();                      // PLAY AUDIO BITE
hold = 51;                       // AUDIO POINTER: 'TIME'
readout2();                      // PLAY AUDIO BITE
hold = 205;                      // AUDIO POINTER 'IS'
readout2();                      // PLAY AUDIO BITE
hold = hourz[hour];              // POINT TO THE LIST VARIABLE IN THE hourz LIST (POINTED TO BY hours) AND STORE THE RETURED VALUE IN hold
readout2();                      // PLAY AUDIO BITE   
///////////
if(minute == -1){                // IF minute IS LESS THAN 0 (ANY NEGATIVE NUMBER), DO NOTHING
}
else if(minute < 9)              // OTHERWISE, IF minute IS LESS THAN 9, DO THE FOLLOWING
{
  hold = 54;                     // AUDIO POINTER: 'ZERO'
  readout2();                    // PLAY AUDIO BITE
  hold = days1[minute];          // POINT TO THE LIST VARIABLE IN THE minute LIST (POINTED TO BY minute) AND STORE THE RETURNED VALUE INTO hold
  readout2();                    // PLAY THE AUDIO BITE
}
else if(minute < 19){            // OTHERWISE, IF minute IS LESS THAN 19, THEN READY TEEN SOUND BITES
  hold = days1[minute];          // POINT TO THE LIST VARIABLE IN THE minute LIST (POINTED TO BY minute) AND STORE THE RETURNED VALUE INTO hold
  readout2();                    // PLAY THE SOUND BITE
} 
else if(minute < 29){            // OTHWERSIE, IF minute IS LESS THAN 29...
  hold = 74;                     // AUDIO POINTER: 'TWENTY'
  readout2();                    // PLAY SOUND BITE
  minute = minute - 20;          // REMOVE 20 FROM minute
  if(minute == -1){}             // IF minute IS LESS THAN 0 (ANY NEGATIVE NUMBER), THEN DO NOTHING
  else                           // OTHERWISE, DO THE FOLLOWING:   
  {
  hold = days1[minute];          // POINT TO THE AUDIO POINTER FOR 0 THROUGH 9 (MINUTES)
  readout2();                    // PLAY THE SOUND BITE
  }
}
else if(minute < 39){            // THE CODE GETS REPETATIVE AT THIS POINT.  WE NEED TO DECODE FOR minutes LESS THAN 40, THEN 50, THEN 60...
  hold = 75;
  readout2();
  minute = minute - 30;
 if(minute == -1){}
  else
  {
  hold = days1[minute];
  readout2();
  }
}
else if(minute < 49){
  hold = 76;
  readout2();
  minute = minute - 40;
  if(minute == -1){}
  else
  {
  hold = days1[minute];
  readout2();
  }
}
else if(minute < 59){
  hold = 77;
  readout2();
  minute = minute - 50;
  if(minute == -1){}
  else
  {
  hold = days1[minute];
  readout2();
  }
}
else
{
}
if(hour < 11){                  // NOW, LET'S DECODE WHETHER TO HAVE THE PROGRAM SAY 'A.M., OR 'P.M.'.  IF hour IS LESS THAN 12, PLAY A.M.
  hold = 44;                    // AUDIP POINTER  
  readout2();                   // PLAY A.M.
}
else                            // OTHERWISE, PLAY P.M.
{
hold = 45;                      // AUDIO POINTER 'P.M.'
readout2();                     // PLAY AUDIO BITE
}
} // THIS IS THE END OF THIS FUNCTION

void speakdate(){                 // THIS FUNCTION SAMPLES THE RTC AND THEN SPEAKS THE DATE.  THERE IS A BUG IN THIS ONE THAT I NEED TO FIX.
DateTime now = rtc.now();         // ASK THE RTC FOR THE CURRENT DATE AND TIME
year =(now.year(), DEC);          // PRINT THE YEAR IN DECIMAL (DEC)
month = (now.month());        // PRINT THE MONTH
day = (now.day());                // PRINT THE CURRENT DAY
day = day - 1;                    // DECREMENT day BY 1, AS 0 IN THE AUDIO LIST IS THE STARTING POINT.
Serial.println(day);              // PRINT THE CURRENT DAY TO THE SERIAL MONITOR
hold = 242;                       // AUDIO POINTERS FOR "THE", "DATE", "IS", EACH FOLLOWED BY A READOUT COMMAND, WHICH PLAYS EACH AUDIO BITE. 
readout2();
hold = 46;
readout2();
hold = 205;
readout2();
if(day < 19){                     // IF day IS LESS THAN 19, THEN PLAY THE RELATIVE audio BITE BETWEEN 1 AND 19 
 hold = days1[day];               // PLACE THE VALUE FROM THE days1 LIST INTO HOLD, POINTED TO BY THE VALUE IN THE day INTEGER
 readout2();                      // PLAY THE AUDIO BITE
}
else if(day < 29){                // IF DAY IS LESS THAN 29, PLAY THE AUDIO BITE "TWENTY", AND THEN THE AUDIO BITE (1 - 9)
hold = 74;                        // AUDIO POINTER: 'TWENTY'
readout2();                       // PLAY THE AUDIO BITE
day = day - 20;                   // REMOVE 20 FROM day SO THAT WHAT IS LEFT IS 9 OR LESS
if(day == 0){}                    // IF ZERO, PLAY NOTHING, AS THE DATE IS THE 20TH
else                              // OTHERWISE...
{
hold = days1[day];                // POINT TO THE VARIABLE IN THE days1 LIST POINTED TO BY THE VALUE IN day
readout2();                       // PLAY THE AUDIO BITE
}
}
else                              // IF day WAS HIGHER THAN 29...
{
  hold = 75;                      // POINT TO THE  'THIRTY' SOUND BITE
  readout2();                     // PLAY IT
  if(day > 29){                   // IF dat IS LARGER THAN 29, PLAY "ONE"                  
    hold = 55;                    // AUDIO POINTER FOR 'ONE'
    readout2();                   // PLAY THE SOUND BITE
  }
}
Serial.print(months[month]);
hold = months[month];                 // I BELIEVE THAT THERE'S A BIG HERE.  COME BACK TO FIX IT WHEN YOU HAVE TIME.
hold = hold - 1; 
readout2();
} // THIS IS THE END OF THIS FUNCTION


void bluetoothtest(){               // SAVES FOUR INCOMING VALUES FROM THE BLUETOOTH MODULE
  lcd.clear();                      // CLEAR THE LCD  
  lcd.print("BT Command: ");        // PRINT "COMMAND" TO THE LCD
  while (Serial1.available() >0 ) { // THIS WILL CLEAR THE SERIAL BUFFER.  IF ANY DATA IS SITTING HERE WAITING, WE'RE DOING TO DELETE IT TO START FRESH.  NOTE THE "1" AFTER SERIAL.  THIS IS BLUETOOTH SERIAL, NOT SERIAL MONITOR SERIAL.
  Serial1.read();
}
  for(int i = 0; i < 4 ; i++){    // GET FOUR BUTTON INPUTS FROM YOUR PHONE
  btint = 0;                      // THIS INTEGER HOLDS OUR INCOMING BUTTON DATA.  SET TO 0 FOR NOW.
  bstate = 0;                     // THIS INTEGER CONTROLS THE BELOW WHILE LOOP
  while(bstate == 0){             // LOOP THE FOLLOWING CODE WHILE bstate REMAINS AT 0.
    {
   if (keyboard.available()) {    // EXIT IF "EXIT" IS ENTERED
      getword();                  // ENTER A WORD INTO YOUR KEYPAD IF YOU WANT
      if(code == 5){              // IF THE RETURNED code VALU EIS 5, THEN 'exit" WAS ENTERED, AND THIS WILL RELEASE YOU FROM THIS PROGRAM
        hold = 50;                // AUDIO POINTER - 'RESETTING'
        readout();                // PLAY AUDO BITE
        delay(1000);              // WAIT 1 SECOND
        rst();                    // THE rst() COMMAND RESETS THE Butler
      }
      lcd.clear();                // CLEAR THE LCD  
      lcd.print("Command: ");     // PRINT "COMMAND" TO THE LCD
      }  
    if (Serial1.available()) {    // WAIT FOR INCOMING BLUETOOTH DATA
    while(Serial1.available()) {  // WAIT FOR INCMING DATA TO PROCESS
    delay(3);                     // WAIT 3ms
    btint = Serial1.read();       // STORE THE DATA THAT WE JUST RECEIVED ON btint (BLUETOOTH INTEGER)
    if(btint == 10){              // 10 IS ESSENTIALLY A CHARACTER THAT WE DON'T CARE ABOUT AND DON'T WANT TO SEE, BUT THIS WILL SHOW UP EACH TIME A BUTTON IS PRESSED.  IF btint EQUALS 10, IGNORE IT. DO NOTHING WITH IT.
    }                    
    else if(btint == 107){        // 107 IS THE INDICATOR THAT THE PERSON HOLDING DOWN THE BUTTON IN ROBOREMO HAS LET GO.  IF btint EQUALS 107, IT MEANS THAT THEY HAVE LET GO OF THE BUTTON.  IF 107, SET bstate TO 1, WHICH ENDS THE WHILE LOOP.
     bstate = 1;
    }
    else{                         // OTHERWISE, PRINT btint TO THE lcd AND SAVE IT.  THIS HAPPENS IF btint IS ANY NUMBER OTHER THAN 10, AND 107.  WHEN A CHARACTER IS TRANSMITTED VIA ROBOTREMO, IT TRANSMITS THE VALUE, THEN A 10, THEN 107 AND ANOTHER 10
                                  // WHEN THE USER LETS GO OF THE BUTTON
    lcd.print("X");               // PRINT btint TO THE LCD
    delay(50);                    // WAIT 250ms
    btcode[i] = btint;            // SAVE btint INTO THE btcode ARRAY.  [i} IS THE CURRENT VALUE OF THE FOR LOOP.  IF THE FIRST LOOP THROUGH THE CODE, THEN i = 1.  IF IT IS THE THIRD, THEN i = 3, ETC.
    }
    }
  }
  }
  }
  }
  delay(2000);
  hold = 0;                       // WE'RE GOING TO USE THIS INTEGER TO HOLD COMPARISON DATA
  lcd.clear();                    // WHEN THE for LOOP COMPLETES, WE WILL HAVE HAD FOUR BUTTONS PRESSED/INPUTTED.  IT IS NOW TIME TO PRINT THEM OUT  ON THE LCD.
  for(int i = 0 ; i < 4 ; i++){   // RUN THE FOLLOWING CODE 4 TIMES
  //lcd.print(btcode[i]);         // LIKE ABOVE, [i] IS NOT ONLY USED TO CONTROL HOW MANY TIMES THE CODE IN THE for LOOP EXECUTES, IT ALSO ACTS AS A POINTER FOR THE btcode ARRAY READS. i INCREMENTS EVERY TIME THE FOR LOOPS EXECUTES
  if(btcode[i] == btcode2[i]){    // COMPARE THE FOUR INCOMING CHARACTERS AGAINST THE FOUR CHARACTERS IN THE btcode LIST AT THE TOP OF THIS CODE. 
    hold = hold + 1;              // IF ANY MATCH, ADD 1 TO hold
  }
  }                               // ENDS THIS for LOOP
  if(hold == 4){                  // IF ALL FOUR CODES MATCHED btcode2, THEN DO THE FOLLOWING
    lcd.clear();                  // CLEAR THE LCD
    lcd.print("Code Match!");     // PRINT TO LCD
    lcd.setCursor(0,1);           // SET CURSOR ON LCD TO BOTTOM LEFT
    lcd.print("Access Granted!"); // PRINT TO LCD STARTING AT BOTTOM LEFT
    delay(2000);                  // WAIT 2 SECONDS
  }
  else                            // OTHERWISE, IF ONE OR MORE CODES WERE A MIS-MATCH, DO THE FOLLOWING
  {
    lcd.clear();                  // CLEAR THE LCD
    lcd.print("Incorrect Code");  // PRINT TO THE LCD
    lcd.setCursor(0,1);           // SET LCD CURSOR TO BOTTON LEFT
    lcd.print("Access Denied!");  // PRINT TO THE LCD STARTING AT THE LOWER LEFT
    delay(2000);                  // WAIT 2 SECONDS
}                                 // END OF THIS FUNCTION    
} // THIS IS THE END OF THIS FUNCTION

void redalert(){  // THIS FUNCTION PLAYS THE STAR TREK 'RED ALERT' SOUND BITE
  hold = 72;      // AUDIO POINTER - 'RED ALERT SITEN'
  readout();      // PLAY AUDIO BITE.  THIS ENDS THE FUNCTION
} // THIS IS THE END OF THIS FUNCTION

void scream(){    // THIS IS ANOTHER SILLY PROGRAM.  IT PLAYS A SCREAMING SOUND EFFECT WHEN CALLED
  hold = 71;      // AUDIO POINTER - 'SCREAM SOUND BITE'
  readout();      // PLAY THE AUDIO BITE.  THIS IS THE END OF THIS FUNCTION
} // THIS IS THE END OF THIS FUNCTION

void rst(){       // THIS IS A FUN ONE!  THE A1 ANALOG PIN IS CONNECTED TO THE RESET LINE.  CHANGE THIS ANALOG PIN TO A DIGITAL OUTPUT, AND YOU CAUSE A RESET
  hold = 50;      // AUDIO POINTER - 'RESETTING'
  readout();      // PLAY THE AUDIO BITE
  delay(1000);    // WAIT ONE SECOND
  pinMode(A1,OUTPUT); // SET A1 AS AN OUTPUT, AND THE ENTIRE BUTLER RESETS
} // THIS IS THE END OF THIS FUNCTION

void flashmem(){              // THIS FUNCTION FLASHES YOUR MOOD LOGS.  EXECUTING THIS FUNCTION WILL ERASE ALL MOOD LOGS FROM EEPROM MEMORY
  lcd.clear();                // CLEAR THE LCD
  lcd.print("FLASH MEMORY?"); // PRINT THIS TO THE LCD
  lcd.setCursor(0,1);         // SET THE LCD CURSOR TO THE SECOND LINE OF THE LCD
  hold = 85;                  // AUDIO POINTER - 'FLASH MEMORY?' 
  readout();                  // PLAY THE AUDIO BITE
  state = 0;                  // SET STATE TO 0
  while(state == 0){          // EXECUTE THE FOLLOWING WHILE LOOP OVER AND OVER UNTIL STATE CHANGES TO ANY NUMBER THER THAN 0.
  {
    lcd.print("Y/N?");        // PRINT THIS TO THE LCD
    delay(2000);              // WAIT TWO SECONDS
    getword();                // ENTER A WORD INTO THE KEYPAD
    if(code == 1){            // IF CODE EQUALS 1, THEN YOU'VE ENTERED 'y', WHICH MEANS YES.  DO THE FOLLOWING:
      hold = 18;              // AUDIO POINTER - 'EXECUTNG'
      readout();              // PLAY THE AUDIO BITE
      lcd.clear();            // CLEAR THE LCD
      lcd.print("DELETING MOOD");   // PRINT THIS TO THE LCD
      lcd.setCursor(0,1);           // SET THE LCD CURSOR TO THE SECOND LINE OF THE LCD
      lcd.print("MEMORY SETTINGS"); // PRINT THIS TO THE LCD
      flashmood();                  // CALL THE flashmood) FUNCTION, WHICH DOES THE REAL WORK HERE.  SEE IT BELOW.
      state = 1;                    // CHANGE STATE TO 1 TO END THIS WHILE LOOP AND FUNCTION
    }
    else if(code == 2){             // IF YOU ENTERED "n" FOR NO, THEN DO THE FOLLOWING INSTEAD:
      lcd.clear();                  // CLEAR THE LCD
      lcd.print("EXITING...");      // PRINT THIS TO THE LCD
      hold = 19;                    // AUDIO POINTER - 'EXITING'
      readout();                    // PLAY THE AUDIO BITE
      delay(2000);                  // WAIT 2 SECONDS
      state = 1;                    // CHANGE STATE TO 1, ENDING THIS WHILE LOOP AND FUNCTION
    }
    else                            // IF YOU ENTERED IN ANYTHING OTEHR THAN 'y' OR 'n', THEN ENTER IN ANOTHER WORD. START OVER...
    {}
}
}
} //THIS IS THE END OF THIS FUNCTION                                
  

void alarm(){               // THIS FUNTION CALLS THE NUCLEAR ALARM SOUND BITE
  lcd.clear();              // CLEAR THE LCD
  lcd.print("Executing:");  // PRINT THIS TO THE LCD
  lcd.setCursor(0,1);       // SET THE LCD CURSOR TO THE SECOND LINE
  lcd.print("ALARM.EXE");   // PRINT THIS TO THE LCD
  hold = 61;                // AUDIO POINTER - 'ALARM SOUND EFFECT'
  readout();                // PLAY THE AUDIO BITE
} // THIS IS THE END OF THIS FUNCTION

void imperial(){
// PLAY THIS ONE WHEN YOUR BOSS IS WALKING TOWARDS YOU FROM DOWN THE HALL! 
  lcd.clear();              // CLEAR THE LCD
  lcd.print("Executing:");  // PRINT THIS TO THE LCD
  lcd.setCursor(0,1);       // SET THE LCD CURSOR TO THE SECOND LINE OF THE LCD
  lcd.print("IMPERIAL.EXE");// PLAY THE IMPERIAL MARCH FROM STAR WARS
  hold = 64;                // AUDIO POINTER - IMPERIAL MARCH
  readout();                // PLAY THE SOUND BITE
} // THIS IS THE END OF THIS FUNCTION

void state1(){              // THIS IS A THROW-AWAY FUNCTION
digitalWrite(RLED,HIGH);    // TURN THR RED LED ON
delay(100);                 // 100ms DELAY
digitalWrite(RLED,LOW);     // TURN THE LED OFF
} // THIS IS THE END OF THIS FUNCTION

void clapsleep()            // THIS FUNCTION IS EMPTY.  IT HASN'T BEEN DESIGNED YET  
{ 
}  // THIS IS THE END OF THIS FUNCTION

void lighttest(){             // THIS FUNCTION TESTS THE LIGHT LEVEL IN TEH ROOM AND PRINTS IT TO THE SERIAL MONITOR AND LCD
hold = analogRead(0);         // SAMPLE THE ANALOG LIGHT SENSOR, AND PLACE THE VALUE IN hold
Serial.print("Light Level: ");// PRINT THIS TO THE SERIAL MONITOR
Serial.println(hold);         // PRINT THE VALUE IN hold AND THEN GO TO THE NEXT LINE
lcd.clear();                  // CLEAR THE LCD
lcd.print("Light LVL: ");     // PRINT THIS TO THE LCD
lcd.setCursor(0,1);           // SET THE LCD CURSOR TO THE SECOND LINE OF THE LCD
lcd.print(hold);              // PRINT THE VALUE IN hold TO THE LCD
delay(3000);                  // WAIT THREE SECONDS
lcd.clear();                  // CLEAR THE LCD
} // THIS IS THE END OF THIS FUNCTION


void newmatrix(){               // THIS IS A LIGHTMETER FUNCTION. IT SAMPLES THE LIGHT IN THE ROOM, AND CHANGES THE 8X8 LED MATRIX STATE BASED ON THE RESULT
  state = 0;                    // SET STATE TO 0
  lcd.clear();                  // CLEAR THE LCD  
  lcd.print("Light Meter.EXE"); // PRINT THIS TO THE LCD
  lcd.setCursor(0,1);           // SET THE LCD CURSOR TO THE SECOND LINE
  lcd.print("ENT: exit ToEXIT");// PRINT THIS TO THE LCD.  ONLY 'exit' WILL ALLOW FOR YOU TO LEAVE THIS FUNCTION  
  while(state != 99){           // EXECUTE THE FOLLOWING WHILE LOOP OVER AND OVER AS LONG AS state DOES NOT EQUAL 99. WE START WITH STATE BEING 0.
    {
for(int i = 0; i < 8; i++){     // EXECUTE THE FOLLOWING LOOP 8 TIMES
  digitalWrite(xarray[i],LOW);  // SET THE xarray LED CONTROL PIN POINTED TO BY i, AND SET IT LOW.  REMEMBER, i INCREMENTS EACH TIME THIS FOR LOOP EXECUTES.
    analogin();                 // CALL THE anaglogin() FUNCTION (SEE BELOW).  IT SAMPLES THE LIGHT SENSOR AND DECODES IT INTO A LIGHT LEVEL FROM 0-7 (8 STATES IN ALL)
    digitalWrite(yarray[hold],HIGH); // SET THE RELATIVE yarray LED CONTROL PIN HIGH.  THE VALUE IN hold RETURNED FROM analogin() POINTS TO THE RLATIVE CONTROL PIN.
    delay(50);                  // WAIT 50ms
    matrixset();                // CALL THE matrixset() FUNCTION BELOW TO RE-SETUP THE LED MATRIX CONTROL PINS. 
     if (keyboard.available()){ // HAS A BUTTON ON THE KEYBOARD BEEN PRESSED?  IF SO, ENTER IN YOUR WORD. 
      getword();                // GET A WORD FROM THE KEYBOARD.  ENTER IN A WORD, RATHER.
      if(code == 13){           // IF THE RETURNED CODE IS 13 'exit" LEAVE THIS FUNCTION BY SETTING STATE TO 99.
        buttonwait();
        state = 99;             
      }
      else                      // OTHERWISE, DO THE FOLLOWING:
      {
        lcd.clear();            // CLEAR THE LCD
        lcd.print("Light Meter.EXE"); // RE-PRINT THIS TO THE LCD
      }
      }
      else if(analogRead(14) > 25){
        buttonwait();
        state = 99;
      }
     }
  }
  }
} // THIS IS THE END OF THIS FUNCTION

void analogin(){        // THIS FUNCTION SAMPLES THE LIGHT LEVEL IN TEH ROOM, AND CHANGES THE VALUE INTO A MORE SIMPLISTIC VALUE
  hold = analogRead(0); // SAMPLE THE A0 PIN, WHICH IS CONNECTED TO THE LIGHT SENSOR
  if(hold > 600){       // IF THE VALUE IS GREATER THAN 600, THEN THE ROOM IS PRETTY DARK.  
    hold = 7;           // CHANGE hold TO 7 AND RETURN
  }
  else if(hold > 550){  // IF LESS THAN 600, BUT GREATER THAN 550, THEN CHANGE hold TO 6 AND RETURN.
    hold = 6; 
  }
  else if(hold > 500){  // CONTINUE TO COMPARE.  THE REST OF THIS PROGRAM IS SIMPLE.  IT DOES THE SAME THING OVER AND OVER UNTIL hold IS GIVEN A NEW VALUE
    hold = 5;           // FROM 0 THROUGH 7.  THE RETURNED VALUE DETERMINES WHICH LED IS TURNED ON IN THE newmatrix() PROGRAM. 
  }
  else if(hold > 450){
    hold = 4;
  }
  else if(hold > 400){
    hold = 3;
  }
  else if(hold > 350){
    hold = 2;
  }
  else if(hold > 300){
    hold = 1;
  }
  else{
    hold = 0;
  }
} // THIS IS THE END OF THIS FUNCTION

void soundmatrix(){             // SIMILAR TO THE newmatrix() FUNCTION, THIS IS A SOUND LEVEL METER
  state = 0;                    // SET STATE TO 0
  lcd.clear();                  // CLEAR THE LCD
  lcd.print("Sound Meter.EXE"); // PRINT THIS TO THE LCD
  lcd.setCursor(0,1);           // SET THE LCD CURSOR TO THE SECOND LINE OF THE LCD
  lcd.print("ENT: exit ToEXIT");// PRINT THIS TO THE LCD  
  while(state != 99){           // DO THE FOLLOWING WHILE state DOES NOT EQUAL 99.  STATE STARTS AT 0
    {
for(int i = 0; i < 8; i++){     // EXECUTE THE FOLLOWING CODE 8 TIMES
  digitalWrite(xarray[i],LOW);  // SET THE xarray LED CONTROL PIN POINTED TO BY i, AND SET IT LOW.  REMEMBER, i INCREMENTS EACH TIME THIS FOR LOOP EXECUTES.
    analogin3();                // CALL THE anaglog3() FUNCTION. IT SAMPELS THE MICROPHONE AND SIMPLIFIES IT'S VALUE INTO A NUMBER BETWEEN 0 AND 7 (8 STATES IN TOTAL) 
    digitalWrite(yarray[hold],HIGH);  // SET THE RELATIVE yarray LED CONTROL PIN HIGH.  THE VALUE IN hold RETURNED FROM analogin() POINTS TO THE RLATIVE CONTROL PIN.
    delay(3);                   // WAIT 3ms
    matrixset();                // RE-SETUP THE LED MATRIX CONTROL PINS
      if (keyboard.available()){ // HAS A BUTTON ON THE KEYBOARD BEEN PRESSED?  IF SO, ENTER IN YOUR WORD. 
      getword();                // GET A WORD FROM THE KEYBOARD.  ENTER IN A WORD, RATHER.
      if(code == 13){           // IF THE RETURNED CODE IS 13 'exit" LEAVE THIS FUNCTION BY SETTING STATE TO 99.
        buttonwait();
        state = 99;             
      }
      else                      // OTHERWISE, DO THE FOLLOWING:
      {
        lcd.clear();            // CLEAR THE LCD
        lcd.print("Sound Meter.EXE"); // RE-PRINT THIS TO THE LCD
      }
      }
      else if(analogRead(14) > 25){
        buttonwait();
        state = 99;
      }
     }
  }
  }
} // THIS IS THE END OF THIS FUNCTION

void analogin3(){      // THIS FUNCTION SAMPLES THE AUDIO LEVEL IN TEH ROOM VIA MICROPHONE, AND SIMPLIFIES THE VALUE INTO A NUMBER BETWEEN 0 AND 7  
  //nowsample2();                
  hold = analogRead(6);// SAMPLE THE AUDIO IN THE ROOM BY TAKING AN ADC READING FROM THE MICROPHONE ON THE A6 ANALOG PIN
  if(hold > 200){      // COMPARE THE RESULT AGAINST VALUE 200, 170, 140, 110, 80, 50, AND 20.  THE RESULT WILL SEE THE VALUE IN hold CHANGED TO A NUMBER BETWENE 0 - 7
    hold = 0;          // SAID VALUE IS RETURNED AND USED IN THE soundmatrix() FUNCTION.
  }
  else if(hold > 170){
    hold = 1;
  }
  else if(hold > 140){
    hold = 2;
  }
  else if(hold > 110){
    hold = 3;
  }
  else if(hold > 80){
    hold = 4;
  }
  else if(hold > 50){
    hold = 5;
  }
  else if(hold > 20){
    hold = 6;
  }
  else{
    hold = 7;
  }
} // THIS IS THE END OF THIS FUNCTION.

void nowsample2(){                // This function samples the audio in the room from the microphone 100x times and averages it.
  hold = 0;                       // Set hold to 0
  for(int i = 0; i < 100 ; i++){  // Do the following 100x times
  holdadc = analogRead(6);        // Sample the ADC value form the microphone.  Place the returned value into holdadc
  hold = hold + holdadc;          // Add the value in holdadc into hold (hold will eventually contain the sum of all 100 samples)
  }
  hold = hold / 100;              // When the loop is done, divide the entire sum by 100 to average it.
}                                 // This is the end of this function




void mictest(){   // This function tests the microphone
state = 0;        // Set state to 0
hold = 136;       // Audio pointer: "Sound"
readout2();       // Play sound bite
hold = 178;       // Audio pointer: "Check"
readout2();       // Play the audio bite
lcd.clear();      // Clear the LCD
lcd.print("Awaiting sound..."); // Print this to the LCD
delay(1000);      // Wait 1 second  
while(state == 0){ // Do the following while state equals 0.  When state changes to anything other than 0, end this loop 
  {
    hold = analogRead(6); // Sample the microphone ADC value (Analog poin 6), and place the retuend value into hold
    if(hold > 400){       // If hold is greater than 400, then a loud noise has been detected.  If so, do the following:
    state = 1;            // Change state form 0 to 1 to end this while loop
    }
  }
}
lcd.clear();                   // Now that a sound has been detected, do the following:
lcd.print("Sound Detected!");  // Print this to the LCD
hold = 136;              // Audio pointer: "Sound"
readout2();               // Play the audio bite
hold = 144;               // Audio pointer: "Detected"
readout2();               // Play the audio bite
delay(1000);              // Wait 1 second
}                         // This is the end of this function


void keyboardtest(){            // This function isn't used in the directory, but can be called anytime to test the external computer keyboard
  hold = 0;                     // Set hold to 0
  Serial.println("Keyboard Test! Enter 5x Characters");   // Print this to the serial monitor
  while(hold != 5){             // Loop the following until hold equals 5.  Or rather, do the following while hold DOES NOT (!=) equal 5    
 {       
    if (keyboard.available())   // Has a button been pressed?  If so, do the following:
    {
    char c = keyboard.read();   // Read the keyboard, and take the returned ASCII code value and place it in char (Character) c
    Serial.print(c);            // Print c to the serial monitor
     hold = hold + 1;           // Increment hold by 1.  Once hold equals 5, then 5 chacters have been received, and this function will end
    }     
}
}
} // This is the end of this function
                                

void buzz(){                  // This function beeps the buzzer once for 20 milliseconds.  Just a quick beep.
  digitalWrite(buzzer,HIGH);  // Turn the buzzer on  
  delay(20);                  // Wait 20ms
  digitalWrite(buzzer,LOW);   // Turn the buzzer off
  delay(20);                  // Wait another 20ms
}                             // All done!


void leds()                    // This function tests the red, green, and yellow LEDs
{
  for(int i = 0; i < 3 ; i++){ // Loop the following code 3 times 
  digitalWrite(RLED,HIGH);     // Turn on the red LED
  delay(250);                  // Wait 1/4 of a second
  digitalWrite(YLED,HIGH);     // Turn on the yellow LED
  delay(250);                  // Wait another quarter second   
  digitalWrite(GLED,HIGH);     // Turn on the green LED
  delay(250);                  // wait for another 250ms
  digitalWrite(RLED,LOW);      // Then turn off all three LEDs in order from red, yellow, and green with delays in between.
  delay(250);
  digitalWrite(YLED,LOW);
  delay(250);
  digitalWrite(GLED,LOW);
  delay(250);          
  }
}
 

void matrixcheck()        // This function tests all 64 LEDs in the 8x8 LED matrix
{                     
digitalWrite(x1,LOW);     // Turn on the x1 row
scroll();                 // Call the scroll function, which turns all y column leds on and off in order, effectively testing 8x of the 64 LEDs 
digitalWrite(x2,LOW);     // Now turn on the x2 row.  Check out the scroll() function to see how it works.  It ends with calling the matrixset() funciton...
scroll();
digitalWrite(x3,LOW);
scroll();
digitalWrite(x4,LOW);
scroll();
digitalWrite(x5,LOW);
scroll();
digitalWrite(x6,LOW);
scroll();
digitalWrite(x7,LOW);
scroll();
digitalWrite(x8,LOW);
scroll();
}

void scroll()             // This function turns all y LEDs on the 8x8 LED matrix on and then off in order from y1 to y8
{
  digitalWrite(y1,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y2,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y3,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y4,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y5,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y6,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y7,HIGH);
  delay(100);
  matrixoff();
   digitalWrite(y8,HIGH);
  delay(100);
  matrixset();
} // THIS IS THE END OF THIS FUNCTION

void matrixset()  // This function sets all 8x8 LED matrix LEDs to a default state.  All x row LEDs are set high, and all y column LEDs are set low
{
  digitalWrite(x1,HIGH);
  digitalWrite(x2,HIGH);
  digitalWrite(x3,HIGH);
  digitalWrite(x4,HIGH);
  digitalWrite(x5,HIGH);
  digitalWrite(x6,HIGH);
  digitalWrite(x7,HIGH);
  digitalWrite(x8,HIGH);
  digitalWrite(y1,LOW);
  digitalWrite(y2,LOW);
  digitalWrite(y3,LOW);  
  digitalWrite(y4,LOW);
  digitalWrite(y5,LOW);
  digitalWrite(y6,LOW);
  digitalWrite(y7,LOW);
  digitalWrite(y8,LOW);
} // THIS IS THE END OF THIS FUNCTION

void matrixoff()  // This function turns all LEDs on the y axis on the 8x8 LED matrix off  
{
  digitalWrite(y1,LOW);
  digitalWrite(y2,LOW);
  digitalWrite(y3,LOW);  
  digitalWrite(y4,LOW);
  digitalWrite(y5,LOW);
  digitalWrite(y6,LOW);
  digitalWrite(y7,LOW);
  digitalWrite(y8,LOW);
} // THIS IS THE END OF THIS FUNCTION

void rtccheck(){                      // THIS PROGRAM GETS THE DATE FROM THE RTC AND PRINTS IT TO THE SERIAL MONITOR
  lcd.clear();                        // CLEAR THE LCD 
  lcd.print(" DATE TO SERIAL");       // PRINT THIS TO THE LCD
  lcd.setCursor(0,1);                 // SET THE LCD CURSOR TO THE SECOND LINE
  lcd.print("    MONITOR!");          // PRINT THIS TO THE LCD
  delay(3000);                        // WAIT THREE SECONDS
  lcd.clear();                        // CLEAR THE LCD
    DateTime now = rtc.now();         // ASK THE RTC FOR THE CURRENT DATE AND TIME
    Serial.println("The date is: ");  // PRINT THIS TO THE SERIAL MONITOR AND GO TO THE NEXT LINE (println)
    Serial.print(now.year(), DEC);    // PRINT THE YEAR IN DECIMAL (DEC)
    Serial.print('/');                // PRINT A FORWARD SLASH
    Serial.print(now.month(), DEC);   // PRINT THE MONTH
    Serial.print('/');          
    Serial.print(now.day(), DEC);     // PRINT THE CURRENT DAY
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);  // REMEMBER THAT ARRAY THAT WE TALKED ABOVE?  We use (daysOfTheWeek) in conjunction with now.daysOfTheWeek().  The number received in now.daysoftheweek points toward the day of the week (mon-sunday)
    // 1 = Monday, 7 = Sunday, etc.
    Serial.print(") ");
    Serial.print(now.hour(), DEC);    // PRINT THE CURRENT HOUR.  HOURS ARE IN 24 MODE.  SO 1 = 1AM, 12 = NOON, 14 = 2PM, ETC.
    hold = (now.hour());              // SAVE THE HOUR IN hold FOR LATER ON.
    Serial.print(':');                // PRINT A COLON TO SEPARATE HOURS AND MINUTES
    Serial.print(now.minute(), DEC);  // PRINT THE CURRENT MINUTE
    Serial.print(':');                // PRINT A COLON TO SEPARATE MINUTES AND SECONDS
    Serial.print(now.second(), DEC);  // PRINT THE CURRENT SECOND
    Serial.print(" ");                // PRINT A SPACE TO SEPARATE SECONDS AND AM/PM
    if(hold < 12)                     // REMEMBER THAT WE SAVED HOURS IN hold?  IF hold IS LESS THAN 12, PRINT "AM".  OTHERWISE, PRINT "PN".
    {
    Serial.print("AM");              
    }
    else
    {
    Serial.print("PM");  
    }
    Serial.println();                 // SKIP TO THE NEXT LINE
    Serial.print("Temperature: ");    // PRINT THIS TO THE SERIAL MONITOR
    Serial.print(rtc.getTemperature());   // ASK THE RTC FOR THE CURRENT TEMPERATURE AND PRINT IT TO THE LCD
    Serial.println(" C");                 // PRINT THIS TO THE LCD
    Serial.println();                     // GO TO THE NEXT LINE IN THE SERIAL MONITOR (PRESS ENTER)
} // THIS IS THE END OF THIS FUNCTION

void SDcardtest(){                                // THIS FUNCTION ACTS TO WRITE THE DATE TO AN SD CARD
    myFile = SD.open("sdtest.txt", FILE_WRITE);   // MAKE SURE THAT YOU HAVE A TEXT FILE CALLED "sdtest.txt" ON YOUR SD CARD.
    if (myFile) {                                 // IF THE FILE OPENS PROPERLY/IF THE FILE EXISTS, DO THE FOLLOWING.  OTHERWISE, SKIP TO THE BOTTOM OF THE CODE.  REMEMBER ME SAYING THIS, AS I WILL REFERENCE IT BELOW.              
    Serial.print("Writing to sdtest.txt...");     // WRITE THIS TO THE SERIAL MONITOR
    digitalWrite(RLED,HIGH);                      // TURN ON THE RED LED.  DON'T REMOVE POWER OR THE SD CARD WHEN THE RED LED IS ON.  THE RED LED ON MEANS THAT WE'RE WRITING TO THE SD CARD
    DateTime now = rtc.now();                     // ASK THE RTC FOR THE CURRENT DATE AND TIME
    // WRITE ALL OF THE RTC DATA TO THE SD CARD!  IT WILL ALL SHOW UP IN THE sdtest.txt FILE ON YOUR SD CARD.
    myFile.print("The date is: ");                // PRINT THIS TO THESD CARD AND GO TO THE NEXT LINE (println)
    myFile.print(now.year(), DEC);    // PRINT THE YEAR IN DECIMAL (DEC)
    myFile.print('/');                // PRINT A FORWARD SLASH
    myFile.print(now.month(), DEC);   // PRINT THE MONTH
    myFile.print('/');                // ALL OF THIS CODE WAS IMPORTED FROM PROJECT#24.  NOTICE THE DIFFERENCE?  I'M TESTING YOU RIGHT NOW.  ARE YOU READING MY COMMENTS?  myFile.print means to print to the SD card. myFile.println means print, and skip to next line
    myFile.print(now.day(), DEC);     // PRINT THE CURRENT DAY
    myFile.print(" (");               // PRINT A BRACKET
    myFile.print(daysOfTheWeek[now.dayOfTheWeek()]);  // REMEMBER THAT ARRAY THAT WE TALKED ABOVE?  We use (daysOfTheWeek) in conjunction with now.daysOfTheWeek().  The number received in now.daysoftheweek points toward the day of the week (mon-sunday)
    // 1 = Monday, 7 = Sunday, etc.
    myFile.print(") ");               // PRINT ANOTHER BRACKET
    myFile.print(now.hour(), DEC);    // PRINT THE CURRENT HOUR.  HOURS ARE IN 24 MODE.  SO 1 = 1AM, 12 = NOON, 14 = 2PM, ETC.
    hold = (now.hour());              // SAVE THE HOUR IN hold FOR LATER ON.
    myFile.print(':');                // PRINT A COLON TO SEPARATE HOURS AND MINUTES
    myFile.print(now.minute(), DEC);  // PRINT THE CURRENT MINUTE
    myFile.print(':');                // PRINT A COLON TO SEPARATE MINUTES AND SECONDS
    myFile.print(now.second(), DEC);  // PRINT THE CURRENT SECOND
    myFile.print(" ");                // PRINT A SPACE TO SEPARATE SECONDS AND AM/PM
    if(hold < 12)                     // REMEMBER THAT WE SAVED HOURS IN hold?  IF hold IS LESS THAN 12, PRINT "AM".  OTHERWISE, PRINT "PM".
    {
    myFile.print("AM");              
    }
    else
    {
    myFile.print("PM");  
    }
    myFile.println();                     // SKIP TO THE NEXT LINE
    myFile.print("Temperature: ");        // PRINT THIS TO THE SD CARD
    myFile.print(rtc.getTemperature());   // ASK THE RTC FOR THE CURRENT TEMPERATURE AND PRINT IT TO THE SD CARD
    myFile.println(" C");                 // PRINT THIS TO THE SD CARD
    myFile.println();                     // GO TO THE NEXT LINE IN THE SD CARD (PRESS ENTER)
    delay(3000);                          // WAIT 3 SECONDS
    // close the file:
    myFile.close();                       // THIS COMMAND CLOSES AND SAVES YOUR TEXT FILE "sdtest.txt"
    digitalWrite(RLED,LOW);               // TURN THE RED LED OFF.  THE DARK TIMES ARE OVER!
    digitalWrite(GLED,HIGH);              // WHILE THE GREEN LED IS ON, IT IS SAFE TO REMOVE POWER!
    Serial.println("done.");              // PRINT THIS TO THE SERIAL MONITOR
    delay(1000);                          // WAIT ONE SECOND 
    digitalWrite(GLED,LOW);               // TURN THE GREEN LED OFF
    Serial.println("Awaiting movement trigger...");            // PRINT THIS TO THE SERIAL MONITOR
    } else {
    // REMEMBER WHAT I TALKED ABOUT ABOVE?  IF THE TEXT FILE DIDN'T EXIST, OR IF THE CHIP SELECT PIN ISN'T WORKING CORRECTLY, THEN ALL OF THE ABOVE CODE WILL BE OVERLOOKED, AND THIS WILL HAPPEN.
    Serial.println("error opening test.txt");     // IF THIS HAPPENS, MAKE SURE THAT YOU HAVE EVERYTHING CONNECTED PROPERLY.  
  }
}     // WELL THAT WAS AN ADVENTURE, WASN'T IT?  


void programcode(){             // When this function is called, you can enter in a new security code into memory
  lcd.print("ENTER A 4-DIGIT"); // Print this to the LCD
  lcd.setCursor(0,1);           // Set the LCD cursor to the second line
  lcd.print("CODE: ");          // Print this to the LCD
  hold = 84;                    // Audio pointer: "Enter in a new code"
  readout();                    // Play the audio bite
  state = 0;                    // Set state to 0
      for(int i = 0; i < 4; i++){   // Loop the following 4 times.  i will be our counter, and act as s pointer into memory
      adckeypadtest();              // Wait for a button to be pressed.  The decoided value will be returned in 'hold'
      securitycode[i] = hold;       // Place the retuend button value in the address in the security code list pointed to by 1 (There are 4 placed in total)
      EEPROM.write(i,hold);         // Write the button value into the address in memory pointed to by i (Addresses in memory for the code are 0,1,2, and 3)
      lcd.print(hold);              // Print the button value to the LCD
    }
    delay(1000);                    // Once the FOR loop is done, wait one second
    lcd.clear();                    // Clear the LCD
    lcd.print("YOUR CODE: ");       // Print this to the LCD
    for(int i = 0; i < 4; i++){     // Perform the following loop 4 times
      lcd.print(securitycode[i]);   // Print the number in securitycode list address pointed to by i
    };                              // The above FOR loop just prints all four numbers that you just entered.
    lcd.setCursor(0,1);             // Set the LCD cursor to the second line
    lcd.print("IS PROGRAMMED!");    // Print this to the LCD
    hold = 69;                      // Audio pointer: "Code programmed"
    readout();                      // Play the audio bite
    delay(2000);                    // Wait 2 seconds
} // THIS IS THE END OF THIS FUNCTION

void verifycode(){                  // This function denies the user entry until the correct security code is entered
  state = 0;                        // set state to 0
  lcd.clear();                      // Clear the LCD
  while(state == 0){                // Do the following while state = 0.  When state changes to anything other than 0, this loop will end
    {             
      hold = 84;                    // Audio pointer: "Enter your security code"
      readout();                    // Play the audio bite    
      lcd.clear();                  // Clear the LCD
      lcd.print("ENTER SECURITY");  // Print this to the LCD
      lcd.setCursor(0,1);           // Set the LCD cursor to the second line
      lcd.print("CODE NOW: ");      // Print this to the LCD
      for(int i = 0; i < 4; i++){   // Perform the following loop 4 times.  'i' will be used as a counter and pointer
      adckeypadtest();              // Wait for a button to be pressed on the keypad, and return the stored value in 'hold'
      securitycode[i] = hold;       // Place the returned value into the address in the securitycode list pointed to by i (Starts at 0, ends at 3)
      lcd.print(hold);              // Print the button value to the LCD
    }   
    delay(1000);                    // Wait one second
    lcd.clear();                    // Clear the LCD
    hold = 0;                       // Clear hold
    // The following does a few things.  First we read EEPROM address 0, and compare it to the first returned button value in the securitycode list
    // It also compares the mastercode1 values against the first returned button value in  the security code list.
    // IF either match, increment hold by 1.  
    // We do this comparison against all other mastercode values, and EEPROM addresses (0-3 in total).  Whenever a match is made, add 1 to hold
    if(EEPROM.read(0) == securitycode[0] || mastercode1 == securitycode[0]){  
      hold = hold + 1;
    }
      if(EEPROM.read(1) == securitycode[1] || mastercode2 == securitycode[1]){
        hold = hold + 1;
      }
        if(EEPROM.read(2) == securitycode[2] || mastercode3 == securitycode[2]){
          hold = hold + 1;
        }
          if(EEPROM.read(3) == securitycode[3] || mastercode4 == securitycode[3]){
            hold = hold + 1;
          }
          if(hold == 4){                // If hold equals 4, then one code has been fully matched, and you'll gain access to the system
            lcd.clear();                // Clear the LCD  
            lcd.print("CODE CORRECT!"); // Print this to the LCD
            lcd.setCursor(0,1);         // Set the LCD cursor to the second line.
            lcd.print("ACCESS GRANTED!"); // Print this to the LCD
            hold = 16;                    // Audio pointer: "Access"
            readout();                    // Play audio bite
            hold = 86;                    // Audio pointer: "Granted"
            readout();                    // Play the audio bite
            delay(300);                   // Wait 0.3 seconds
            lcd.clear();                  // Clear the LCD
            state = 1;                    // Set state to 1 to end this while loop
          } 
    else                                  // If one or more numbers did not match...
    {
      lcd.clear();                        // Clear the LCD
      lcd.print("INCORRECT CODE!");       // Print this to the LCD
      lcd.setCursor(0,1);                 // Set the LCD cursor to the second line
      lcd.print("TRY AGAIN...");          // Print this to the LCD
      hold = 16;                          // Audio pointer: "Access"
      readout();                          // Play the audio bite
      hold = 53;                          // Audio pointer: "Denied"    
      readout();                          // Play the audio bite
      delay(300);                         // Wait 0.3 seconds, then start at the top of the while loop to try again
    }                                     // You won't leave this funciton until a proper code is entered, and therefore won't gain access until you do so.
    }
  }
}  // THIS IS THE END OF THIS FUNCTION
  

void buttonwait(){                  // This function waits for the user to let go of any button being pushed.  If no button is pressed when this function is called, then it will effectively skip this function.
  delay(10);
  while(analogRead(14) > 25){        // Do nothing while the button is being pushed.
  {}
}    
delay(100);
}


void adckeypadtest(){              // THIS FUNCTION TESTS THE ON-BAORD ADC KEYPAD
hold = 0;                          // SET hold TO 0   
while(analogRead(14) < 25){        // SAMPLE THE ADCK PIN.  IF NO BUTTON IS PUSHED, WE SHOULD SEE 0v AND AN ADC VALUE OF AROUND 0.  DO NOTHING IN THIS WHILE LOOP UNTIL A BUTTON IS PUSHED (ADCK VALUE IS HIGHER THAN 25 INDICATES A BUTTON PRESS)
  {}
}                                  // WHEN A BUTTON IS PRESSED, END THIS WHILE LOOP
delay(50);                         // WAIT 50ms TO COMPENSATE FOR SWITCH BOUNCE
hold = analogRead(14);             // SAMPLE THE ADCK PIN AGAIN FOR THE ANALOG BUTTON VALUE
//lcd.print("AnalogVal: ");        // PRINT THIS TO THE TOP LINE OF THE LCD
//lcd.print(hold);                 // PRINT THE SAMPLED ADCK ANALOG TO DIGITAL VALUE
//buzz();                            // CALL THE buzz() FUNCTION TO BEEP THE BUZZER
decode();                          // CALL THE DECODE FUNCTION.  THIS FUNCTION DECODES THE ANALOG VALUE AND TURNS IT INTO A NUMBER FROM 0-9 THAT CORRESPONDS TO THE BUTTON THAT YOU PRESSED
//lcd.setCursor(0,1);              // SET THE LCD CURSOR TO THE BOTTOM LINE
//lcd.print("Button#" );           // PTINT THIS TO THE LOWER LINE OF THE LCD
//lcd.print(hold);                 // hold NOW HOLDS THE DECODED BUTTON VALUE.  PRINT IT TO THE LCD.
while(analogRead(14) > 25){        // SAMPLE THE ADCK PIN OVER AND OVER AND DO NOTHING UNTIL YOU HAVE LET GO OF THE BUTTON.  DO NOTHING UNTIL ADCK VALUE IS LESS THAN 25 (NEAR 0V)
  {}
}                                  // WHEN YOU HAVE LET GO OF THE BUTTON, END THIS WHILE LOOP
//lcd.clear();                     // CLEAR THE LCD
delay(50);                         // WAIT 50ms TO COMPENSATE FOR SWITCH BOUNCE, THEN START THIS LOOP OVER
} // THIS IS THE END OF THIS FUNCTION

void decode()                     // THIS FUNCTION TAKES THE ADC VALUE TAKEN FROM THE ADCK PIN AND TURNS THE VALUE IN hold FROM AN ADC VALUE TO A NUMBER VALUE FROM 0 - 9 WHICH CORRESPONDS TO THE BUTTON YOU'VE PRESSED  
{
  if(hold > 950)                  // IF hold IS GREATER THAN 950 (CLOSE TO 5V)...
  {
   hold = 0;                      // THEN hold WILL EQUAL 0...
  }
  else if(hold > 850)             // IF hold WASN'T HIGHER THAN 950, THEN SEE IF IT IS HIGHER THAN 760... AND SO ON.  THIS IS THE FIRST TIME WE'RE SEEING THE "ELSE IF" STATEMENT.  WE'LL TALK ABOUT IT BELOW.
  {
    hold = 9;
  }
  else if(hold > 740)
  {
    hold = 8;
  }
  else if(hold > 660)
  {
    hold = 7;
  }
  else if(hold > 560)
  {
    hold = 6;
  }
  else if(hold > 460)
  {
    hold = 5;
  }
  else if(hold > 360)
  {
  hold = 4;
  }
  else if(hold > 260)
  {
    hold = 3;
  }
  else if(hold > 160)
  {
    hold = 2;
  }
  else
  {
    hold = 1;                   // IF hold IS NOT GREATER THAN 120, THEN THE ONLY BUTTON LEFT IS BUTTON#1, SO WE DON'T HAVE TO COMPARE AGAINST ANYTHING.
  }
} // THIS IS THE END OF THIS FUNCTION




void mood(){                    // This is the function used when the Butler asks us if we want to log our mood for the day
  lcd.clear();                  // Clear the LCD
  lcd.print("PRESS ANY BUTTON");// Print this to the LCD
  lcd.setCursor(0,1);           // Go to the second line of the LCD
  lcd.print("ON THE KEYPAD...");// Print this to the second line of the LCD  
  hold = 34;                    // Audio pointer: "Would you like to log your mood for the day?"
  readout();                    // Play the audio bite
  delay(500);                       // Wait 500ms
  hold = 35;                        // Audio Pointer: "If so, enter your mood into the keypad"
  readout();                        // Play the audio bite
  state = 0;                        // Set state to 0
  for(int i = 0; i < 4000 ; i++){   // Do the following 4000 times.  This is a counter FOR loop.  If we don't want to log our mood, don't do anything for 4 seconds
    delay(1);                       // Delay 1/1000th of a second (1ms)
    if(analogRead(14) > 25){        // Check to see if any button has been pressed
    state = 1;                      // If so, set state to 1 
    break;                          // Exit this for loop early
    }
  }
  if(state == 1){                   // If no button was pressed, state still equals 0 and you'll exit from this function. If a button was pressed, do the following:
  delay(100);                       // Wait 100ms
  hold = analogRead(14);            // Take an analog sample from the keypad and store it in hold
  decode();                         // Call the decode() function to decode which button was pressed
  buzz();                           // Call the buzz() function to beep the buzzer to indicate that a button has been pressed
  delay(500);                       // Wait half a second
  moodval = hold;                   // WE'RE GOING TO SAVE OUR VALUE ELSEWHERE FOR NOW, AS WE NEED hold FOR THE READOUT COMMAND.
  while(analogRead(14) > 25){       // SAMPLE THE ADCK PIN OVER AND OVER AND DO NOTHING UNTIL YOU HAVE LET GO OF THE BUTTON.  DO NOTHING UNTIL ADCK VALUE IS LESS THAN 25 (NEAR 0V)
  {}
  }   
  hold = 69;                        // Audio pointer: "Thank you"
  readout();                        // Play audio bite
  hold = 94;                        // Audio pointer: "Your mood has been logged"
  readout();                        // Play audio bite
  divisor = EEPROM.read(4);         // Read EEPROM address 4, and place the returned value into 'divisor'
  if(divisor == 255 || divisor == 30 || divisor == 0){    // IF 255 or 0, THEN THIS IS THE FIRST MEASUREMENT. IF 30, THEN WE HAVE TO START OVER.
    flashmood();                  // CLEAR ALL SETTINGS
    EEPROM.write(4,1);            // SAVE DIVISOR TO ADDRESS 4
    EEPROM.write(5,7);            // SAVE ADDRESS POINTER. ZERO/START ADDRESS FOR POINER IS 7
    EEPROM.write(6,moodval);      // SAVE MOOD TO ADDRESS 6
  }  
  else                            // If divisor was anything other than 2, 30, or 255, then do the following instead:
  {
    divisor = divisor + 1;        // ADD ONE TO DIVISOR
    EEPROM.write(4,divisor);      // SAVE DIVISOR TO EEPROM
    pointer = EEPROM.read(5);     // READ EEPROM POINTER   
    pointer = pointer + 1;        // ADD ONE TO POINTER
    EEPROM.write(5,pointer);      // SAVE THE POINTER BACK INTO MEMORY
    EEPROM.write(pointer,moodval);// SAVE NEW MOOD VALUE TO MEMORY BASED ON POINTER    
  }
  }
}  // THIS IS THE END OF THIS FUNCTION



void getmood(){                       // This program looks at your past mood loggings, and determines how you've been over time.
  lcd.clear();                        // Clear the LCD
  divisor = EEPROM.read(4);           // Read address 4 in EEPROM memory, and store it in the 'divisor' integer
  pointer = EEPROM.read(5);           // Read address 5, and place it in the 'pointer' integer.  
  if(divisor == 0 || divisor == 255){ // Check to see if divisor is either 0 OR 255.  IF divisor is either of these values, do the following:
    lcd.print("NO MOOD DATA!");       // Print this to the LCD.  No mood data has been logged
    lcd.setCursor(0,1);               // Set the cursor to the second line of the LCD
    lcd.print("Exiting");             // Print this to the second line of the LCD
    delay(2000);                      // Leave this function. 
  }
  else                                // If divisor equalled anything other than 0 or 255, do the following:
  {
   moodadder = 0;                     // Clear the moodadder integer
   pointer = pointer + 1;             // Pointer was taken from memory address 5 and acts a pointer into memory.  Add one to pointer.
   for(int i = 6 ; i != pointer ; i++){   // Start i at 6, and loop the following for as long as i DOES NOT equal pointer.  Incrememt i after each loop.
    hold = EEPROM.read(i);            // read the address in EEPROM memory that i is currently pointing at, and store it in 'hold'
    //Serial.println(hold);           // Uncomment this line of code if you want to see what the value is on the serial monitor
    moodadder = moodadder + hold;     // Add the value from hold into moodadder.
   }                                  // We just took all logged mood values that we currently have stored in memory, and have added them together into moodadder
   Serial.print("moodadder = ");      // Print this to the serial montior
   Serial.println(moodadder);         // The sum of all logged moods are now in moodadder.  Print this value to the serial monitor
   Serial.print("Divisor: ");         // Print this to the serial montior
   Serial.println(divisor);           // Print the value in divisor to the serial monitor.  
   Serial.print("AVG Mood = ");       // Print this to the serial montitor
   moodadder = moodadder / divisor;   // Time to average your mood over time.  Divide the total sum of mood loggings by the divisor value
   Serial.print(moodadder);           // Print the averaged mood (1-10)
   lcd.clear();                       // Clear the LCD
   if(divisor < 5){             // IF LESS THAN 5 SAMPLES HAVE BEEN TAKEN, DON'T MENTION AVERAGE
   lcd.print("YOUR MOOD HAS");  // Print this to the LCD
   lcd.setCursor(0,1);          // Place the LCD cursor to the left side of the second line of the LCD.
   hold = 77;           // "YOUR MOOD HAS BEEN..." (Audio bite)  See the audio library.  This is an audio bite pointer.
   readout();           // Call the readout function to play the audio bite  
   if(moodadder < 4){   // If your averaged mood has been less than 4 (Pretty bad), do the following:  
   lcd.print("BEEN QUITE POOR");  // Print this to the LCD
   hold = 88;           // Point to the "poor" audio bite
   readout();           // Play the audio bite
   delay(1500);         // Wait 1.5 seconds
   hold = 74;           // Audio pointer: "DO SOMETHING NICE FOR YOURSELF."
   readout();           // Place the audio bite
   }                  
   else if(moodadder < 8){        // If moodadder was not less than 4, but is less than 8, do the following:
   lcd.print("BEEN UP & DOWN");   // Print this to the LCD
   hold = 30;                     // Audio pointer: "DECENT"       
   readout();            // Play the audio bite         
   delay(1500);          // Wait 1.5 seconds
   hold = 24;            // Audio pointer: "HAVE A GREAT DAY"
   readout();            // Play the audio bite
   }
   else{                 // If moodadder was 8 or higher, do the following:
   lcd.print("BEEN GREAT!"); // Print this to the LCD   
   hold = 90;            // Audio pointer: "QUITE GOOD"
   readout();            // Play the audio bite
   delay(1500);          // Wait 1.5 seconds
   hold = 22;            // Audio pointer: 'GOOD FOR YOU'
   readout();            // Play the audio bite
   }                     
   }                     // All done... But what if 'divisor' was greater than 5?  
   else                  // IF divisor was greater than 5, let's talk about averaged moods.  Do the following:
   {
   lcd.print("YOUR AVG MOOD:");   // Print this to the LCD
   lcd.setCursor(0,1);            // Move the LCD cursor to the left of the second line
   hold = 93;            // Audio pointer: "YOUR AVERAGED MOOD HAS BEEN..." 
   readout();            // Play the audio bite
   if(moodadder < 4){    // If your averaged mood is less than 4 (Bad), do the following:
   lcd.print("CONSISTENTLY BAD");     // Print this to the LCD
   hold = 7;      // Audio pointer: "CONSISTENTLY BAD"  
   readout();     // Play the audio bite
   delay(1500);   // Wait 1.5 seconds
   hold = 21;     // Audio pointer: 'I'm just a computer, and can't help you'
   readout();     // Play the audio bite
   delay(1000);   // Wait one second
   hold = 24;     // Audio pointer: "I hope that you have a great day."
   readout();     // Play the audio bite
   delay(1000);   // Wait one second
   }
   else if(moodadder < 8){   // If moodadder was less than 8, but greater than 4, then do the following
   lcd.print("UP AND DOWN"); // Print this to the LCD     
   hold = 27;     // Audio pointer: "MIDDLE RANGE"
   readout();     // Play the audio bite
   delay(1500);   // Wait 1.5 seconds
   hold = 74;     // Audio pointer: "HAVE A GREAT DAY"
   readout();     // Play the audio bite
   }        
   else{          // Otherwise, if moodadder is greater than 7, do the following:
   lcd.print("SUPER AWESOME!"); // Print this to the LCD
   hold = 44;     // Audio pointer: "QUITE GOOD LATELY"
   readout();     // Play the audio bite
   delay(1500);   // Wait 1.5 seconds
   hold = 42;     // Audio pointer: Owen Wilson: 'OH WOW!'
   readout();     // Play the audio bite  
   }
   }
  }
} // THIS IS THE END OF THIS FUNCTION

void flashmood(){                 // This function acts to flash (Clear) the values in EEPROM memory associated with mood loggings.
for(int i = 4; i < 40 ; i++){     // Loop 36 times.  Start with i at 4, and incremement after each loop until i is 40.
  EEPROM.write(i,0);              // i is going to be a pointer to the area in MEMORY that we're going to write as 0
  Serial.println(EEPROM.read(i)); // This line is completely optional. It verifies that the write occured, and prints the result to the serial monitor
}                                 // End of the FOR loop
for(int i = 0; i < 8; i++){       // Blink the red LED 8 times to signify that the EEPROM has been flashed
  digitalWrite(RLED,HIGH);
  delay(200);
  digitalWrite(RLED,LOW);
  delay(200);
}
} // THIS IS THE END OF THIS FUNCTION

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////For BBT
// The Audio Section
// This section is dedicated to the audio chips, and how they interact with the 8x8 LED matrix for a Kitt effect.


void readout()
{
  sample();               // Call the sample() function to sample the analog audio output, and set up decoding varaibles.  See this function below.  Really!  Look now!
  digitalWrite(cs,LOW);   // Talk to chip#1
  SPI.transfer(value1);   // Send command info (value1) to the chip via SPI.  Value1 is constant and never changes.  It is declared at the top of the code.
  SPI.transfer(hold);     // Call word number stored in hold
  digitalWrite(cs,HIGH);  // Stop talking to chip#1.  The word will be said by the BBT at this time
  delay(10);              // Delay of 10ms
  digitalWrite(YLED,HIGH);  // Turn on the yellow LED.
  while(digitalRead(csstop) == HIGH){ // The 'csstop' pin tells the processor when the audio bite has stopped playing.  Do the following while HIGH:
    {
    for(int i = 0; i < 8; i++){      // Perform the following loop 8x times.  One for each row of LEDs
    digitalWrite(xarray[i],LOW);     // i starts at 0, and ends at 7 (8x total) Each time this code executes, i increments.  xarray controls the row of LEDs.  It is a list.
    analogin2();                     // Call the analogin2() function, and return a value in 'hold'.  Check this function out now before you keep going...
    digitalWrite(yarray[hold],HIGH); // The returned decoded audio value is stored in hold, which will control the vertical LEDs.  yarray is a list of vertical LED outputs.
    delay(5);                        // Wait 5ms
    matrixset();                     // Call the matrixset() function to re-setup the matrix.  See the function below.
    }  
  }                                  // Once the FOR loop has completed executing (Once for each LED across from left to right), turn off the yellow LED
  digitalWrite(YLED,LOW);            // Turn yellow led off.
  delay(10);                         // Wait 10ms before starting another left to right audio meter scroll.  
  }
}                                    //  The above will loop over and over until the audio bite has stopped playing, and the ccstop line is LOW. 



void analogin2(){                     // This gets a little confusing , so listen closely =)
  nowsample();                        // Call the 'nowsample' function.  Have a look below to see how it works.
  if(hold > adcsampleg){              // Remember in the sample() function where we created variables adcsamplea through adcsampleg? 
    hold = 0;                         // This is where it comes into play.  We're going to take the averaged audio value that we took in "nowsample()'
  }                                   // And we're going to compare against all of the values that we created in the sample() function.
  else if(hold > adcsamplef){         // This will determine what LED to turn on on the vertical axis.  If the new sample in hold is larger than adcsampleg...
    hold = 1;                         // Then hold will equal 0, and this will effectively turn on the highest LED.  You'd think that it would be the lowest,
  }                                   // but no.  It is reversed.  Have a look back at the sample() funciton.  adcsampleg holds the larges value to compare against
  else if(hold > adcsamplee){         // adcsamplea holds the lowest.  We're comparing our new value in hold across 8x adcsample varibles that we create every
    hold = 2;                         // time we call the sample() function.  It may sound a little convoluted, but this is how I designed this program.
  }                                   // When you have your new value in hold, look back up in the code to where this function was called in the readout() function...
  else if(hold > adcsampled){         // We digitalWrite/Turn the LED on that is associated with the value in 'hold' within the yarray list. 
    hold = 3;                         // digitalWrite(yarray[hold],HIGH) -- If hold equals 3 when we return from this function, then digitalWrite(yarray[3],HIGH)
  }
  else if(hold > adcsamplec){
    hold = 4;
  }
  else if(hold > adcsampleb){
    hold = 5;
  }
  else if(hold > adcsamplea){
    hold = 6;
  }
  else{
    hold = 7;
  }
} // THIS IS THE END OF THIS FUNCTION

void nowsample(){               // This function takes 50 samples of the audio volume level, adds the values together in hold, and then divides hold by 50
  hold = 0;                     // Start hold at 0
  for(int i = 0; i < 50 ; i++){ // Perform the following loop 50 times
  holdadc = analogRead(15);     // Sample the A15 Analog line and place the returned value into 'holdadc'.  Analog pin#15 connects to the audio output socket.
  hold = hold + holdadc;        // hold equals itself plus the new sample held in adc.  
  }
  hold = hold / 50;             // Average hold by dividing it by 50.  This will give us an average voolume level of the audio sample.  
} // THIS IS THE END OF THIS FUNCTION

void readout2()                 // Readout(2) is called when you're taking to chip#2.  It is very similar to readout(0, but has a couple of differences.
{
  sample();                     // We still call the sample() function to get our averaged audio values to be placed in adcsamplea-adcsampleg
  digitalWrite(cs2,LOW);        // However, now we control the cs2 line as opposed to cs.  Cs means "Chip select" and cs2 is the SPI chipselect control pin for chip#2
  SPI.transfer(value1); 
  SPI.transfer(hold);
  digitalWrite(cs2,HIGH);       // The above is the same as readout(), only now we set cs2 high, as opposed to cs.
  delay(100);
  digitalWrite(YLED,HIGH);
  while(digitalRead(cs2stop) == HIGH){
    {
    for(int i = 0; i < 8; i++){
    digitalWrite(xarray[i],LOW);
    analogin2();
    //for(int j = 0; j < 8; j++){
    digitalWrite(yarray[hold],HIGH);
    delay(2);
    matrixset();
   }
  }
  digitalWrite(YLED,LOW);
  delay(100);
  }
} // THIS IS THE END OF THIS FUNCTION

void sample(){                      // This samples audio and sets up a decoding algorithm
  adcsamples = 0;                   // Clear the 'adcsamples' variable
  for(int i = 0; i < 100 ; i++){    // Execute the following loop 100x times
  holdadc = analogRead(15);         // Sample the audio output line (A15) and place the returned value in the 'holdadc' variable
  adcsamples = adcsamples + holdadc; // adcsamples equals itself + the new holdadc value
  }
  adcsamples = adcsamples / 100;      // Once the FOR loop is done (100x executions), divide the sum held in 'adcsamples' by 100 to get an average.
  adcsamplea = adcsamples - 6;        // Now we will set up 8x new variables.  adcsamplea equals adcsamples - 6.  So if adcsamples = 100, adcsampla = 96
  adcsampleb = adcsamples - 4;        // The point to all of this is that we'll need to create 8x differnt values to compare against for our volume meter
  adcsamplec = adcsamples - 2;        // As you can see adcsamplea is going to hold the smallest value of the 8, and adscampleh will hold the most. 
  adcsampled = adcsamples;            // If adscamples held 100 (as an example), then adcsampleh would hold 108.  This will all make sense in a little bit
  adcsamplee = adcsamples + 2;        // We'll compare real-time audio samples against these 8x variables to determine which vertical LEDs on the 8x8 array...
  adcsamplef = adcsamples + 4;        // Will be turned on based on the averaged volume.  This helps us to create a volume meter, or "Kitt' speech LED array.
  adcsampleg = adcsamples + 6;
  adcsampleh = adcsamples + 8;
} // THIS IS THE END OF THIS FUNCTION

void readout3()                       // The third and fourth chips haven't been populated, and therefore I haven't done much with them yet.
{                                     // It only takes four lines of code and a delay (If you want it) to play an audio bite.  
  digitalWrite(cs3,LOW);              // There's a lot involved with making the led array work for us, but you have to admit that it is pretty cool!
  SPI.transfer(value1);
  SPI.transfer(hold);
  digitalWrite(cs3,HIGH);
  delay(100);
  digitalWrite(YLED,HIGH);
  while(digitalRead(cs3stop) == HIGH){
    {
    for(int i = 0; i < 8; i++){
    digitalWrite(xarray[i],LOW);
    analogin2();
    //for(int j = 0; j < 8; j++){
    digitalWrite(yarray[hold],HIGH);
    delay(2);
    matrixset();
   }
  }
  digitalWrite(YLED,LOW);
  delay(100);
  }
} // THIS IS THE END OF THIS FUNCTION

 void readout4()
 {
  digitalWrite(cs4,LOW);
  SPI.transfer(value1);
  SPI.transfer(hold);
  digitalWrite(cs4,HIGH);
  delay(100);
  digitalWrite(YLED,HIGH);
  while(digitalRead(cs4stop) == HIGH){
    {
    for(int i = 0; i < 8; i++){
    digitalWrite(xarray[i],LOW);
    analogin2();
    //for(int j = 0; j < 8; j++){
    digitalWrite(yarray[hold],HIGH);
    delay(2);
    matrixset();
   }
  }
  digitalWrite(YLED,LOW);
  delay(100);
  }
} // THIS IS THE END OF THIS FUNCTION

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////FOR KEYBOARD

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////FOR KEYBOARD
// This entire section is dedicated to keyboard stuff.  I keep this separated by a ton of forward slashes, as I want to always keep this space
// at the bottom of the code.  Just so that I can keep track of it.

void getword() // This function saves an entered word to the emptycode[] list, and displays the word on the lcd.
{
lcd.clear();                  // Clear the LCD
lcd.print("ENTER COMMAND:");  // Print this to the top line of the LCD
lcd.setCursor(0, 1);          // Set the cursor to the second line of the LCD
if(digitalRead(keyDIP) == LOW){
clrcode();                    // call the 'clrcode() function below.  This function clears the data in emptycode[].  It makes the entire list 0s.
returnvalue();                // This function is a big one.  It waits for a word to be entered, and saves it to emptycode[].  See below.
printletters();               // This function prints the ASCII code character values from the word you just entered to the serial monitor.   See below. 
compareword();                // This function compares the new word against all other lists in the list section.  If any matches are made, then "code" will 
Serial.print("Code = ");    // not equal 0, but rather a number corresponding to a matched word.  Check out the function.  You'll see what I mean.
Serial.println(code);         // Print the matched code to the serial monitor.  If no match was made, code = 0.
delay(100);                   // Wait 100ms.
lcd.clear();                  // Clear the LCD
keyboardflush();              // The keyboardflush function clears the keyboard buffer.  If there's anything pressed at this point, this will clear that data.
}                             // AFTER ALL OF THIS, WE'LL TO BACK TO VOID LOOP() WHICH WILL CALL THE getword() FUNCTON ALL OVER AGAIN. 
else
{
  buttonoption();
}
}

void buttonoption(){
state = 0;                      // Start with state at 0;
adckeypadtest();                // Wait for the fisrt button to be pressed
buttonnum1 = hold;              // Place the returned value from hold into buttonnum1
delay(100);
adckeypadtest();              // Get the button number
buttonnum1 = buttonnum1 * 10; // Multiply the first number that you entered by 10
code = buttonnum1 + hold;        // Add the button value that you just ented, and place the sum into code
lcd.clear();
lcd.print("Code = ");
lcd.print(code);
delay(1500);
}


void clrcode()    // This function clears every single value in the emptycode[] list to 0 one-by-one.
{
emptycode[0] = 0;
emptycode[1] = 0;
emptycode[2] = 0;
emptycode[3] = 0;
emptycode[4] = 0;
emptycode[5] = 0;
emptycode[6] = 0;
emptycode[7] = 0;
emptycode[8] = 0;
emptycode[9] = 0;
emptycode[10] = 0;
emptycode[11] = 0;
emptycode[12] = 0;
emptycode[13] = 0;
emptycode[14] = 0;
emptycode[15] = 0;
} // THIS IS THE END OF THIS FUNCTION

void returnvalue() // This function returns an entered word.  There is a bit to digest here.
{
  state = 0;                    // Set 'state', 'charnum', 'hold', and 'letternum' to 0 as a starting state.
  charnum = 0;
  hold = 0;
  letternum = 0;
  while(state == 0) {           // Since we just set 'state' to 0, execute the following code in this while loop until 'state' equals anything other than 0.
  {                     
  if (keyboard.available()) {   // Wait for a keyboard character to be entered
    char c = keyboard.read();   // Once received, place the ASCII character returned by the keyboard in to 'char c' (character c) 
    hold = c;                   // Save it again to 'hold'.  'hold' now also equals 'c'
    if(hold == 13)              // If 'hold' equals 13, then you've pressed enter, and we're done.  The ASCII character for enter is 13.  
    {                           // GOOGLE 'ASCII TABLE'  TO LOOK AT OTHER ASCII VALUES
      break;                    // If 13 was the returned value, then exit this while loop.  Break means exit. You could also say state = 1 to do the same thing.
    }
    if(c == 127){               // Otherwise, check to see if c (or hold) equals 'backspace' (127 ASCII).  If so, we need to delete a character.
      if(letternum != 0){       // Letternum is our character counter.  If it DOESN'T EQUAL 0 (!= 0), then do the following.
      letternum = letternum - 1;  // Decrement letternum by 1
      charnum = charnum - 1;      // Decrement charnum by 1
      lcd.setCursor(letternum,1); // Move backwards one character on the LCD
      lcd.print(" ");             // Add a space to delete the last character you entered
      lcd.setCursor(letternum,1); // Move backwards once again on the LCD with the character deleted.
      }
      else                        // If letternum DID EQUAL 0... 
      {}                          // then do nothing...
      }                           // end of the 'if(letternum != 0 )' if statement
    else                          // If c DID NOT equal 127 (Was not a backspace character), then do the following instead... 
    {
    letternum = letternum + 1;    // Add 1 to the letternum counter
    lcd.print(c);                 // print the received character to the LCD
    emptycode[charnum] = c;       // Place the character in the emptycode list in the slot determined by the value in 'charnum'
    charnum = charnum + 1;        // Add 1 to charnum so that the pointer knows there to add the next character in the emptycode[] list
    if(charnum == 16)             // If charnum equals 16, then there's no more room in the list.  This forces us to end this function.
    {
      delay(1000);                // Wait once second, and end the while loop by changing state to 1
      state = 1;                  // YEEEEAAAAHHH BOYEEEEEE
    }
  }
  }
  }
  }
} // THIS IS THE END OF THIS FUNCTION

void printletters(){  // If you have your serial monitor open, you can now see the word that you just entere in ASCII
Serial.println();                 // Start a new line in the serial monitor.  The 'ln' at the end of 'print' means 'new line'.
for(int i = 0; i < 16; i++){      // This FOR loop acts to print our new word in order to the serial monitor.  All 16 characters.  Even the 0s.
  Serial.print(emptycode[i]);     // As the FOR loop executes, i is incremented.  i is the pointer in the emptycode list.  
  Serial.print(" ");              // Print a space after each character is entered.
}                                 // After the above two code lines are executed 16 times, the FOR loop ends.
Serial.println();                 // Start a new line on the serial monitor
} // THIS IS THE END OF THIS FUNCTION


void keyboardflush()  // This function gets rid of any characters currently in the buffer so that we don't get any unexpected business.
{
while (keyboard.available() >0 ) {  // Is there anything in the buffer?  If yes, get rid of it by reading it.  Otherwise, end this function.    
   keyboard.read();                 // Read the keyboard buffer and do nothing with it
}
} // THIS IS THE END OF THIS FUNCTION

void compareword(){    // Compare the new word that you just entered against all other command list words.                         
hold = 0;                                 // Clear 'hold', 'code', and 'state'          
code = 0;
state = 0;
Serial.println();                         // Start a new line on the serial monitor
Serial.println("Comparing commands...");  // Print this to the serial monitor
for(int i = 0;i <16; i++){                // This FOR loop compares the emptycode[] list against the cmd1[] list.  i increments after each execution.
if(emptycode[i] == cmd1[i]){              // if the value in emptycode[] pointed to by i, equals the same value in cmd1[] pointed to by the sam value (i) 
  hold = hold + 1;                        // Then increment 'hold' by 1.  If all 16 values match, return with 'code' equalling 1.
}
if(hold == 16){                           // If the new word that we just entered matches the word in cmd1[], return with 'code' equalling 1.
  code = 1;
}
}                                         // If the above word was NOT a match, let's try comparint it to the cmd2[] list.
hold = 0;                                 // Clear 'hold' and run comparisons against all other word lists.  If none match, 'code' returns 0.
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd2[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 2;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd3[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 3;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd4[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 4;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd5[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 5;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd6[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 6;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd7[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 7;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd8[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 8;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd9[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 9;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd10[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 10;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd11[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 11;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd12[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 12;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd13[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 13;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd14[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 14;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd15[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 15;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd16[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 16;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd17[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 17;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd18[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 18;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd19[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 19;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd20[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 20;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd21[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 21;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd22[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 22;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd23[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 23;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd24[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 24;
}
}
hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd25[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 25;
}
}
} // THIS IS THE END OF THIS FUNCTION


// To add a new word comparison to this long function, copy and paste the following:
/*
 * hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd26[i]){       // cmdxx[i] should be incremented by 1.  IF the last was 25, then this should be 26.
  hold = hold + 1;  
}
if(hold == 16){
  code = 26;                        // The value to be placed in 'code' needs to also be incremented in order for the statemachines() function to know where to
}                                   // direct the code
}


NOTE, THE LAST AND FINAL COMPARISON AT THE END OF THIS FUNCTION NEEDS ONE LAST CLOSING CURLY BRACE. IF YOU'RE JUST ADDING ONE TO THE END, THEN IT SHOULD LOOK LIKE:

hold = 0;
for(int i = 0;i <16; i++){
if(emptycode[i] == cmd25[i]){
  hold = hold + 1;  
}
if(hold == 16){
  code = 25;
}
}
}




*/
