Chapter 6 Solutions

Question Solutions

  1. The amount of current it allows to pass into its collector and out through its base.
  2. The phototransistor’s collector and emitter terminals are connected to leads.
  3. The lead that’s closer to the flat spot is the emitter.  The lead that’s further away from the flat spot is the collector.
  4. The wavelength of red is closer to the wavelength of infrared, so it should be more sensitive to red.
  5. VA3 increases with more light.
  6. The phototransistor supplies the resistor with more or less current.
  7. Change the 2 kΩ resistor to a higher value.
  8. If the applied voltage is above the threshold voltage, the input register bit for that pin stores a 1.  If it’s below threshold voltage, the input register bit stores a 0. 
  9. The voltage decreases.

Exercise Solutions

  1. V = I × R = 0.001 A × 2000 Ω = 2 V.
  2. V = I × R → I = V ÷ R = 4.5 ÷ 2000 = 0.00225 A = 2.25 mA.
  3. 105 → 10 with 5 zeros appended and multiplied by 1 pF.  1,000,000 × 1 pF  = (1 × 106) × (1 × 10–12) F = 1 × 10–6 F = 1 μF.
  4.  It would be  long tDecay = rcTime(7);
  5. ndShade =  tRight / (tLeft+tRight) - 0.5 = 1001 ÷ (1001 + 1001) – 0.5 = 0.5 – 0.5 = 0.
  6. Solution:
  for(int i = 1; i<=50; i++)  // Repeat 50 times
  {
    Serial.print('=');        // one = char each time through
  }

Project Solutions

  1. This is a modified version of HaltUnderBrightLight
/*
 * Robotics with the BOE Shield - Chapter 6, Project 1
 * Chirp when light is above threshold.  Will require updating value of
 * threshold & retesting under bright light to get to the right value.
 */

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

void loop()                          // Main loop auto-repeats
{
  if(volts(A3) > 3.5)                 // If A3 voltage greater than 3.5
  {
    tone(4, 4000, 50);               // Start chirping
    delay(100);   
  }
}

float volts(int adPin)               // Measures volts at adPin
{                                    // Returns floating point voltage
 return float(analogRead(adPin)) * 5.0 / 1024.0;
}    
  1. The solution for this one is to make a copy of LightSeekingShieldBot, and add one command to the loop function:  ndShade = -ndShade.  Add it right before the if…else statement.  Then, instead of indicating shade to turn away from, it indicates bright light to turn away from.  Another approach would be to use an ndLight calculation that equals tLeft / (tLeft + tRight).  You would have to search/replace ndShade with ndLight in the sketch.                           
  1. Use LightSensorValues to determine a threshold.  It’s best to take tLeft + tRight.  You can use the LightSensorValues to test this.  Start with a value that’s 1/4 of the way from reaching the bright light level.  So if tLeft + tRight = 4000 and 400 for bright light, use the value 400 + ¼ × (4000 – 400) = 400 + 900 = 1300.  Don’t use 1300, it’s just an example; figure out the value for your conditions.

    Next, add an if statement similar to the one from HaltUnderBrightLight to the main loop of LightSeekingShieldBot.  Careful though, HaltUnderBrightLight uses the greater than (>) operator because it’s using a voltage output circuit.  We need the less than (<) operator for the QT circuit because smaller values mean brighter light.  We also need to express the threshold as a floating point value, like 1300.0.  Here’s an example:
  // Add this if condition to stop under the bright lamp.
  if((tRight + tLeft) < 1300.0)   // tLeft+tRight < 1300?
  {
    servoLeft.detach();           // Stop servo signals
    servoRight.detach();   
  }

Here’s a modified version of LightSeekingShieldBot that will do the trick.  Remember, you’ll still have to calibrate it to your lighting conditions.

/*
 * Robotics with the BOE Shield - Chapter 6, Project 3
 * 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
 
  // Add this if condition to stop under the bright lamp.
  if((tRight + tLeft) < 1300.0)              // If A3 voltage greater than 2
  {
    servoLeft.detach();                      // Stop servo signals
    servoRight.detach();   
  }
 
  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
}