Activity 4: Object Detection and Avoidance
An interesting thing about these IR detectors is that their outputs are just like the whiskers. When no object is detected, the output is high; when an object is detected, the output is low. In this activity, the example sketch RoamingWithWhiskers is modified so that it works with the IR detectors; all it takes is few simple modifications. Here are the steps:
- Save the sketch RoamingWithWhiskers as RoamingWithIr
- Add the irDetect function.
int irDetect(int irLedPin, int irReceiverPin, long frequency)
{
tone(irLedPin, frequency, 8);
delay(1);
int ir = digitalRead(irReceiverPin);
delay(1);
return ir;
}
- Replace these digitalRead calls:
byte wLeft = digitalRead(5); byte wRight = digitalRead(7);
…with these calls to irDetect:
int irLeft = irDetect(9, 10, 38000); int irRight = irDetect(2, 3, 38000);
- Replace all instances of wLeft with irLeft and wRight with irRight.
- Update the /*…*/ and // comments.
Example Sketch – RoamingWithIr
- Open RoamingWithWhiskers.
- Save it as RoamingWithIr.
- Modify it so that it matches the sketch below.
- Save it; then, upload it into the Arduino.
- Disconnect the BOE Shield-Bot from its programming cable.
- Reconnect the battery pack and move the 3-position switch to position 2.
- Place your BOE Shield-Bot somewhere where it can roam and avoid obstacles.
- Verify that it behaves like RoamingWithWhiskers (aside from the fact that there’s no contact required).
/*
* Robotics with the BOE Shield - RoamingWithIr
* Adaptation of RoamingWithWhiskers with IR object detection instead of
* contact switches.
*/
#include <Servo.h> // Include servo library
Servo servoLeft; // Declare left and right servos
Servo servoRight;
void setup() // Built-in initialization block
{
pinMode(10, INPUT); pinMode(9, OUTPUT); // Left IR LED & Receiver
pinMode(3, INPUT); pinMode(2, OUTPUT); // Right IR LED & Receiver
tone(4, 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, 38000); // Check for object on left
int irRight = irDetect(2, 3, 38000); // Check for object on right
if((irLeft == 0) && (irRight == 0)) // If both sides detect
{
backward(1000); // Back up 1 second
turnLeft(800); // Turn left about 120 degrees
}
else if(irLeft == 0) // If only left side detects
{
backward(1000); // Back up 1 second
turnRight(400); // Turn right about 60 degrees
}
else if(irRight == 0) // If only right side detects
{
backward(1000); // Back up 1 second
turnLeft(400); // Turn left about 60 degrees
}
else // Otherwise, no IR detected
{
forward(20); // Forward 1/50 of a second
}
}
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 forward(int time) // Forward function
{
servoLeft.writeMicroseconds(1700); // Left wheel counterclockwise
servoRight.writeMicroseconds(1300); // Right wheel clockwise
delay(time); // Maneuver for time ms
}
void turnLeft(int time) // Left turn function
{
servoLeft.writeMicroseconds(1300); // Left wheel clockwise
servoRight.writeMicroseconds(1300); // Right wheel clockwise
delay(time); // Maneuver for time ms
}
void turnRight(int time) // Right turn function
{
servoLeft.writeMicroseconds(1700); // Left wheel counterclockwise
servoRight.writeMicroseconds(1700); // Right wheel counterclockwise
delay(time); // Maneuver for time ms
}
void backward(int time) // Backward function
{
servoLeft.writeMicroseconds(1300); // Left wheel clockwise
servoRight.writeMicroseconds(1700); // Right wheel counterclockwise
delay(time); // Maneuver for time ms
}