Question Solutions
- The amount of current it allows to pass into its collector and out through its base.
- The phototransistor’s collector and emitter terminals are connected to leads.
- 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.
- The wavelength of red is closer to the wavelength of infrared, so it should be more sensitive to red.
- VA3 increases with more light.
- The phototransistor supplies the resistor with more or less current.
- Change the 2 kΩ resistor to a higher value.
- 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.
- The voltage decreases.
Exercise Solutions
- V = I × R = 0.001 A × 2000 Ω = 2 V.
- V = I × R → I = V ÷ R = 4.5 ÷ 2000 = 0.00225 A = 2.25 mA.
- 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.
- It would be long tDecay = rcTime(7);
- ndShade = tRight / (tLeft+tRight) - 0.5 = 1001 ÷ (1001 + 1001) – 0.5 = 0.5 – 0.5 = 0.
- Solution:
for(int i = 1; i<=50; i++) // Repeat 50 times { Serial.print('='); // one = char each time through }
Project Solutions
- 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; }
- 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.
- 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 }