Line Following Trouble

Dear Forum,

I am typing this quickly, and somewhat frantically, so please forgive any typos. I am bilding a robot (4 wheels) that is designed to use 3 sparkfun reflectance sensors to follow lines, and an ultrasonic sensor so that the robot will stop when something is in front of it. I have 4 dc motors, being controlled by an Adafruit motorshield V2. I have gotten the ultrasonic sensor to work, and the robot moves, until something is in front of it. The line sensing is a different story. The robot moves, turns a little sometimes, but generally moving just straight. Here is my code:

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"


Adafruit_MotorShield motorShield = Adafruit_MotorShield();   //motorShield object

Adafruit_DCMotor *motorFR = motorShield.getMotor(1);        // create instances of motors
Adafruit_DCMotor *motorFL = motorShield.getMotor(2);
Adafruit_DCMotor *motorBR = motorShield.getMotor(3);
Adafruit_DCMotor *motorBL = motorShield.getMotor(4);


long inches;
long duration;
const int pingPin = 7;        //ultrasonic sensor on pin 7
const int distance = 6;       // closest it can be

int rightIR = A5;
int centerIR = A4;
int leftIR = A3;               //connected to analog 0
int LSpeed;
int RSpeed;

int speedR;
int speedL;



int lineSense() {
  
  int leftVal = ((analogRead(leftIR) - 200) - ((analogRead(leftIR) - 200) % 50));
  int centerVal =  ((analogRead(centerIR) - 150) - ((analogRead(centerIR) - 150) % 50));
  int rightVal =  ((analogRead(rightIR) - 300) - ((analogRead(rightIR) - 300) % 50));
  int movingDirection = (centerVal + leftVal) - (rightVal + centerVal);  //or minus???
  
  Serial.print("The left value is: ");
  Serial.println(leftVal);
  delay(1000);
  Serial.print("The right value is: ");
  Serial.println(rightVal);
  delay(1000);
  Serial.print("The drift is: ");
  Serial.println(movingDirection);
  delay(1000);
  return movingDirection;

}


void follow(int drift) {

  lineSense();

  if (drift > 25) {
    speedR--;
    speedL++;

    Serial.print("speed R is:");              //for debugging
    Serial.println(speedR);

    motorFR->setSpeed(speedR);
    motorBR->setSpeed(speedR);

    Serial.print("speed L is:");
    Serial.println(speedL);

    motorFL->setSpeed(speedL);               //set the speed
    motorBL->setSpeed(speedL);

    if (drift < -25) {

      speedL--;        //decrease the speed of the left - needs to get over right
      speedR++;
      
     // delay(1000);
      Serial.print("speed R is:");
      Serial.println(speedR);
      motorFR->setSpeed(speedR - 60);
      motorBR->setSpeed(speedR - 60);

      //delay(1000);
      Serial.print("speed L is:");
      Serial.println(speedL);

      motorFL->setSpeed(speedL - 60);
      motorBL->setSpeed(speedL - 60);



    }

  }

}

long detectObject() {
  
  pinMode(pingPin, OUTPUT);          // Set pin to OUTPUT
  digitalWrite(pingPin, LOW);        // Ensure pin is low
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);       // Start ranging
  delayMicroseconds(5);              //   with 5 microsecond burst
  digitalWrite(pingPin, LOW);        // End ranging
  pinMode(pingPin, INPUT);           // Set pin to INPUT
  duration = pulseIn(pingPin, HIGH); // Read echo pulse
  inches = duration / 74 / 2;
  return inches;                //return distance to nearest object in inches

}


void moveForward() {

  motorFR->run(FORWARD);          //all motors run forward
  motorFL->run(FORWARD);
  motorBR->run(FORWARD);
  motorBL->run(FORWARD);



}

void stopMotor() {

  motorFR->run(RELEASE);          //all motors stop
  motorFL->run(RELEASE);
  motorBR->run(RELEASE);
  motorBL->run(RELEASE);

}





void setup() {
  
  Serial.begin(9600);
  motorShield.begin();
  motorFR->setSpeed(70);      // set default speed for all the motors
  motorBR->setSpeed(70);
  motorBL->setSpeed(70);      //change vals depending
  motorFL->setSpeed(70);

}


void loop() {


  follow(lineSense());
  detectObject();            //look for object
  Serial.println(inches);   // print out how far the nearest
  if (inches < distance)     //if the nearest object is less than distance (6) away
    stopMotor();            //stop
  else
    moveForward();
    Serial.println("movingForward");    //otherwise, keep moving forward

}

Please note the way the adafruit motor controller controls the dc motors is setSpeed function sets a speed, and run makes it go in whatever direction in relation to that speed. Note: RELEASE is stop.
How can I make the robot follow the line?

Thanks,
ma7730

I was using a Leonardo, but for some weird reason it stopped working, I couldn’t upload to it, so I switched to an Uno, but in the Serial monitor I just get: Estimated.

The lineSense() function pisses away 3 seconds every time it is called. No wonder you can't follow the line.

  lineSense();

When you do call it, you throw away the important information that it returns.

void loop() {


  follow(lineSense());

So, each call to follow() takes 6 seconds...

Why does detectObject() return a global variable?

Thank you so much for your quick response. I greatly appreciate it. When you say I waste away three seconds, am I correct to assume you are talking about the delays? I just deleted all the delays (except the ones in the detect object function, those are needed of course), and it still works exactly the same. I just moves forward until there is an obstacle.

What do you mean by saying that I am throwing away the important information when I call it?
The detectObject function returns a global variable so that when I call the function, in the main loop, I have

  detectObject();            //look for object
  Serial.println(inches);   // print out how far the nearest
   if (inches < distance)     //if the nearest object is less than distance (6) away
    stopMotor();            //stop
  else
    moveForward();

It sees how far the object is and then sends that value to the variable inches, so I can see if that is fewer than 6, distance.

Thanks,
ma7730

What do you mean by saying that I am throwing away the important information when I call it?

You call the function:

  lineSense();

It returns a value. What are you doing with the value that it returns? You are discarding it. I fail to see how calling the function is useful.

The detectObject function returns a global variable so that when I call the function, in the main loop, I have

Either the variable is local to the function, and you return the value in the variable OR the variable is global, and there is no need to return a value. Returning the value in a global variable is silly.