Permalink
Switch branches/tags
Nothing to show
Find file
ce3cfd3 Sep 24, 2014
173 lines (143 sloc) 4.99 KB
#include <Servo.h>
Servo leftWheel;
Servo rightWheel;
int leftWheelPin = 3; // These are digital PWM pins
int rightWheelPin = 11;
int mspeed = 200; // Variable that will be added to lspeed & rspeed to set a precise speed
int lspeed = 1530; // Signal sent that stops left motor
int rspeed = 1535; // Signal sent that stops right motor
// Signal of ~1300 turns motor clockwise at full speed
// Signal of ~ 1700 turns motor coutner-clockwise at full speed
int leftEyePin = A2;
int rightEyePin = A0;
int leftEyeVal;
int rightEyeVal;
int dist = 250; // Distance within which the robot will react, roughly 10cm
int leftGS = A5; // GS = Ground Sensor
int rightGS = A4;
int leftGSVal;
int rightGSVal;
int GSthresh; // Threshold used to detect if robot has moved from black surface to white
// This code assumes that a black surface provides a high signal.
void setup()
{
leftWheel.attach(leftWheelPin); // Initialise the servos
rightWheel.attach(rightWheelPin);
GSthresh=((analogRead(leftEyePin)+analogRead(rightEyePin))/2)-300; // Calculate the threshold for ground sensors
// This line takes the values seen in the two ground sensors. It assumes that the robot is starting on the black surface
// We get the average of the two values and reduce by 300.
// This value of 300 is ideal for ground sesnors that are 3mm above the ground. Smaller value will be needed if the sensors are higher than 3mm
// If either eye gives a signal that is 300 under the average value of black, we must be on white.
}
// Main Loop
void loop()
{
turnLeft(); // We start off initially by turning left to find the opponent
// Check the ground to see if we are at the edge of the ring
leftGSVal = analogRead(leftGS);
rightGSVal = analogRead(rightGS);
if(leftGSVal<GSthresh||rightGSVal<GSthresh) {survive();}
// Look for opponent
leftEyeVal = analogRead(leftEyePin);
rightEyeVal = analogRead(rightEyePin);
if(leftEyeVal>dist&&rightEyeVal>dist) {attack();} // If enemy is seen in both eyes
if(leftEyeVal>dist) {hunt(true);} // Seen in left eye
if(rightEyeVal>dist) {hunt(false);} // Seen in right eye
delay(20);
}
void hunt(boolean left) // Called when enemy is seen in just one eye.
// We must tell the function which eye the enemy was seen in
// This will only require a boolean
{
if(left==true) {turnLeft();}
else {turnRight();}
delay(20);
// Check the ground for the edge of the ring
leftGSVal = analogRead(leftGS); // Must make this check as often as possible
rightGSVal = analogRead(rightGS);
if(leftGSVal<GSthresh||rightGSVal<GSthresh) {survive();}
leftEyeVal = analogRead(leftEyePin); // This time we are calling the function recursivly,
rightEyeVal = analogRead(rightEyePin);
if(leftEyeVal>dist&&rightEyeVal>dist) {attack();} // If enemy is seen in both eyes
if(leftEyeVal>dist) {hunt(true);} // Seen in left eye
if(rightEyeVal>dist) {hunt(false);} // Seen in right eye
return;
}
void attack() // Called when enemy is seen in both eyes
{
while(leftEyeVal>dist&&rightEyeVal>dist) // We only continue driving forward so long as the opponent is seen in both eyes
{
driveForward();
delay(20);
leftGSVal = analogRead(leftGS); // Once again, keeping an eye on the edge of the ring
rightGSVal = analogRead(rightGS);
if(leftGSVal<GSthresh||rightGSVal<GSthresh) {survive();}
leftEyeVal = analogRead(leftEyePin);
rightEyeVal = analogRead(rightEyePin);
}
if(leftEyeVal>dist) {hunt(true);} // Seen in left eye
if(rightEyeVal>dist) {hunt(false);} // Seen in right eye
loop; // If we no longer see the opponent in either eye, return to the beginning of the function and begin searching from scratch
}
void survive() // Called when edge of ring is detected
{
stopWheels();
// If we see the edge of the ring in both eyes
// Reverse for 0.75 seconds and returns to main loop
if(leftGSVal<GSthresh&&rightGSVal<GSthresh)
{
driveBackward();
delay(750);
loop;
}
// If left side of robot is near the edge
// Turn left on the spot and reverse
if(leftGSVal<GSthresh)
{
turnLeft();
delay(175);
driveBackward();
delay(750);
loop; // This turns the robot a bit and then reverses
}
// If left side of robot is near the edge
if(rightGSVal<GSthresh)
{
turnRight();
delay(175);
driveBackward();
delay(750);
loop; // Same with this one
}
}
// Functions called to turn the wheels in a desired way
void turnLeft()
{
leftWheel.writeMicroseconds(lspeed-mspeed);
rightWheel.writeMicroseconds(rspeed-mspeed);
return;
}
void turnRight()
{
leftWheel.writeMicroseconds(lspeed+mspeed);
rightWheel.writeMicroseconds(rspeed+mspeed);
return;
}
void stopWheels()
{
leftWheel.writeMicroseconds(lspeed);
rightWheel.writeMicroseconds(rspeed);
return;
}
void driveForward()
{
leftWheel.writeMicroseconds(lspeed+mspeed);
rightWheel.writeMicroseconds(rspeed-mspeed);
return;
}
void driveBackward()
{
leftWheel.writeMicroseconds(lspeed-mspeed);
rightWheel.writeMicroseconds(rspeed+mspeed);
return;
}