Activity 5: Shield-Bot Navigating by Light

At this point, the LightSeekingDisplay sketch needs four things to take it from displaying what it’s going to do to actually doing it:

  1. Remove the Serial.print calls.
  2. Add servo code.
  3. Add the maneuver function.
  4. Add a call to the loop function to pass speedLeft and speedRight to the maneuver function. 

The result is the LightSeekingShieldBot sketch.

  • Enter, save, and upload LightSeekingShieldBot to your Arduino.
  • Connect the battery pack, put the BOE Shield-Bot on the floor, and set the power switch to 2.
  • Let the BOE Shield-Bot roam and try casting shadows over its left and right light sensors.  It should turn away from the shadow.
/*
 * Robotics with the BOE Shield - LightSeekingShieldBot
 * Roams toward light and away from shade.
 */

#include <Servo.h>                           // Include servo library
 
Servo servoLeft;                             // Declare left and right servos
Servo servoRight;

void setup()                                 // Built-in initialization block
{
  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
{
  float tLeft = float(rcTime(8));            // Get left light & make float
  float tRight = float(rcTime(6));           // 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 (ndShade > 0.0)                         // Shade on right?
  {                                          // Slow down left wheel
    speedLeft = int(200.0 - (ndShade * 1000.0));
    speedLeft = constrain(speedLeft, -200, 200);
    speedRight = 200;                        // Full speed right wheel
  }
  else                                       // Shade on Left?
  {                                          // Slow down right wheel
    speedRight = int(200.0 + (ndShade * 1000.0));
    speedRight = constrain(speedRight, -200, 200);
    speedLeft = 200;                         // Full speed left wheel
  }  

  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
}

// 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
}

Your Turn – Light/Shade Sensitivity Adjustments

If you want more sensitivity to light, change 1000 to a larger value in these two commands:

    speedLeft = int(200.0 - (ndShade * 1000.0));
    speedRight = int(200.0 + (ndShade * 1000.0));

Want less light sensitivity?  Change 1000 to a smaller value.

  • Try it.

Here are several more light-sensing navigation ideas for your BOE Shield-Bot that can be made with adjustments to the loop function:

  • To make your BOE Shield-Bot follow shade instead of light, place ndShade = -ndShade right before the if…else statement. Curious about how or why this works? Check out Project 2 at the end of this chapter.
  • End roaming under a bright light or in a dark cubby by detecting very bright or very dark conditions.  Add tLeft and tRight together, and compare the result to either a really high (dark) threshold value or a really low (bright) threshold value.
  • Make your BOE Shield-Bot function as a light compass by remaining stationary and turning toward bright light sources.
  • Incorporate whiskers into the roaming toward light activity so that the BOE Shield-Bot can detect and navigate around objects in its way.