Skip to content
Parallax Learn

Parallax Learn

  • Welcome
  • Tutorials
        • Tutorial Series head tag

          Tutorial Series
        • Tutorial Series

          The special, classroom-ready series pages are organized collections of tutorials for our most popular hardware and/or languages. The tutorials for each topic are conveniently accessible from a single page, shown in the order it is recommended that they be completed.
        • Robotics Series Head tag

          Robotics Series
        • Robotics Series

          • Artificial Intelligence
          • Cybersecurity: Radio Data tutorialCybersecurity
          • cyber:bot + Python
          • cyber:bot + MakeCode
          • Boe-Bot Tutorial SeriesBoe-Bot
          • Arduino Shield-Bot
          • ActivityBot with C TutorialsActivityBot + C
          • ActivityBot with BlocklyProp Tutorial SeriesActivityBot + BlocklyProp
          • Scribbler 3 Tutorial SeriesScribbler 3
        • Electronics & Programming Series Head tag

          Electronics & Programming Series
          • BS2 Board of Education Tutorial SeriesBS2 Board of Education
          • Propeller C-Language BasicsPropeller C Basics
          • FLiP Try-It Kit C Tutorial SeriesFLiP Try-It Kit + C
          • FLiP Try-It Kit BlocklyProp TutorialsFLiP Try-It Kit + BlocklyProp
          • Badge WX Tutorial SeriesBadge WX
          • Propeller BlocklyProp Basics and ProjectsPropeller BlocklyProp Basics
          • View All Tutorial Series »
        • Browse Tutorials
        • Browse Tutorials

          Individual tutorials sorted by robot or kit, and language.
        • By Robot or Kit
          • ActivityBot
          • SumoBot WX
          • Boe-Bot
          • Shield-Bot
          • cyber:bot
          • Badge WX
          • ELEV-8
          • ARLO
        • By Language
        • By Language

          • Propeller C
          • Arduino
          • BlocklyProp
          • PBASIC
          • Python
          • MakeCode
          • View All Tutorials »
  • Educators
  • Reference
  • Downloads
  • Home
  • All Courses

Robotics with the Board of Education Shield for Arduino

Curriculum

  • 9 Sections
  • 148 Lessons
  • Lifetime
Expand all sectionsCollapse all sections
  • About This Tutorial
    3
    • 2.0
      About the BOE Shield-Bot
    • 2.1
      Audience and Support
    • 2.2
      Author & Contributors
  • Chapter 1. Your Shield-Bot's Brain
    25
    • 3.1
      Chapter 1. Your Shield-Bot’s Brain
    • 3.2
      Hardware and Software Options
    • 3.3
      Shield-Bot Chassis Parts
    • 3.4
      Shield-Bot Hardware
    • 3.5
      Shield-Bot Electronics Parts
    • 3.6
      Activity 1: Download and Install the Software
    • 3.7
      Activity 2: Write a Simple “Hello!” Sketch
    • 3.8
      Codebender Hello Sketch
    • 3.9
      How the Hello Sketch Code Works
    • 3.10
      Modify the Sketch to Repeat
    • 3.11
      Hello Messages on New Lines
    • 3.12
      Open the Arduino Reference
    • 3.13
      Activity 3: Store and Retrieve Values
    • 3.14
      Global vs.Local Variables
    • 3.15
      Activity 4: Solve Math Problems
    • 3.16
      Try Floating Point Math
    • 3.17
      Activity 5: Make Decisions
    • 3.18
      More Decisions with if… else if
    • 3.19
      Activity 6: Count and Control Repetitions
    • 3.20
      How the for Loop Works
    • 3.21
      Adjust Initialization, Condition, and Increment
    • 3.22
      Activity 7: Constants and Comments
    • 3.23
      Chapter 1 Summary
    • 3.24
      Chapter 1 Challenges
    • 3.25
      Chapter 1 Solutions
  • Chapter 2. Shield, Lights, Servo Motors
    23
    • 4.0
      Chapter 2. Shield, Lights, Servo Motors
    • 4.1
      Activity 1: Board of Education Shield Setup
    • 4.2
      Activity 2: Build and Test LED Indicator Lights
    • 4.3
      Introducing the Resistor
    • 4.4
      Introducing the LED
    • 4.5
      Introducing the Prototyping Area
    • 4.6
      LED Test Circuit
    • 4.7
      How a Sketch Makes the LED Turn On and Off
    • 4.8
      Introducing the Timing Diagram
    • 4.9
      Activity 3: LED Servo Signal Monitors
    • 4.10
      How to Use the Arduino Servo Library
    • 4.11
      Activity 4: Connect Servo Motors and Batteries
    • 4.12
      Connect the Servos to the BOE Shield
    • 4.13
      Connect the Battery Pack to the BOE Shield
    • 4.14
      5-cell Pack Setup
    • 4.15
      4-cell Pack + Boe-Boost Setup
    • 4.16
      Activity 5: Centering the Servos
    • 4.17
      Activity 6: Testing the Servos
    • 4.18
      Controlling Servo Speed and Direction
    • 4.19
      How To Control Servo Run Time
    • 4.20
      Chapter 2 Summary
    • 4.21
      Chapter 2 Challenges
    • 4.22
      Chapter 2 Solutions
  • Chapter 3. Assemble and Test your BOE Shield-Bot
    22
    • 5.0
      Chapter 3. Assemble and Test your BOE Shield-Bot
    • 5.1
      Activity 1: Assembling the BOE-Shield-Bot
    • 5.2
      Mount the Topside Hardware
    • 5.3
      Remove the Servo Horns
    • 5.4
      Mount the Servos on the Chassis
    • 5.5
      Mount the Battery Pack
    • 5.6
      Mount the Wheels
    • 5.7
      Attach the BOE Shield to the Chassis
    • 5.8
      Activity 2: Re-test the Servos
    • 5.9
      Testing the Left and Right Wheels
    • 5.10
      Servo Troubleshooting
    • 5.11
      Activity 3: Start-Reset Indicator
    • 5.12
      Build the Piezospeaker Circuit
    • 5.13
      Programming the Start-Reset Indicator
    • 5.14
      Example Sketch: StartResetIndicator
    • 5.15
      Activity 4: Test Speed Control
    • 5.16
      Example Sketch: Test Servo Speed
    • 5.17
      How TestServoSpeed Works
    • 5.18
      Optional: Record Your Own Transfer Curve Data
    • 5.19
      Chapter 3 Summary
    • 5.20
      Chapter 3 Challenges
    • 5.21
      Chapter 3 Solutions
  • Chapter 4. BOE Shield-Bot Navigation
    19
    • 6.0
      Chapter 4. BOE Shield-Bot Navigation
    • 6.1
      Activity 1: Basic BOE Shield-Bot Maneuvers
    • 6.2
      How ForwardThreeSeconds Works
    • 6.3
      Moving Backward, Rotating, and Pivoting
    • 6.4
      Activity 2: Tuning the Basic Maneuvers
    • 6.5
      Tuning the Turns
    • 6.6
      Activity 3: Calculating Distances
    • 6.7
      Activity 4: Ramping Maneuvers
    • 6.8
      Activity 5: Simplify Navigation with Functions
    • 6.9
      Function Call with Parameters
    • 6.10
      Put Maneuvers Into Functions
    • 6.11
      Activity 6: Custom Maneuver Function
    • 6.12
      Activity 7: Maneuver Sequences with Arrays
    • 6.13
      Using Array Elements
    • 6.14
      Navigation with Arrays
    • 6.15
      Character Arrays and switch-case
    • 6.16
      Chapter 4 Summary
    • 6.17
      Chapter 4 Challenges
    • 6.18
      Chapter 4 Solutions
  • Chapter 5. Tactile Navigation with Whiskers
    13
    • 7.0
      Chapter 5. Tactile Navigation with Whiskers
    • 7.1
      Activity 1: Build and Test the Whiskers
    • 7.2
      How Whisker Switches Work
    • 7.3
      Testing the Whiskers
    • 7.4
      How DisplayWhiskerStates Works
    • 7.5
      Activity 2: Field-Test the Whiskers
    • 7.6
      Activity 3: Navigation with Whiskers
    • 7.7
      How RoamingWithWhiskers Works
    • 7.8
      Activity 4: Artificial Intelligence for Escaping Corners
    • 7.9
      How Escaping Corners Works
    • 7.10
      Chapter 5 Summary
    • 7.11
      Chapter 5 Challenges
    • 7.12
      Chapter 5 Solutions
  • Chapter 6. Light-Sensitive Navigation with Phototransistors
    18
    • 8.0
      Chapter 6. Light-Sensitive Navigation with Phototransistors
    • 8.1
      Introducing the Phototransistor
    • 8.2
      Activity 1: Simple Light to Voltage Sensor
    • 8.3
      Example Sketch: PhototransistorVoltage
    • 8.4
      Halt Under the Bright Light
    • 8.5
      How the Phototransistor Circuit Works
    • 8.6
      Ohm’s Law
    • 8.7
      Activity 2: Measure Light Levels Over a Larger Range
    • 8.8
      Building the Photosensitive Eyes
    • 8.9
      Test the Phototransistor Circuit
    • 8.10
      rcTime and Voltage Decay
    • 8.11
      Activity 3: Light Measurements for Roaming
    • 8.12
      Light Measurement Graphic Display
    • 8.13
      Activity 4: Test a Light-Roaming Routine
    • 8.14
      Activity 5: Shield-Bot Navigating by Light
    • 8.15
      Chapter 6 Summary
    • 8.16
      Chapter 6 Challenges
    • 8.17
      Chapter 6 Solutions
  • Chapter 7. Navigating with Infrared Headlights
    14
    • 9.0
      Chapter 7. Navigating with Infrared Headlights
    • 9.1
      Infrared Light Signals
    • 9.2
      Activity 1: Build and Test the Object Detectors
    • 9.3
      Object Detection Test Code
    • 9.4
      Activity 2: Field Testing
    • 9.5
      Sniffing for IR Interference
    • 9.6
      Activty 3: Detection Range Adjustments
    • 9.7
      Activity 4: Object Detection and Avoidance
    • 9.8
      Activity 5: High-performance IR Navigation
    • 9.9
      Activity 6: Drop-off Detector
    • 9.10
      Example Sketch: AvoidTableEdge
    • 9.11
      Chapter 7 Summary
    • 9.12
      Chapter 7 Challenges
    • 9.13
      Chapter 7 Solutions
  • Chapter 8. Robot Control with Distance Detection
    11
    • 10.0
      Chapter 8. Robot Control with Distance Detection
    • 10.1
      Activity 1: Testing the Frequency Sweep
    • 10.2
      Displaying Both Distances
    • 10.3
      Activity 2: BOE Shield-Bot Shadow Vehicle
    • 10.4
      A Look Inside Proportional Control
    • 10.5
      Example Sketch: FollowingShieldBot
    • 10.6
      Follow the Leader
    • 10.7
      Activity 3: What’s Next?
    • 10.8
      Chapter 8 Summary
    • 10.9
      Chapter 8 Challenges
    • 10.10
      Chapter 8 Solutions

Activity 4: Test a Light-Roaming Routine

One approach toward making the Boe-Bot roam toward light sources is to make it turn away from shade.  You can use the ndShade variable to make the BOE Shield-Bot turn a little or a lot when the contrast between the light detected on each side is a little or a lot. 

Shady Navigation Decisions

Here is an if statement that works well for turning away from shade on the right side of the BOE Shield-Bot.  It starts by declaring two int variables, speedLeft and speedRight.  They are not declared within the if…else block because other blocks in the loop function will need to check their values too.  Next, if(ndShade > 0.0) has a code block that will be executed if shade is detected on the robot’s right side, slowing down the left wheel to make the BOE Shield-Bot turn away from the dark.  To do this, ndShade * 1000.0 is subtracted from 200.  Before assigning the result to speedLeft, int(200.0–(ndShade×1000.0) converts the answer from a floating point value back to an integer.  We’re doing this to make the value compatible with the maneuver function from Chapter 4, which needs an int value.

  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
  }

This diagram shows an example of how this works when ndShade is 0.125.  The left wheel slows down because 200 – (0.125×1000) = 75.  Since linear speed control is in the 100 to –100 range, it puts the wheel at about ¾ of full speed.  Meanwhile, on the other side, speedRight is set to 200 for full speed forward.

The larger ndShade is, the more it subtracts from 200. That’s not a problem in this example, but if ndShade were 0.45, it would try to store –250 in the speedLeft variable.  Since the speeds we’ll want to pass to the maneuver function need to be in the -200 to 200 range, we’ll use the Arduino’s constrain function to prevent speedLeft from going out of bounds:  speedLeft = constrain(speedLeft, –200, 200).

Here is an else statement that works well for turning away from shade on the left.  It slows down the right wheel and keeps the left wheel going full speed forward.  Notice that it adds (ndShade*1000) to 200.  Reason being, this is the else statement for if(ndShade > 0.0), so it will get used when ndShade is equal to or smaller than zero.  So, if ndShade is –0.125, speedRight = int(200.0 + (ndShade * 1000.0)) would evaluate to 200 + (–1.25 × 1000) = 200 – 125 = 75.  The constrain function is used again, to limit speedRight.

  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
  }   

Test Navigation Decisions with Serial Monitor

Before actually testing out these navigation decisions, it’s best to take a look at the variable values with the Serial Monitor.  So, instead of a call to the maneuver function, first, let’s use some Serial.print calls to see if we got it right.

  Serial.print(speedLeft, DEC);              // Display speedLeft
  Serial.print("   ");                       // Spaces
  Serial.print(ndShade, DEC);                // Display ndShade
  Serial.print("    ");                      // More spaces
  Serial.println(speedRight, DEC);           // Display speedRight
 
  delay(2000);                               // 1 second delay
}

The print and println calls should result in a display that shows the value of speedLeft in the left column, speedRight in the right column, and ndShade between them.  Watch it carefully.  The side with brighter light will always display 200 for full-speed-forward, and the other will be slowing down with values less than 200—the darker the shade, the smaller the number.     

Example Sketch – Light Seeking Display

  • Make sure the power switch is set to 1.
  • Enter, save and upload the sketch LightSeekingDisplay.
  • Open the Serial Monitor.
  • Try casting different levels of shade over the BOE Shield-Bot’s right light sensor.  Does speedLeft (in the left column) slow down or even go into reverse with lots of shade?
  • Try the same thing with the left light sensor to verify the right wheel slows down.
  • Try casting more shade over both.  Again, since the shade is the same for both, ndShade should stay close to zero, with little if any slowing of the wheels.  (Remember, speedLeft and SpeedRight would have to drop by 100 before they’ll start to slow down.)
/*
 * Robotics with the BOE Shield - LightSeekingDisplay
 * Displays speedLeft, ndShade, and speedRight in Serial Monitor. Verifies
 * that wheel speeds respond correctly to left/right light/shade conditions.
 */

void setup()                                 // Built-in initialization block
{
  tone(4, 3000, 1000);                       // Play tone for 1 second
  delay(1000);                               // Delay to finish tone

  Serial.begin(9600);                        // Set data rate to 9600 bps
}  
 
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
  }  
 
  Serial.print(speedLeft, DEC);              // Display speedLeft
  Serial.print("   ");                       // Spaces
  Serial.print(ndShade, DEC);                // Display ndShade
  Serial.print("    ");                      // More spaces
  Serial.println(speedRight, DEC);           // Display speedRight
 
  delay(1000);                               // 1 second delay
}

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
}

Printer-friendly version
Light Measurement Graphic Display
Prev
Activity 5: Shield-Bot Navigating by Light
Next

DISCUSSION FORUMS | PARALLAX INC. STORE

About | Terms of Use | Feedback: learn@parallax.com | Copyright©Parallax Inc. 2024

© 2026 Parallax Learn • Built with GeneratePress