You are on page 1of 9

Chapter 5 Challenges

Questions
1. What kind of electrical connection is a whisker?
A single-pole, single-throw tactile switch.
2. When a whisker is pressed, what voltage occurs at the I/O pin
monitoring it? What binary value will the digitalRead function return? If
digital pin 8 is used to monitor the whisker circuit, what value
does digitalRead return when a whisker is pressed, and what value does it
return when a whisker is not pressed?
Zero volts, resulting in binary zero (0) returned by digitalRead.
digitalRead(8) == 0 when whisker is pressed.
digitalRead(8) == 1 when whisker is not pressed.

3. If digitalRead(7)== 1, what does that mean? What does it mean


if digitalRead(7)== 0? How about digitalRead(5)==
1 and digitalRead(5)== 0?
digitalRead(7)== 1 means the right whisker is not pressed.
digitalRead(7)== 0 means the right whisker is pressed.
digitalRead(5)== 1 means the left whisker is not pressed.
digitalRead(5)== 0 means the left whisker is pressed.
4. What statements did this chapter use to call different navigation
functions based on whisker states?
This chapter used if, ifelse, and ifelse ifelse statements
5. What is the purpose of having nested if statements?
If one condition turns out to be true, the code might need to analyze another
condition with a nested if statement.
Exercises
1. Write a routine that uses a single variable named whiskers to track
whisker contacts. It should store a 3 when no whiskers are contacted, a 2 if
the right whisker is contacted, a 1 if the left whisker is contacted, or 0 if both
whiskers are contacted. Hint: multiply the result by two.
// Robotics with the BOE Shield Chapter 5, Exercise 1
// Value from 0 to 3 indicates whisker states:
// 0 = both, 1 = left, 2 = right, 3 = neither.
void setup() // Built-in initialization block
{
tone(4, 3000, 1000); // Play tone for 1 second
delay(1000); // Delay to finish tone

pinMode(7, INPUT); // Set right whisker pin to input


pinMode(5, INPUT); // Set left whisker pin to input

Serial.begin(9600); // Set data rate to 9600 bps


}

void loop() // Main loop auto-repeats


{
byte whiskers = 2 * digitalRead(5);
whiskers += digitalRead(7);

Serial.println(whiskers); // Display wLeft

delay(50); // Pause for 50 ms


}

2. Modify the loop function in RoamingWithWhiskers so that it makes the


BOE Shield-Bot stop and not restart when both whiskers contact at the same
time.
void loop() // Main loop auto-repeats
{
byte wLeft = digitalRead(5); // Copy right result to wLeft
byte wRight = digitalRead(7); // Copy left result to wRight

if((wLeft == 0) && (wRight == 0)) // If both whiskers contact


{
pause(500); // Pause motion for 0.5 seconds
backward(1000); // Back up 1 second
turnLeft(800); // Turn left about 120 degrees
}
else if(wLeft == 0) // If only left whisker contact
{
pause(500); // Pause motion for 0.5 seconds
backward(1000); // Back up 1 second
turnRight(400); // Turn right about 60 degrees
}
else if(wRight == 0) // If only right whisker contact
{
pause(500); // Pause motion for 0.5 seconds
backward(1000); // Back up 1 second
turnLeft(400); // Turn left about 60 degrees
}
else // Otherwise, no whisker contact
{
forward(20); // Forward 1/50 of a second
}
}

3. Add a function named pause to RoamingWithWhiskers. It should make


the BOE Shield-Bot stay still for a certain amount of time.
void pause(int time) // Pause drive wheels
{
servoLeft.writeMicroseconds(1500); // Left wheel stay still
servoRight.writeMicroseconds(1500); // Right wheel stay still
delay(time); // Maneuver for time ms
}

4. Modify the loop function so that the BOE Shield-Bot stays still for 0.5
seconds before backing up and turning.
void loop() // Main loop auto-repeats
{
byte wLeft = digitalRead(5); // Copy right result to wLeft
byte wRight = digitalRead(7); // Copy left result to wRight

if((wLeft == 0) && (wRight == 0)) // If both whiskers contact


{
pause(500); // Pause motion for 0.5 seconds
backward(1000); // Back up 1 second
turnLeft(800); // Turn left about 120 degrees
}
else if(wLeft == 0) // If only left whisker contact
{
pause(500); // Pause motion for 0.5 seconds
backward(1000); // Back up 1 second
turnRight(400); // Turn right about 60 degrees
}
else if(wRight == 0) // If only right whisker contact
{
pause(500); // Pause motion for 0.5 seconds
backward(1000); // Back up 1 second
turnLeft(400); // Turn left about 60 degrees
}
else // Otherwise, no whisker contact
{
forward(20); // Forward 1/50 of a second
}
}
Projects
1. Modify RoamingWithWhiskers so that the BOE Shield-Bot stops and
makes a 4 kHz beep that lasts 100 ms before executing its usual evasive
maneuver. Make it beep twice if both whisker contacts are detected during
the same sample. HINT: Use the pause function you developed in the
Exercises section to make it pause immediately after the tone starts playing.
Also, a 0.2 second pause after the tone call separates the 0.1 second tone
from servo motion, or allows you to hear a second tone.
/ RoamingWithWhiskers Chapter 5 Project 1
// Go forward. Back up and turn if whiskers indicate BOE Shield bot
// bumped into something.

#include <Servo.h> // Include servo library

Servo servoLeft; // Declare left and right servos


Servo servoRight;

void setup() // Built-in initialization block


{
pinMode(7, INPUT); // Set right whisker pin to input
pinMode(5, INPUT); // Set left whisker pin to input

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


{
byte wLeft = digitalRead(5); // Copy right result to wLeft
byte wRight = digitalRead(7); // Copy left result to wRight

if((wLeft == 0) && (wRight == 0)) // If both whiskers contact


{
tone(4, 4000, 100); // Play a 0.1 ms tone
pause(200); // Stop for 0.2 seconds
tone(4, 4000, 100); // Play a 0.1 ms tone
pause(200); // Stop for 0.2 seconds
backward(1000); // Back up 1 second
turnLeft(800); // Turn left about 120 degrees
}
else if(wLeft == 0) // If only left whisker contact
{
tone(4, 4000, 100); // Play a 0.1 ms tone
pause(200); // Stop for 0.2 seconds
backward(1000); // Back up 1 second
turnRight(400); // Turn right about 60 degrees
}
else if(wRight == 0) // If only right whisker contact
{
tone(4, 4000, 100); // Play a 0.1 ms tone
pause(200); // Stop for 0.2 seconds
backward(1000); // Back up 1 second
turnLeft(400); // Turn left about 60 degrees
}
else // Otherwise, no whisker contact
{
forward(20); // Forward 1/50 of a second
}
}

void pause(int time) // Backward function


{
servoLeft.writeMicroseconds(1500); // Left wheel clockwise
servoRight.writeMicroseconds(1500); // Right wheel counterclockwise
delay(time); // Maneuver for time ms
}
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
}

2. Modify RoamingWithWhiskers so that the BOE Shield-Bot roams in a 1


yard (or 1 meter) diameter circle. When you touch one whisker, it will cause
the BOE Shield-Bot to travel in a tighter circle (smaller diameter). When you
touch the other whisker, it will cause the BOE Shield-Bot to navigate in a
wider diameter circle.
// Robotics with the BOE Shield - Chapter 5, project 2 WhiskerCircle
// BOE Shield-Bot navigates a circle of 1 yard diameter.
// Tightens turn if right whisker pressed, or reduces turn if left whisker
// is pressed.

#include <Servo.h> // Include servo library

Servo servoLeft; // Declare left and right servos


Servo servoRight;

int turn;

void setup() // Built-in initialization block


{
pinMode(7, INPUT); // Set right whisker pin to input
pinMode(5, INPUT); // Set left whisker pin to input

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


delay(1000); // Delay to finish tone

servoLeft.attach(13); // Attach left signal to Port 13


servoRight.attach(12); // Attach right signal to Port 12

turn = 0;

// servoLeft.detach(); // Stop sending servo signals


// servoRight.detach();
}

void loop() // Main loop auto-repeats


{ // Nothing needs repeating
int wLeft = digitalRead(5);
int wRight = digitalRead(7);

if(wLeft == 0)
{
turn -= 10;
}
else if(wRight == 0)
{
turn += 10;
}

// Arc to the right


servoLeft.writeMicroseconds(1600); // Left wheel counterclockwise
servoRight.writeMicroseconds(1438 + turn); // Right wheel clockwise slower
delay(50); // ...for 25.5 seconds
}