//Variables
//Libraries
#include <Servo.h>
#include<LiquidCrystal.h>
//LEDs_Mandrill
int LED_red = 23;
int LED_yellow = 22;
int LED_green = 24;
int LED_blue = 26;
//LED_States
int LED_red_state = LOW;
int LED_yellow_state = LOW;
int LED_green_state = LOW;
int LED_blue_state = LOW;
//Buttons_Human
int Button_Human_reset = 53;//black
int Button_Human_red = 52;//red
int Button_Human_yellow = 50;//yellow
int Button_Human_green = 48;//green
int Button_Human_blue = 46;//blue
//Button_States_Human
int buttonState_reset;
int buttonState_red;
int buttonState_yellow;
int buttonState_green;
int buttonState_blue;
//Buttons_Mandrill
int Button_Mandrill_red = 13;//red
int Button_Mandrill_yellow = 12;//yellow
int Button_Mandrill_green = 11;//green
int Button_Mandrill_blue = 10;//blue
//Button_States_Mandrill
int buttonState_Mandrill_red;
int buttonState_Mandrill_yellow;
int buttonState_Mandrill_green;
int buttonState_Mandrill_blue;
//Buzzer
int Buzzer = 42;
//Ultra_Sonic
int trig = 2;//Pin for sound going out
int echo = 3;//pin for sound going in
float distance;//a number for distance
float time;//a number for time the sound left
//Servo
Servo myservo;
//LCD Display
const int rs = 40, en = 38, d4 = 30, d5 = 32, d6 = 34, d7 = 36;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
//System_Variables
//Unchangeing
int RED = LED_red;
int YELLOW = LED_yellow;
int GREEN = LED_green;
int BLUE = LED_blue;
int Servo_Closed_Position = 0;
int Servo_Open_Position = 90;
//Changeing
//Human and System
int Game_Start = 0;
int Color_Data = 0;
int Color_Selected_Data = 0;
int Number_Of_Colors_Pressed = 0;
int Reset_Count = 0;
int Human_Button_Red_Count = 0;
int Human_Button_Yellow_Count = 0;
int Human_Button_Green_Count = 0;
int Human_Button_Blue_Count = 0;
int Color_Order_One = 0;
int Color_Order_Two = 0;
int Color_Order_Three = 0;
int Color_Order_Four = 0;
//Mandrill
int Number_Of_Colors_Pressed_Mandrill = 0;
int Color_Order_One_Mandrill = 0;
int Color_Order_Two_Mandrill = 0;
int Color_Order_Three_Mandrill = 0;
int Color_Order_Four_Mandrill = 0;
int Leds_Displayed_Count = 0;
int Correct_Order_Check = 0;
//Other
int Has_Food_Been_Dropped = 0;
int distance_1 = 0;
int Distance_1_Recorded_Count = 0;
//Setup
void setup()
{
//Open_Serial
Serial.begin(9600);
//LEDs_Mandrill
pinMode(LED_red, OUTPUT);
pinMode(LED_yellow, OUTPUT);
pinMode(LED_green, OUTPUT);
pinMode(LED_blue, OUTPUT);
//Buttons_Human
//high if not pushed, low if pushed; No need for resistors this way
pinMode(Button_Human_reset, INPUT_PULLUP);
pinMode(Button_Human_red, INPUT_PULLUP);
pinMode(Button_Human_yellow, INPUT_PULLUP);
pinMode(Button_Human_green, INPUT_PULLUP);
pinMode(Button_Human_blue, INPUT_PULLUP);
//Button_States_Human
buttonState_reset = digitalRead(Button_Human_reset);
buttonState_red = digitalRead(Button_Human_red);
buttonState_yellow = digitalRead(Button_Human_yellow);
buttonState_green = digitalRead(Button_Human_green);
buttonState_blue = digitalRead(Button_Human_blue);
//Buttons_Mandrill
//high if not pushed, low if pushed; No need for resistors this way
pinMode(Button_Mandrill_red, INPUT_PULLUP);
pinMode(Button_Mandrill_yellow, INPUT_PULLUP);
pinMode(Button_Mandrill_green, INPUT_PULLUP);
pinMode(Button_Mandrill_blue, INPUT_PULLUP);
//Button_States_Mandrill
buttonState_Mandrill_red = digitalRead(Button_Mandrill_red);
buttonState_Mandrill_yellow = digitalRead(Button_Mandrill_yellow);
buttonState_Mandrill_green = digitalRead(Button_Mandrill_green);
buttonState_Mandrill_blue = digitalRead(Button_Mandrill_blue);
//Buzzer
pinMode(Buzzer, OUTPUT);
//Ultra_Sonic
pinMode(echo, INPUT);//echo takes in the sound
pinMode(trig, OUTPUT);//trig gives the sound
//Servo
myservo.attach(28);//attaches servo pin 9 to the servo object (named myservo)
//LCD Display
lcd.begin(16, 2);
}
//Basic Fuctions
void read_buttons()//This reads all buttons
{
//Human
buttonState_reset = digitalRead(Button_Human_reset);
buttonState_red = digitalRead(Button_Human_red);
buttonState_yellow = digitalRead(Button_Human_yellow);
buttonState_green = digitalRead(Button_Human_green);
buttonState_blue = digitalRead(Button_Human_blue);
//Mandrill
buttonState_Mandrill_red = digitalRead(Button_Mandrill_red);
buttonState_Mandrill_yellow = digitalRead(Button_Mandrill_yellow);
buttonState_Mandrill_green = digitalRead(Button_Mandrill_green);
buttonState_Mandrill_blue = digitalRead(Button_Mandrill_blue);
}
void find_distance()//This uses the Ultra_Sonic sensor to find the distance of how far the object in front of it is in cm
{
//This section is to find the distance
digitalWrite(trig, LOW);//turn off the sound being sent out
delayMicroseconds(2);//wait
digitalWrite(trig, HIGH);//turn on the sound being sent out
delayMicroseconds(10);//wait
digitalWrite(trig, LOW);//turn off the sound being sent out
time = pulseIn(echo, HIGH);//how long it took for the sound to come back
distance = (time*.0343)/2;; //This value is the distance from the sensor in centimeters
//this section is complete
}
void reset_game()//this resets all values
{
Game_Start = 0;
Color_Data = 0;
Color_Selected_Data = 0;
Number_Of_Colors_Pressed = 0;
Reset_Count = 0;
Human_Button_Red_Count = 0;
Human_Button_Yellow_Count = 0;
Human_Button_Green_Count = 0;
Human_Button_Blue_Count = 0;
Color_Order_One = 0;
Color_Order_Two = 0;
Color_Order_Three = 0;
Color_Order_Four = 0;
Number_Of_Colors_Pressed_Mandrill = 0;
Color_Order_One_Mandrill = 0;
Color_Order_Two_Mandrill = 0;
Color_Order_Three_Mandrill = 0;
Color_Order_Four_Mandrill = 0;
Leds_Displayed_Count = 0;
Correct_Order_Check = 0;
Has_Food_Been_Dropped = 0;
distance_1 = 0;
Distance_1_Recorded_Count = 0;
LCD_Reseting_Screen();
}
void print_start()
{
Serial.print("Game Start: ");
Serial.println(Game_Start);
delay(100);
}
void print_color_data()
{
Serial.print("Color Data: ");
Serial.println(Color_Data);
delay(100);
}
//Specific Fuctions
//LCD Screens
//System LCDs
void LCD_Start()//This displays the start message
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("Press Reset");
lcd.setCursor(4,1);
lcd.print("To Start");
delay(500);
lcd.clear();
}
void LCD_Starting_Screen()
{
lcd.setCursor(4,0);
lcd.print("Starting");
delay(500);
lcd.clear();
}
void LCD_Reseting_Screen()
{
lcd.setCursor(4,0);
lcd.print("Reseting");
delay(500);
lcd.clear();
}
void LCD_Bye()
{
lcd.setCursor(4,0);
lcd.print("Goodbye");
delay(500);
lcd.clear();
}
//Button LCDs
void LCD_Select_Colors()
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("Select Four");
lcd.setCursor(5,1);
lcd.print("Colors");
delay(500);
lcd.clear();
}
void LCD_Select_Colors_Selected()
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("Selected");
delay(500);
lcd.clear();
}
void LCD_Select_Colors_Thank_You()
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("All Selected");
lcd.setCursor(4,1);
lcd.print("Thank You");
delay(500);
lcd.clear();
}
void LCD_Look_Up()
{
lcd.setCursor(5,0);//(column,row) is how the Cursor works
lcd.print("Look Up");
delay(500);
lcd.clear();
}
void LCD_Select_Colors_Selected_Mandrill()
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("Mandrill");
lcd.setCursor(3,1);//(column,row) is how the Cursor works
lcd.print("Selected");
delay(500);
lcd.clear();
}
void LCD_They_Did_It_Correctly()
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("They Did It");
lcd.setCursor(3,1);//(column,row) is how the Cursor works
lcd.print("Correctly!");
delay(3000);
lcd.clear();
}
void LCD_They_Did_It_Wrong()
{
lcd.setCursor(3,0);//(column,row) is how the Cursor works
lcd.print("They Did It");
lcd.setCursor(0,1);//(column,row) is how the Cursor works
lcd.print("Wrong, Reseting");
delay(3000);
lcd.clear();
}
//After buttons LCDs
void LCD_Feeding_Mandrills_Reward()
{
lcd.setCursor(0,0);//(column,row) is how the Cursor works
lcd.print("Giving Mandrills");
lcd.setCursor(3,1);//(column,row) is how the Cursor works
lcd.print("A Reward");
delay(3000);
lcd.clear();
}
void LCD_Look_At_Feeding()
{
lcd.setCursor(0,0);//(column,row) is how the Cursor works
lcd.print("Mandrills Reward");
lcd.setCursor(0,1);//(column,row) is how the Cursor works
lcd.print("Dropped, Look");
delay(3000);
lcd.clear();
lcd.setCursor(0,0);//(column,row) is how the Cursor works
lcd.print("Mandrills Will");
lcd.setCursor(0,1);//(column,row) is how the Cursor works
lcd.print("Go Get It");
delay(3000);
lcd.clear();
}
//Serial
void printColorsValues()//prints the values that record the number of times the human buttons were pushed
{
Serial.print("Red: ");
Serial.println(Human_Button_Red_Count);
Serial.print("Yellow: ");
Serial.println(Human_Button_Yellow_Count);
Serial.print("Green: ");
Serial.println(Human_Button_Green_Count);
Serial.print("Blue: ");
Serial.println(Human_Button_Blue_Count);
}
void printColorsOrder()//prints the values that record the number of times the human buttons were pushed
{
Serial.print("One: ");
Serial.println(Color_Order_One);
Serial.print("Two: ");
Serial.println(Color_Order_Two);
Serial.print("Three: ");
Serial.println(Color_Order_Three);
Serial.print("Four: ");
Serial.println(Color_Order_Four);
}
void printColorsOrderMandrill()//prints the values that record the number of times the human buttons were pushed
{
Serial.print("One (mandrill): ");
Serial.println(Color_Order_One_Mandrill);
Serial.print("Two (mandrill): ");
Serial.println(Color_Order_Two_Mandrill);
Serial.print("Three (mandrill): ");
Serial.println(Color_Order_Three_Mandrill);
Serial.print("Four (mandrill): ");
Serial.println(Color_Order_Four_Mandrill);
}
void Correct_Order_Check_Serial()
{
Serial.print("Correct_Order_Check Value: ");
Serial.println(Correct_Order_Check);
}
void Print_Distance()
{
Serial.print("Distance Value (cm): ");
Serial.println(distance);
}
void Print_Distance_1()
{
Serial.print("Distance_1 Value (cm): ");
Serial.println(distance_1);
}
//Other
//Humans and System
void Button_Start()//This confirms if the start button has been pushed
{
read_buttons();
if(buttonState_reset == LOW){//if the reset button has been pushed then
Game_Start = 1;//1 means that the game is on
Reset_Count = 1;//the reset button was pushed once
LCD_Starting_Screen();
}
else{//if the reset button has not been pushed then
LCD_Start();
}
}
void Reset_Button_Pushed()//if reset button is pushed then stop the game
{
if(buttonState_reset == LOW){
Game_Start = 0;//turn game off
LCD_Bye();
}
}
void Record_Button_Human()//records the number of times each button was pushed
{
if(buttonState_red == LOW){//if the red button was pushed record that it was pushed
Human_Button_Red_Count = Human_Button_Red_Count + 1;//recored the number of times pushed
Record_Color_Order(RED);//record that the button was pushed at what order
}else if(buttonState_yellow == LOW){//if the yellow was pushed and red was not
Human_Button_Yellow_Count = Human_Button_Yellow_Count + 1;//recored the number of times pushed
Record_Color_Order(YELLOW);//record that the button was pushed at what order
}else if(buttonState_green == LOW){//if green was pushed and yellow and red was not
Human_Button_Green_Count = Human_Button_Green_Count + 1;//recored the number of times pushed
Record_Color_Order(GREEN);//record that the button was pushed at what order
}else if(buttonState_blue == LOW){//if blue was pushed and yellow, red, and green was not
Human_Button_Blue_Count = Human_Button_Blue_Count + 1;//recored the number of times pushed
Record_Color_Order(BLUE);//record that the button was pushed at what order
}
}
void Record_Color_Order(int Color_Pushed)//this will record the order in which each button is pushed, insert the color as the variable
{
if(Color_Order_One != 0 && Color_Order_Two == 0 && Color_Order_Three == 0){//if one was already recorded and two and three were not
Color_Order_Two = Color_Pushed;//then record two
}else if(Color_Order_One != 0 && Color_Order_Two != 0 && Color_Order_Three == 0){//if one and two was already recordedand and three were not
Color_Order_Three = Color_Pushed;//then record three
}else if(Color_Order_One != 0 && Color_Order_Two != 0 && Color_Order_Three != 0){//if one, two, and three was already recorded
Color_Order_Four = Color_Pushed;//then record four
}
else{//if nothing has been recorded
Color_Order_One = Color_Pushed;//record
}
}
//Mandrills
void Flash_Mandrills()//This will use the order of colors pushed to flash the mandrills the order
{
digitalWrite(Color_Order_One, HIGH);
delay(1000);
digitalWrite(Color_Order_One, LOW);
delay(300);
digitalWrite(Color_Order_Two, HIGH);
delay(1000);
digitalWrite(Color_Order_Two, LOW);
delay(300);
digitalWrite(Color_Order_Three, HIGH);
delay(1000);
digitalWrite(Color_Order_Three, LOW);
delay(300);
digitalWrite(Color_Order_Four, HIGH);
delay(1000);
digitalWrite(Color_Order_Four, LOW);
delay(300);
}
void Call_Mandrills()//flashes all lights so that the mandrills come over and look for the pattern
{
digitalWrite(RED, HIGH);
digitalWrite(YELLOW, HIGH);
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
delay(300);
digitalWrite(RED, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
delay(300);
digitalWrite(RED, HIGH);
digitalWrite(YELLOW, HIGH);
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
delay(300);
digitalWrite(RED, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
delay(300);
digitalWrite(RED, HIGH);
digitalWrite(YELLOW, HIGH);
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
delay(300);
digitalWrite(RED, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
delay(300);
}
void Tell_Mandrills()//flashes all lights so that the mandrills know they selected the button
{
digitalWrite(RED, HIGH);
digitalWrite(YELLOW, HIGH);
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
delay(300);
digitalWrite(RED, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
delay(300);
}
void Mandrill_Correct_Order()//this will scan and see if the mandrills enter the buttons in the correct order
{
if(Color_Order_One == Color_Order_One_Mandrill && Color_Order_Two == Color_Order_Two_Mandrill && Color_Order_Three == Color_Order_Three_Mandrill && Color_Order_Four == Color_Order_Four_Mandrill){//if the order of leds flashing is the same as the order of buttons pushed by mandrills
Correct_Order_Check = 1;//then they are correct
}
else{
Correct_Order_Check = 2;//other wise they are wrong
}
}
void Record_Button_Mandrill()//records using the buttons
{
if(buttonState_Mandrill_red == LOW){//if the red button was pushed record that it was pushed
Mandrill_Record_Color_Order(RED);//record that the button was pushed at what order
}else if(buttonState_Mandrill_yellow == LOW){//if the yellow was pushed and red was not
Mandrill_Record_Color_Order(YELLOW);//record that the button was pushed at what order
}else if(buttonState_Mandrill_green == LOW){//if green was pushed and yellow and red was not
Mandrill_Record_Color_Order(GREEN);//record that the button was pushed at what order
}else if(buttonState_Mandrill_blue == LOW){//if blue was pushed and yellow, red, and green was not
Mandrill_Record_Color_Order(BLUE);//record that the button was pushed at what order
}
}
void Mandrill_Record_Color_Order(int Color_Pushed_Mandrill)//this is a fuction to record the values of order in which the mandrills pushed the buttons
{
if(Color_Order_One_Mandrill != 0 && Color_Order_Two_Mandrill == 0 && Color_Order_Three_Mandrill == 0){//if one was already recorded and two and three were not
Color_Order_Two_Mandrill = Color_Pushed_Mandrill;//then record two
}else if(Color_Order_One_Mandrill != 0 && Color_Order_Two_Mandrill != 0 && Color_Order_Three_Mandrill == 0){//if one and two was already recordedand and three were not
Color_Order_Three_Mandrill = Color_Pushed_Mandrill;//then record three
}else if(Color_Order_One_Mandrill != 0 && Color_Order_Two_Mandrill != 0 && Color_Order_Three_Mandrill != 0){//if one, two, and three was already recorded
Color_Order_Four_Mandrill = Color_Pushed_Mandrill;//then record four
}
else{//if nothing has been recorded
Color_Order_One_Mandrill = Color_Pushed_Mandrill;//record
}
}
//Rewarding Mandrills
void Drop_Food_Servo()
{
myservo.write(Servo_Open_Position);
delay(5000);
myservo.write(Servo_Closed_Position);
}
void Drop_Food()
{
if (Has_Food_Been_Dropped == 0){//if the food has not been dropped
LCD_Feeding_Mandrills_Reward();
Drop_Food_Servo();
LCD_Look_At_Feeding();
Has_Food_Been_Dropped = Has_Food_Been_Dropped + 1;
delay(5000);//to give time for the food to settle
}
}
void record_distance_1()
{
if (Has_Food_Been_Dropped == 1 && Distance_1_Recorded_Count == 0){//if the food has been dropped and distance one has not been recorded
find_distance();//finds the distance infront of the ultra sonic
distance_1 = distance;//record distance 1 as the current distance
Print_Distance();
Print_Distance_1();
Distance_1_Recorded_Count = Distance_1_Recorded_Count + 1;
}
}
//Loop
void loop()
{
myservo.write(Servo_Closed_Position);//Make sure the servo is in the right place (my need to change this value)
reset_game();//This sets the game to off and resets all values to starting
read_buttons();//This sets all of the button states to their starting values
while(Game_Start == 0)//Run the start menu until the start button has been pushed
{
read_buttons();//This sets all of the button states to their starting values
Button_Start();
}
while(Game_Start != 0)//While game is not off, This will run the game until the game is turned off
{
//system fuctions
read_buttons();//This sets all of the button states to their starting values
Reset_Button_Pushed();//if the reset button is pushed then the game will turn off
//button while loops
while(Number_Of_Colors_Pressed != 4 && Game_Start != 0)//while 4 colors have not been selected, run the select colors screen
{
//so that the game can be reset while in this loop
read_buttons();
Reset_Button_Pushed();
LCD_Select_Colors();//shows the select colors screen
if(buttonState_red == LOW || buttonState_yellow == LOW || buttonState_green == LOW || buttonState_blue == LOW){//if any human button is pressed then
LCD_Select_Colors_Selected();//show that a color was selected
Number_Of_Colors_Pressed = Number_Of_Colors_Pressed + 1;//add that a color was selected to the counter
Record_Button_Human();
}
else{//if a button was not pressed then reads the buttons and ask to select a color
read_buttons();
LCD_Select_Colors();
}
if(Number_Of_Colors_Pressed == 4){//if four colors have been pressed then give a thank you message
LCD_Select_Colors_Thank_You();
}
printColorsValues();
printColorsOrder();
}
//Show the Mandrills the pattern
Reset_Button_Pushed();//if the reset button is pushed then the game will turn off
if(Number_Of_Colors_Pressed == 4 && Leds_Displayed_Count == 0){//so it doesnt flash if reset
LCD_Look_Up();//display look up
delay(2000);
Call_Mandrills();//will flash all of the lights so that the mandrills know it is starting
delay(700);
Flash_Mandrills();//flash the leds in order of colors selected for the mandrill
Leds_Displayed_Count = Leds_Displayed_Count + 1;
}
while(Number_Of_Colors_Pressed_Mandrill != 4 && Game_Start != 0)//not finished
{//is a copy and is not done, mainly need add the checking if the mandrills did it right
//so that the game can be reset while in this loop
read_buttons();
Reset_Button_Pushed();
LCD_Look_Up();//display look up
//Have the mandrills push the buttons and read if they entered the buttons right
if(buttonState_Mandrill_red == LOW || buttonState_Mandrill_yellow == LOW || buttonState_Mandrill_green == LOW || buttonState_Mandrill_blue == LOW){//if any Mandrill button is pressed then
Tell_Mandrills();
LCD_Select_Colors_Selected_Mandrill();//show that a color was selected by the mandrill
Number_Of_Colors_Pressed_Mandrill = Number_Of_Colors_Pressed_Mandrill + 1;//add that a color was selected to the counter
Record_Button_Mandrill();
}
else{//if a button was not pressed then reads the buttons and ask to select a color
read_buttons();
LCD_Look_Up();//display look up
}
if(Number_Of_Colors_Pressed_Mandrill == 4 /* and they did it correctly*/){//if four colors have been pressed then give a message that they did it
Mandrill_Correct_Order();
Correct_Order_Check_Serial();
if(Correct_Order_Check == 1){//if the mandrills got the correct order
LCD_They_Did_It_Correctly();
}
else if(Correct_Order_Check == 2){//if the mandrills put in the wrong order
LCD_They_Did_It_Wrong();
}
//LCD_Now_Dropping_Food(); Needs to be made
}//add else if that if 4 buttons were pushed but they did not do it correctly then say oh no and end
printColorsOrderMandrill();
}
//Turn off game if mandrills failed
Reset_Button_Pushed();
if (Number_Of_Colors_Pressed_Mandrill == 4 && Correct_Order_Check == 2){//if the order was wrong reset
reset_game();
}
//Continue Game if mandrills succeded
Reset_Button_Pushed();
if(Number_Of_Colors_Pressed_Mandrill == 4 && Correct_Order_Check == 1){//if the order was right
//comment instructions
//lcd says giving food to mandrills //
//the servo moves open the trap door and realeases the food //
//servo waits for 5 seconds //
//the servo closes the door //
//lcd says to watch the playground or feeding area //
//the ultra sound waits for 5 seconds //
//if the ultra sounds sees where the banana should be then it continues
//if the ultra sound never sees the banana or sees that it was taken then buzzer plays music and the lcd displays that they got the food
//say thank you for playing and then reset the game
//actual code
Drop_Food();//drop the food
record_distance_1();//record distance 1 as the current distance
while(distance_1 < distance + 5 && distance_1 > distance - 5)//while distance_1 is almost the same as distance (give or take 5cm)
{
find_distance();
Print_Distance();
Print_Distance_1();
delay(1000);
}
}
}
print_start();
}