Understanding digitalread with phototransistors

I’m really new to electronics and a moderately experienced programmer and I just bought the Parallax Boe-Bot Education board with Arduino.

Following this guide for setting up navigation via phototransistors: http://learn.parallax.com/node/261 and then using this code:

/*
 * Robotics with the BOE Shield - LeftLightSensor
 * Measures and displays microsecond decay time for left light sensor.
 */

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
{
  long tLeft = rcTime(8);                    // Left rcTime -> tLeft
 
  Serial.print("tLeft = ");                  // Display tLeft label
  Serial.print(tLeft);                       // Display tLeft value
  Serial.println(" us");                     // Display tLeft units + newline

  delay(1000);                               // 1 second delay
}
                                             // rcTime function at pin  
long rcTime(int pin)                         // ..returns decay time
{                                            
  pinMode(pin, OUTPUT);                      // Charge capacitor
  digitalWrite(pin, HIGH);                   // ..by setting pin ouput-high
  delay(1);                                  // ..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;                               // Return decay time
}

i’ve been able to get basic navigation by turning towards bright lights. Trying to branch off from here, I’ve wanted to get my Boe-bot to act more like a cockroach where I turn away from any light and try to find shade until it’s immersed in darkness. Here is my code for a VERY basic version of what I would like to do.

#include <Servo.h>

Servo servoLeft;
Servo servoRight;

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

  servoLeft.attach(13);                      // Attach left signal to pin 13
  servoRight.attach(12);                     // Attach right signal to pin 12}  
} 
void loop()                                  // Main loop auto-repeats
{
  Serial.println("\n\n\nSTARTED LOOP\n\n\n");
  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.01)                         // Shade on left?
  {                                           // Slow down left wheel
    Serial.println("Shade is on the left\n");
    speedLeft = int(200.0 - (ndShade * 1000.0));
    speedLeft = constrain(speedLeft, -200, 200);
    speedRight = 200;                        // Full speed right wheel
  }
  else if (ndShade >= 0.01)                  // Shade on right?
  {                                          // Slow down right wheel
    Serial.println("Shade is on the right\n");
    speedRight = int(200.0 + (ndShade * 1000.0));
    speedRight = constrain(speedRight, -200, 200);
    speedLeft = 200;                         // Full speed left wheel
  }  
  else //darkness. Stop.
  {
   Serial.println("I should be stopped!!!!!!\n");
   speedLeft = 0;
   speedRight = 0; 
  }
  
  Serial.println("tLeft     ndShade     tRight");
  
  Serial.print(tLeft);
  Serial.print("   ");
  Serial.print(ndShade);
  Serial.print("   ");
  Serial.print(tRight);
  Serial.println(" ");
 
  maneuver(speedLeft, speedRight, 1000);       // 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
  {
       Serial.println("In loop."); 
  }
  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
}

However, since i’ve changed the code, i’ve found that the Boe-bot get stuck in the while loop where it’s trying to do a digitalRead until the pin returns LOW. I’m not sure what i’ve changed to make it stuck in this loop longer than I expected it to, because the code seemed to work fine before, but for some reason the digitalRead is always reading HIGH (unless I move from a dark place to a light place or visa versa.)

There is obviously something fundemental i’m missing here and because I’m new to the electronics side of things I’m thinking that’s the reason why. Any nudge in the right direction to understanding why it’s getting stuck is appreciated! Thanks in advance.

Without the pullup R, the input is floating. This is probably why the voltage does not change as you expect.

Weedpharma

Thanks for your input-

I apologize for being a complete novice in this but after looking up what a Pullup Resistor was I'm not sure how I would implement this in my circuit for the cockroach motion.

Could you possibly explain what I changed to make the pullup necessary? As far as I understood, the first block of code didn't have a pullup so that the capacitor could drain and then count how long it took for it to drain completely, and that's the time it would use to determine whether the left or right phototransistor was receiving the correct amount of light.

If i'm not mistaken (and I probably am) then if the phototransistor is receiving no light, the capacitor shouldn't fill up at all, and so it should return LOW immediately; but that's obviously not the case.

Anyways, if you could explain the difference between why I didn't need a pullup before and why I do now, that would be helpful. And to use a pullup would i just connect another resistor to the breadboard and Vin? Thanks!