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:
- Remove the Serial.print calls.
- Add servo code.
- Add the maneuver function.
- 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.