How to use pololu qtr8rc sensor panel for follow a white in black surface

If anyone could please tell me how to use pololu qtr8rc sensor panel for follow a white in black surface its runs good in black line but not works in white line.I switched on the whiteLine in readline function

 line_position = qtrrc.readLine(sensorValues,1);

  // read the value of only a single sensor to see the line.
  // when the value is greater than 200 the sensor sees the line.
  while (sensorValues[6] < 200)  // wait for line position to near center
  {
    line_position = qtrrc.readLine(sensorValues, 1);
  }
   
  // find near center
  while (line_position > 4350) // continue loop until line position is near center
  {
    line_position = qtrrc.readLine(sensorValues, 1);
  }
 
  // stop both motors
  analogWrite(pwm_b, 0); // stop right motor first which kinda helps avoid over run
  analogWrite(pwm_a, 0);

  // delay as indicator setup and calibration is complete
  delay(1000); 
  
} // end setup



void loop() // main loop
{

  // read calibrated sensor values and obtain a measure of the line position from 0 to 7000
  unsigned int line_position =  qtrrc.readLine(sensorValues, 1);
   
  // begin line
  follow_line(line_position);

}  // end main loop

Hello.

I changed the thread title to a shorter version and copied and pasted the original in your post. Please avoid creating lengthy titles for future threads you create.

From your code, it looks like you are missing the second argument for the readMode parameter in readLine(). For details, please see the function’s documentation under the “QTRSensors Methods & Usage Notes” section of the Arduino Library for the Pololu QTR Reflectance Sensors.

- Amanda

Thank you AmandaS ill try

AmandaS if you could pls convert my code to follow white line, I tried but nothing changed

//QTRSensors folder must be placed in your arduino libraries folder
#include <QTRSensors.h>  // Pololu QTR Library 

//line sensor defines
#define NUM_SENSORS   8     // number of sensors used
#define TIMEOUT       2500  // waits for 2500 microseconds for sensor outputs to go low
#define EMITTER_PIN   QTR_NO_EMITTER_PIN  // emitter control pin not used.  If added, replace QTR_NO_EMITTER_PIN with pin#

// line sensor declarations
// sensors 0 through 7 are connected to digital pins 2 through 10, respectively (pin 3 is skipped and used by the Ardumoto controller)
// 0 is far Right sensor while 7 is far Left sensor
QTRSensorsRC qtrrc((unsigned char[]) {10,9,8,7,6,5,4,2},NUM_SENSORS, TIMEOUT, EMITTER_PIN); 
unsigned int sensorValues[NUM_SENSORS]; // array with individual sensor reading values
unsigned int line_position=0; // value from 0-7000 to indicate position of line between sensor 0 - 7

// ArduMoto motor driver vars
// pwm_a/b sets speed.  Value range is 0-255.  For example, if you set the speed at 100 then 100/255 = 39% duty cycle = slow
// dir_a/b sets direction.  LOW is Forward, HIGH is Reverse 
int pwm_a = 3;  //PWM control for Ardumoto outputs A1 and A2 is on digital pin 10  (Left motor)
int pwm_b = 11;  //PWM control for Ardumoto outputs B3 and B4 is on digital pin 11  (Right motor)
int dir_a = 12;  //direction control for Ardumoto outputs A1 and A2 is on digital pin 12  (Left motor)
int dir_b = 13;  //direction control for Ardumoto outputs B3 and B4 is on digital pin 13  (Right motor)

// motor tuning vars 
int calSpeed = 165;   // tune value motors will run while auto calibration sweeping turn over line (0-255)

// Proportional Control loop vars
float error=0;
float lastError=0;
float PV =0 ;
float kp = 0;
float ki = 0;
float kd =0;
int m1Speed=0;
int m2Speed=0;
//int line_position=0;
int motorspeed=0;

void setup()
{
  //Set control pins to be outputs
  pinMode(pwm_a, OUTPUT);  
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_a, OUTPUT);  
  pinMode(dir_b, OUTPUT);  

  //set both motors to stop
  analogWrite(pwm_a, 0);  
  analogWrite(pwm_b, 0);
    
  // delay to allow you to set the robot on the line, turn on the power, 
  // then move your hand away before it begins moving.
  delay(2000);

  // calibrate line sensor; determines min/max range of sensed values for the current course
  for (int i = 0; i <= 100; i++)  // begin calibration cycle to last about 2.5 seconds (100*25ms/call)
  {
    
    // auto calibration sweeping left/right, tune 'calSpeed' motor speed at declaration
    // just high enough all sensors are passed over the line. Not too fast.
    if (i==0 || i==60)  // slow sweeping turn right to pass sensors over line
    {
       digitalWrite(dir_a, LOW); 
       analogWrite(pwm_a, calSpeed);
       digitalWrite(dir_b, HIGH);  
       analogWrite(pwm_b, calSpeed);   
    }
    
    else if (i==20 || i==100) // slow sweeping turn left to pass sensors over line
    {
       digitalWrite(dir_a, HIGH); 
       analogWrite(pwm_a, calSpeed);
      digitalWrite(dir_b, LOW);  
       analogWrite(pwm_b, calSpeed);   
   }
    
    qtrrc.calibrate(); // reads all sensors with the define set 2500 microseconds (25 milliseconds) for sensor outputs to go low.
    
  }  // end calibration cycle

  // read calibrated sensor values and obtain a measure of the line position from 0 to 7000
  line_position = qtrrc.readLine(sensorValues);

  // read the value of only a single sensor to see the line.
  // when the value is greater than 200 the sensor sees the line.
  while (sensorValues[6] < 200)  // wait for line position to near center
  {
    line_position = qtrrc.readLine(sensorValues);
  }
   
  // find near center
  while (line_position > 4350) // continue loop until line position is near center
  {
    line_position = qtrrc.readLine(sensorValues);
  }
 
  // stop both motors
  analogWrite(pwm_b, 0); // stop right motor first which kinda helps avoid over run
  analogWrite(pwm_a, 0);

  // delay as indicator setup and calibration is complete
  delay(1000); 
  
} // end setup



void loop() // main loop
{

  // read calibrated sensor values and obtain a measure of the line position from 0 to 7000
  unsigned int line_position = qtrrc.readLine(sensorValues);
   
  // begin line
  follow_line(line_position);

}  // end main loop





void follow_line(int line_position) //follow the line
{

  // 0 is far Right sensor while 7 (7000 return) is far Left sensor

  switch(line_position)
  {
       
    // Line has moved off the left edge of sensor
    // This will make it turn fast to the left
    case 7000:
           digitalWrite(dir_a, HIGH); 
           analogWrite(pwm_a, 200);
           digitalWrite(dir_b, LOW);  
           analogWrite(pwm_b, 200);
    break;

    // Line had moved off the right edge of sensor
    // This will make it turn fast to the right
    case 0:     
           digitalWrite(dir_a, LOW); 
           analogWrite(pwm_a, 200);
           digitalWrite(dir_b, HIGH);  
           analogWrite(pwm_b, 200);
    break;
 
    // The line is still within the sensors. 
    // This will calculate adjusting speed to keep the line in center.
    default:      
    
      error = (float)line_position - 3500;
 
  // set the motor speed based on proportional and derivative PID terms
  // kp is the a floating-point proportional constant (maybe start with a value around 0.5)
  // kd is the floating-point derivative constant (maybe start with a value around 1)
  // note that when doing PID, it's very important you get your signs right, or else the
  // control loop will be unstable
  kp=1/20;
  kd=2/3;
   
  PV = kp * error + kd * (error - lastError);
  lastError = error;
  
  //this codes limits the PV (motor speed pwm value)  
  // limit PV to 55
  if (PV > 55)
  {
    PV = 55;
  }
  
  if (PV < -55)
  {
    PV = -55;
  }
    
  
  m1Speed = 200 + PV;
  m2Speed = 200 - PV;
     
      //set motor speeds
      digitalWrite(dir_a, HIGH);  
      analogWrite(pwm_a, m1Speed);
      digitalWrite(dir_b, HIGH);  
      analogWrite(pwm_b, m2Speed);
      break;
  } 

} // end follow_line  

here is my code for follow black line on white surface could u pls tell me what are the changes that I have to do to follow white line

Hi guys first I thank AmandaS to give me correct instructions about my early questions here is the link for it
How to use pololu qtr8rc sensor panel for follow a white in black surface,
After that I goon with my robot and found why it not giving correct outputs while following white line like black line,then I found two errors in my side one is the distance between the surface and the surface according to my measurements It should between 8-9.5mm other than It gives me wrong sensor readings,the other thing is the motor shield I used,It is Arduino Motor Shield in it 8 and 9 pins were defined as brake so if I set sensor out to those pins it will not give a input so it also cause for a problem.so when we use a shield like that want to know about those otherwise we have to face troubles.and also I want to say
*** unsigned int position = qtra.readLine(sensorValues) for black line;
*** unsigned int line_position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, 1); (white line)
are the only difference part in the code between black line follower white line follower.
I think this will help to other beginners who use qtr8rc sensor panel.for any one want the code pls reply me

  • Rangika Mark

I merged your new thread with your existing thread, since it seemed unnecessary to create a new topic.

I am glad you figured out the issue with your code; thank you for letting us know and sharing your experience with others who might encounter the same problem.

- Amanda

Does i need to change the sign of position to follow white line.Like to follow black line error = position - 2500; and for white line is it 2500 - position??

Hello.

No; setting the whiteLine argument for readLine() to true takes care of the inverted values by replacing each sensor value with the maximum possible value (1000) minus the actual value before averaging. You can find that information under the “QTRSensors Methods & Usage Notes” section of the Arduino Library for the Pololu QTR Reflectance Sensors guide.

- Amanda