We had an assignment to make a rock, paper, scissors game with the RGB LED.
R beats G
G beats B
B beats R
We were to use Serial communication to play with another person in class
I played with Laura so that we could test the entire communication protocol.
I had one bug that gave me a lot of problems which was that I was not delaying long
enough when trying to receive more than one character in a row as in "GGG"
I was not giving the buffer long enough to actually receive all of the data
Here is a schematic of my arduino board for this project (These are the exact pin #'s used)
And here is my code. I used a header file to organize my code and so that I could use enumerations which seem to have a slight problem in Arduino:
//functions.h
#include "Arduino.h"
HardwareSerial& s = Serial1;
const byte R_rock = 10;
const byte G_paper = 8;
const byte B_scissors = 9;
const byte R_stat = 7;
const byte G_stat = 6;
const byte B_stat = 5;
const byte pot_pin = A8;
int pot_val = 0;
const byte switch_pin = 2;
int prev_switch_val = 0;
int switch_val = 0;
int R_val = 0;
int G_val = 0;
int B_val = 0;
int R_stat_val = 0;
int G_stat_val = 0;
int B_stat_val = 0;
int state = 0;
enum Color{ RED, GREEN, BLUE };
Color my_choice = RED;
Color opponent_choice = RED;
void set_rps_color()
{
pot_val = analogRead(pot_pin); // read the potentiometer to determine color choice
if(pot_val < 413)
{
R_val = 255;
G_val = 0;
B_val = 0;
}
else if(pot_val < 827)
{
R_val = 0;
G_val = 255;
B_val = 0;
}
else
{
R_val = 0;
G_val = 0;
B_val = 255;
}
}
//be careful with this...not listening to this all the time...
boolean switch_pressed()
{
prev_switch_val = switch_val;
switch_val = digitalRead(switch_pin);
//Serial.print(prev_switch_val);Serial.print(" ");
//Serial.println(switch_val);
if(prev_switch_val==0 && switch_val==1)
{
return true;
}
return false;
}
int determine_winner(enum Color me,enum Color opponent)
{
int test = (3+((int)me-(int)opponent))%3;
if(test == 2)
{
//I win
R_stat_val = 0;
G_stat_val = 255;
B_stat_val = 0;
}
else if(test == 1)
{
//They win
R_stat_val = 255;
G_stat_val = 0;
B_stat_val = 0;
}
else if(test == 0)
{
//tie
R_stat_val = 175;
G_stat_val = 255;
B_stat_val = 0;
}
return test;
}
int get_opponent()
{
//need to read 3 times and construct a string?
if(s.available() > 0)
{
char incomingByte = s.read();
if(incomingByte == 'R') opponent_choice = RED;
else if(incomingByte == 'G') opponent_choice = GREEN;
else if(incomingByte == 'B') opponent_choice = BLUE;
else return -1;
}
else
{
return -1;
}
return int(opponent_choice);
}
int send_choice()
{
if(R_val == 255) {s.write("R"); my_choice = RED; return 0;}
else if(G_val == 255) {s.write("G"); my_choice = GREEN; return 1;}
else if(B_val == 255) {s.write("B"); my_choice = BLUE; return 2;}
else return -1;
}
void set_stat_color(int R, int G, int B)
{
R_stat_val = R;
G_stat_val = G;
B_stat_val = B;
}
//
// i is 1 for the first reset => send ZZZ
// i is 2 for the second reset => send XXX
//
int send_reset(int i)
{
if(i==1) {s.write("ZZZ"); }
else if(i==2) {s.write("XXX");}
else return -1;
}
//
// i is 1 for the first reset => listening for ZZZ
// i is 2 for the second reset => listening for XXX
//
bool listen_for_reset(int i)
{
String inData = " ";
int index = 0;
char inChar;
if(i==1)
{
//Serial.println("Wont work without this print for some weird crazy reason");
while(s.available() > 0)
{
//Serial.println("Serial data available");
inChar = s.read();
if(index < 3)
{
inData[index]=inChar;
index++;
}
delay(10);
}
//inData.trim();
if(inData == "ZZZ" || inData == "zzz")
{
return true;
}
}
else if(i==2)
{
//Serial.println("Wont work without this print for some weird crazy reason");
while(s.available() > 0)
{
inChar = s.read();
if(index < 3)
{
inData[index]=inChar;
index++;
}
delay(10);
}
//inData.trim();
if(inData == "XXX" || inData == "xxx")
{
return true;
}
}
return false;
}
//main file
#include "functions.h"
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(R_rock, OUTPUT);
pinMode(G_paper, OUTPUT);
pinMode(B_scissors, OUTPUT);
pinMode(R_stat, OUTPUT);
pinMode(G_stat, OUTPUT);
pinMode(B_stat, OUTPUT);
pinMode(pot_pin, INPUT);
pinMode(switch_pin, INPUT);
s.begin(9600);
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
switch (state){
case 0:
//Waiting for someone to press "reset"
if(switch_pressed())
{
send_reset(1); //send the first reset signal
set_stat_color(0,0,255); //set status to blue
state ++; //advance state to wait for opponent
break;
}
else if(listen_for_reset(1))
{ //opponent pressed reset
set_stat_color(0,0,255); //set status color to blue
state+=2; //advance state to wait for me to press reset
break;
}
break;
case 1:
//waiting for opponent to press reset
if(listen_for_reset(1))
{
set_stat_color(155,0,255);//set status color to magenta
state+=2;//advance state to choose color
break;
}
break;
case 2:
//waiting for me to press reset
if(switch_pressed())
{
send_reset(1);//send the first reset signal
set_stat_color(155,0,255);
state++; //advance state to choose color
break;
}
break;
case 3:
//Allow our player to select color
set_rps_color(); //can change color as much as we want
if(switch_pressed()) //when done press switch
{
send_choice();
set_stat_color(155,255,255);//set stat color to signify I have chosen
state++;//advance state to wait on opponent
break;
}
if(get_opponent()>=0)//also listen for opponent choice
{
set_stat_color(0,255,255);//set stat color to signal opp chose and is waiting on me
state+=2;//advance state for opp to wait on me
break;
}
break;
case 4:
//Serial.println("In case 4");
//Wait for other player to select color
if(get_opponent()>=0)
{
set_stat_color(0,255,255); //set stat color
state+=2; //advance state to determine winner
}
break;
case 5:
//Opponent is waiting on me to choose
set_rps_color(); //can change color as much as we want
if(switch_pressed())
{
send_choice();
set_stat_color(155,255,255);//set stat color to signify I have chosen
state++; //advance state to determine winner
}
break;
case 6:
//determine winner
determine_winner(my_choice,opponent_choice); //This sets the stat light color
state++; //advance state to wait for reset
break;
case 7:
//Either opponent or I must press reset to start over
if( switch_pressed() || listen_for_reset(2))
{
send_reset(2); //send the second reset
//Clean up
R_stat_val = 0;
G_stat_val = 0;
B_stat_val = 0;
R_val = 0;
G_val = 0;
B_val = 0;
//Start back at case 0
state = 0;
}
}
analogWrite(R_rock,R_val);
analogWrite(G_paper,G_val);
analogWrite(B_scissors,B_val);
analogWrite(R_stat,R_stat_val);
analogWrite(G_stat,G_stat_val);
analogWrite(B_stat,B_stat_val);
}
No comments:
Post a Comment