Guard Dog and Mailman Scenario With Arduino

by laurenboyer in Circuits > Robots

1475 Views, 18 Favorites, 0 Comments

Guard Dog and Mailman Scenario With Arduino

Screen Shot 2014-12-14 at 8.27.53 PM.png
IMG_9472.JPG

The objective of this project is to program two robots to interact successfully with each other, acting out a guard dog-mailman scenario. The scenario being that the Guard Dog robot protects its house (aka light-source) from anything that comes within its range. If it senses an intruder, such as the Mailman, it will sound an alarm and attack the intruder until it feels like the area is safe again. At the same time, the Mailman robot acts as the intruder whose main objective is to reach the house/light source without being attacked by the Guard Dog.
Every time the guard dog comes near it, the mailman retreats, causing the guard dog to resume its patrol. In our previous labs, we saw how robots equipped with sensors could interact with, and adjust to, the external world. This was especially true in the Braitenberg vehicle lab where robots equipped with phototransistors interacted with light and also in the Maze labs where robots navigated their way past obstacles using infrared sensors. With these concepts in mind, we started this project with the goal of programming the robots to not only interact with each other, but to also interact with the world around them. We thought a scenario such as this one was interesting because, if refined and made more comprehensive, it could allow robots to be used as actual robotic guard dogs - possibly coupled with Boston Dynamics’ Big Dog design.

To solve this problem, we first have to create infrared and phototransistor circuits for our for our robots. The guard dog will only utilize the infrared circuit but also requires the ability to alert others of its detections through the use of LED’s and piezoelectric speakers, requiring circuits for these. The mailman will be set up similarly with the infrared sensors but will require phototransistors in order to detect the light source. This project require our robots to constantly detect their environments and then reacting to the changes going on around them. The reactions will first be in the form of sound and light, followed by reactions in the form of movement. We will use if, if else, and else statements, light and infrared detection code, and functions that we will create to perform specific tasks - such as guard dog functions to patrol its perimeter or attack the mailman when he is detected. We will be observing each robot reacts to its respective environments - with and without each other, and how each robot reacts to the other reacting to it. This is easily recorded through observation and note taking, from which results are easily displayed in our report.

Make Sure You've Got All the Necessary Materials

For the Guard Dog Robot you will need:

  • 1 Arduino Shield Bot
  • 4 LEDs
  • 2 infrared sensors + 2 receivers
  • 6 wires
  • 4 red-red-brown resistors
  • 2 red-black-red resistors
  • 1 piezoelectric speaker

For the Mailman Robot you will need:

  • 1 Arduino Shield Bots
  • 2 infrared sensors + 2 recievers
  • 2 phototransistors
  • 2 capacitors
  • 2 red-red-brown resistors
  • 2 red-black-red resistors
  • 2 brown-black red resistors
  • 6 wires
  • 1 piezoelectric speaker

Also, you will need a pretty strong light source. For our project, we used a desk lamp.

Set Up Guard Dog Circuit

IMG_9461.jpg
IMG_9462.jpg
IMG_9460.jpg

The Guard Dog and Mailman robots both have two different circuits for their two different purposes. Here's how we set up the Guard Dog's circuit!

Set Up the Mailman's Circuit

photo 2.JPG
photo 3.JPG
photo 4.JPG

Here's how we set up the mailman's circuit. Make sure each wire is in it's correct spot!

Programming

Guard Dog

For the Guard Dog robot, the code is programmed as an “if else” clause. In its dormant state, or in other words the “else” part of the clause, the robot is programmed to perform a “sway” function in which it scans from side to side. The sway function consists of the Arduino sending signals to the servos to turn to the left, delay for a bit, then turn to the right, delay for a bit, and repeat. If either of the infrared sensors detects something within a certain zone range, the robot will perform a type of alarm. The alarm contains a “for loop” as well as codes to trigger lights and sounds. The alarm starts by stopping the servos, then initiates the for loop. The loop triggers flashing of the 4 LED’s on the Arduino board according to how many flashes entered in the loop function, in this case we chose 20 flashes. The Arduino then proceeds to play a tone then drive forward play a second tone, then back away to its starting location. The basis of this program is that the guard dog is keeping watch over its territory, if it sees something then it alerts and “chases” the intruder away.

Code for Guard Dog:


#include // Include the Servo Library
Servo servoLeft; // Declare Left and Right Servos Servo servoRight;

void setup() // Initialization Code

{ pinMode(10, INPUT); // Set pins to input/output power

pinMode(9, OUTPUT);

pinMode(3, INPUT);

pinMode(2, OUTPUT);

pinMode(5, OUTPUT);

pinMode(6, OUTPUT);

tone(11, 3000, 1000); // Play tone for 1 second

delay(1000);

servoLeft.attach(13); // Attach left and right Servos to pins

servoRight.attach(12); }

void loop() // Main looping code

{ int irLeft = irDetect(9, 10, 39000); // Set left and right infrared sensors to detect for motion within certain zone range

int irRight = irDetect(2, 3, 39000);

if((irLeft == 0) || (irRight == 0)) // If the Left or Right infrared sensors detect something, perform the alarm function

{ alarm(20);

}

else // In all other cases, perform the "sway" function

{ sway(0); }

}

int irDetect(int irLedPin, int irReceiverPin, long frequency)

{ tone(irLedPin, frequency, 8); // IRLED 38 kHz for at least 1 ms

delay(1); // Wait 1 ms

int ir = digitalRead(irReceiverPin); // IR receiver -> ir variable

delay(1); // Down time before recheck

return ir; // Return 1 no detect, 0 detect }

void alarm(int flashes) // Alarm function

{ servoLeft.writeMicroseconds(1500); // Send stop signals to both Servos

servoRight.writeMicroseconds(1500);

for(int i=1; i<=flashes; i++) // Set up for the "for loop" function as the variable increases from 1 to the number of flashes declared

{ digitalWrite(5, HIGH); digitalWrite(6, HIGH); // Turn on the LED's at pins 5 and 6

delay(50); // Delay for 50 milliseconds

digitalWrite(5, LOW); // Turn off the LED's at pins 5 and 6

digitalWrite(6, LOW);

delay(50); // Delay for 50 milliseconds

} tone(11, 4000, 1000); // Play tone for 1 second

delay(1000);

forward(2000); // Go forward for 2 seconds

digitalWrite(5, HIGH);

digitalWrite(6, HIGH);// Turn on LED's at pins 5 and 6

tone(11, 2000, 1000); // Play tone for 1 second

delay(1000);

digitalWrite(5, LOW);

digitalWrite(6, LOW);

backward(2000); // Go backward for 2 seconds

}

void sway(int time) // Sway function

{ servoLeft.writeMicroseconds(1700); // Rotate Servos at full speed counter-clockwise servoRight.writeMicroseconds(1700);

delay(1000); // ... for 1 second

servoLeft.writeMicroseconds(1300); // Rotate Servos at full speed clockwise servoRight.writeMicroseconds(1300);

delay(1000); // ... for 1 second

}

void forward(int time) // Forward function

{ servoLeft.writeMicroseconds(1700); // Left Servo full-speed counter-clockwise servoRight.writeMicroseconds(1300); // Right Servo full-speed clockwise

delay(time); // Delay for declared time value

}

void backward(int time) // Backward function

{ servoLeft.writeMicroseconds(1300); // Left Servo full-speed clockwise

servoRight.writeMicroseconds(1700); // Right Servo full-speed counter-clockwise

delay(time); // Delay for declared time value

}

Mailman

For the Mailman robot, the code is programmed as an “if else” clause as well. The main function is that through the phototransistors, the Mail Man robot will trend toward the light source. If the Mailman detects something through its infrared sensors on either side, then the Mailman will let out a certain tone signaling that it realizes that it has attracted the attention of the Guard Dog. Then, the Mailman will backup to get away from the dog since it will be coming toward the robot. The basis of this part of the code is that the Mailman wants to get to the light source; however, if it sees the dog, then it knows that the task cannot be accomplished.

Code for Mailman Robot:



#include // Include servo library
Servo servoLeft; // Declare left and right servos Servo servoRight;

void setup() // Built-in initialization block { pinMode(10, INPUT); // Set pins to input/output power pinMode(9, OUTPUT); pinMode(3, OUTPUT); pinMode(2, OUTPUT); pinMode(5, INPUT); pinMode(12, OUTPUT); tone(11, 3000, 1000); // Play tone for 1 second delay(1000); // Delay to finish tone servoLeft.attach(13); // Attach left signal to pin 13 servoRight.attach(12); // Attach right signal to pin 12 } void loop() // Main loop auto-repeats { int irLeft = irDetect(9, 10, 39000); // Set left and right infrared sensors to detect for motion within certain zone range int irRight = irDetect(2, 3, 39000); float tLeft = float(rcTime(12)); // Get left light & make float float tRight = float(rcTime(2)); // Get right light & make float float ndShade; // Normalized differential shade ndShade = tRight / (tLeft+tRight) - 0.5; // Calculate it and subtract 0.5 int speedLeft, speedRight; // Declare speed variables if((irLeft == 0) || (irRight == 0)) // If the Left or Right infrared sensors detect something, perform the alarm function { backward(2000); } else if (ndShade > 0.0) // Shade on right? { // Slow down left wheel speedLeft = int(200.0 - (ndShade * 1300.0)); speedLeft = constrain(speedLeft, -200, 200); speedRight = 200; // Full speed right wheel } else if (ndShade < 0.0) // Shade on Left? { // Slow down right wheel speedRight = int(200.0 + (ndShade * 1300.0)); speedRight = constrain(speedRight, -200, 200); speedLeft = 200; // Full speed left wheel } else { } maneuver(speedLeft, speedRight, 20); // Set wheel speeds }

long rcTime(int pin) // rcTime measures decay at pin { pinMode(pin, OUTPUT); // Charge capacitor digitalWrite(pin, HIGH); // ..by setting pin ouput-high delay(5); // ..for 5 ms pinMode(pin, INPUT); // Set pin to input digitalWrite(pin, LOW); // ..with no pullup long time = micros(); // Mark the time while(digitalRead(pin)); // Wait for voltage < threshold time = micros() - time; // Calculate decay time return time; // Returns decay time }

int irDetect(int irLedPin, int irReceiverPin, long frequency) { tone(irLedPin, frequency, 8); // IRLED 38 kHz for at least 1 ms delay(1); // Wait 1 ms int ir = digitalRead(irReceiverPin); // IR receiver -> ir variable delay(1); // Down time before recheck return ir; // Return 1 no detect, 0 detect }

// maneuver function void maneuver(int speedLeft, int speedRight, int msTime) { servoLeft.writeMicroseconds(1500 + speedLeft); // Set Left servo speed servoRight.writeMicroseconds(1500 - speedRight); // Set right servo speed if(msTime==-1) // if msTime = -1 { servoLeft.detach(); // Stop servo signals servoRight.detach(); } delay(msTime); // Delay for msTime }

void backward(int time) // Backward function { servoLeft.writeMicroseconds(1300); // Left Servo full-speed clockwise servoRight.writeMicroseconds(1700); // Right Servo full-speed counter-clockwise delay(time); // Delay for declared time value }

void forward (int time) { servoLeft.writeMicroseconds (1700); servoRight.writeMicroseconds (1300); delay(time); }