QTR-8A Reflectance Sensor Array Problems

I just got my sensor array in the mail today. After hooking it up using the sample code provided by the Pololu site, all i am getting for my values are 9’s and position of 2500. The sensor is 1/8" off the ground. Ive tried covering all ambient light, and i’ve tried shining a light under the sensor. I’m using a Arduino Duemilanove. Any thoughts?

Hello.

How do you have everything connected? Do you have a cheap digital camera (such as one in a cell phone) you can use to see if the IR LEDs are on (they should glow purple in the camera display if it lacks an IR filter and they are on)? Also, what kind of surface are you using?

- Ben

Thanks for the reply.

I have the power, ground, and LEDON hooked up correctly (im gettng 5 volts at the sensor using a DMM; and the LED is on on my Arduino). I broke off the 2 sensors on the end, so i have the remaining 6 sensors hooked up to the analog pins on the Arduino.

The IR LED lights are on during the calibration part of the code, but whenever the actual sensing starts they turn off, and i still get 9 9 9 9 9 9 2500

Right now i just have a piece of black electrical tape on a white piece of paper for my surface.

After some testing… it seems whenever i print out the calibrated min and max numbers… they seem to be reasonable numbers. Somehow the values from the calibration do not translate to good information in the main loop from the qtra.readLine function. I cant seem to get the code to compile when i try to just get the raw values using the qtra.read function.

Can you post the code you are trying to use and the errors you get when you compile?

- Ben

THIS CODE WORKS… EXCEPT THAT IT ALWAYS GIVES ME VALUES OF 1000 FOR THE SENSOR AND 2500 AS THE POSITION

#include <PololuQTRSensors.h>

#define NUM_SENSORS 6 // number of sensors used
#define NUM_SAMPLES_PER_SENSOR 4 // average 4 analog samples per sensor reading
#define EMITTER_PIN 2 // emitter is controlled by digital pin 2

// sensors 0 through 5 are connected to analog inputs 0 through 5, respectively
PololuQTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4, 5},
NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

void setup()
{
delay(500);
int i;
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // turn on LED to indicate we are in calibration mode
for (i = 0; i < 400; i++) // make the calibration take about 10 seconds
{
qtra.calibrate(); // reads all sensors 10 times at 2.5 ms per six sensors (i.e. ~25 ms per call)
}
digitalWrite(13, LOW); // turn off LED to indicate we are through with calibration

// print the calibration minimum values measured when emitters were on
Serial.begin(9600);
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(qtra.calibratedMinimumOn[i]);
Serial.print(’ ');
}
Serial.println();

// print the calibration maximum values measured when emitters were on
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(qtra.calibratedMaximumOn[i]);
Serial.print(’ ');
}
Serial.println();
Serial.println();
delay(1000);
}

void loop()
{
unsigned int position = qtra.readLine(sensorValues);

// print the sensor values as numbers from 0 to 9, where 0 means maximum reflectance and
// 9 means minimum reflectance, followed by the line position
unsigned char i;
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(sensorValues[i]); // I TOOK OUT THE MATH THAT CONVERTED THE NUMBER TO SOMETHING BETWEEN 1-9
Serial.print(’ ');
}
Serial.print(" ");
Serial.println(position);

delay(250);
}

Im not sure where to put the qtra.read() function in the code to get the raw data from the sensor.

Thanks

Is this where you got the qtr library you are using?

pololu.com/docs/0J19

It looks like you should be able to simplify your program greatly, which will probably help you locate the problem. For example, a good start would be to remove the calibration code entirely and to just print out the raw sensor readings. Also, I suggest that you disconnect the LEDON pin while you’re trying to get things working. When disconnected, the LEDs should be on 100% of the time. When connected, it just becomes another place where something could be going wrong (e.g. if you read the sensors with the LEDs off, you will generally see the maximum readings for all the sensors).

For example, can you just try something like:

#include <PololuQTRSensors.h>

#define NUM_SENSORS 6 // number of sensors used
#define NUM_SAMPLES_PER_SENSOR 4 // average 4 analog samples per sensor reading

// sensors 0 through 5 are connected to analog inputs 0 through 5, respectively
PololuQTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4, 5}, 
NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, QTR_NO_EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

void setup(){}
void loop()
{
  qtra.read(sensorValues);
  unsigned char i;
  for (i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensorValues[i]); // I TOOK OUT THE MATH THAT CONVERTED THE NUMBER TO SOMETHING BETWEEN 1-9
    Serial.print(' ');
  }
  delay(250);
}

Also, when you post code, please use the [ code ][ /code ] tags (minus the whitespace), or press the “Code” button so that it is formatted nicely, like my code above.

- Ben

Yea. i was using that code that was provided in the example on this site

this is what im using now. it seems to be working… im getting 1023 for the black electrical tape. but its only going to 1015-1020 whenever i place the sensor over the white paper

would you advise putting an LED near the sensor so it alluminates the ground and eliminates the ‘shadow’ thats underneath the sensor? or vise versa… (enclosing the sensor so not much light gets in)

#include <PololuQTRSensors.h>

#define NUM_SENSORS 6 // number of sensors used
#define NUM_SAMPLES_PER_SENSOR 4 // average 4 analog samples per sensor reading

// sensors 0 through 5 are connected to analog inputs 0 through 5, respectively
PololuQTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4, 5}, 
NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, QTR_NO_EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

void setup(){
  Serial.begin(9600);
  }
void loop()
{
  qtra.read(sensorValues);
  unsigned char i;
  for (i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensorValues[i]); 
    Serial.print(' ');
    
  }
  Serial.println("    ");   
  delay(250);
}

BTW… great support

Hmm, those results are somewhat surprising. Can you post a few pictures of your setup for me? Specifically, can you post a close-up of each side of your sensor array PCB and a shot that shows how everything is connected?

Using extra LEDs should not be necessary; each sensor on the board is paired with its own IR-emitting LED that is used for illumination (in the IR wavelength that the sensors measure, there is no shadow underneath the board when the LEDs are on). Just to be clear, you are holding the sensor with the SMT components facing towards the surface, right?

Once you have things working, you might want to enclose the sensor to keep out ambient IR since that can potentially skew the sensor readings. Lack of an enclosure would not be responsible for your problems now as ambient IR would cause your sensor readings to be lower (right now you’re measurements are an indication of almost zero reflectance).

- Ben

Code is working fine now… i guess i just needed to reset the program. Im getting 900s for black tape and 30s for white paper.

Now I’d like to be able to use the calibration code but whenever I use it, it sets everything to 1000, it’s like it won’t see any reflectance.

I also tried to see the difference between purple and yellow but it would only fluctuate by about 1 number in the low 30s range.

Now that you know what raw sensor values you’re getting, it should be easier to figure out what’s going wrong with calibration. After calibration, print out the minimum and maximum readings for each sensor and see if that gives you any clues. Note that during the calibration phase you must expose each sensor you’re using to what you want to consider “full black” and “full white”, which generally requires moving the sensor across your line at the height you plan on using it. If you don’t calibrate properly (say one sensor only ever sees black during the calibration phase), the calibrated readings will be bad.

It’s possible that the sensor will not be able to distinguish between your purple and yellow surfaces. Remember that the sensor measures IR reflectance, and your purple and yellow surfaces just might not look that different in infrared. Do you have any control over the surface material?

- Ben

I added the calibration code that i had originally, except i deleted the portions that dealt with turning the LED light on for the signal that you are calibrating. Magically it works now… So that problem is solved . Thanks for the help.

Now for the bad news… I dont have any control over the surface that we are using for the competition. (which is a purple surface with a 2 cm yellow line for tracking; (which is just purple and yellow paint on a sheet of plywood)). I tried calibrating the sensor over the yellow and purple track and it didnt help any. The sensor still cant distinguish between between the 2.

Here is the code that works for me if you want to add that to the library instead of the code thats on there now

#include <PololuQTRSensors.h>

#define NUM_SENSORS 6 // number of sensors used
#define NUM_SAMPLES_PER_SENSOR 4 // average 4 analog samples per sensor reading

// sensors 0 through 5 are connected to analog inputs 0 through 5, respectively
PololuQTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4, 5}, 
NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, QTR_NO_EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

void setup(){
  delay(500);
  int i;
  for (i = 0; i < 400; i++)  // make the calibration take about 10 seconds
  {
    qtra.calibrate();       // reads all sensors 10 times at 2.5 ms per six sensors (i.e. ~25 ms per call)
  }

  // print the calibration minimum values measured when emitters were on
  Serial.begin(9600);
  for (i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtra.calibratedMinimumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  
  // print the calibration maximum values measured when emitters were on
  for (i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtra.calibratedMaximumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  Serial.println();
  delay(1000);
  }

void loop()
{
  qtra.read(sensorValues);
  unsigned char i;
  for (i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensorValues[i]); 
    Serial.print(' ');
    
  }
  Serial.println("    ");   
  delay(250);
}

I tested the sample program from the Arduino QTR library when I wrote it and it worked for me. It doesn’t make sense to me that the user LED on pin 13 would have any affect on the sensor. Can you tell me exactly how you have everything connected (i.e. what pin on the sensor is connected to what pin on the Arduino)? Do you have anything else connected to your Arduino? What is your power source?

Your getting such low raw values for the purple and yellow surfaces means that both are very reflective to IR, but this could just be because the purple and yellow surfaces are shiny. You might have more luck distinguishing between the two if you angle your sensor array slightly. For example, imagine a shiny new black car and a shiny new white car on a sunny day. If you are positioned just right so that the sun reflects off the car into your eyes, that sun spot is going to look blindingly white on both cars, even the black one. The key to distinguishing the colors is to look at the parts of the car that aren’t reflecting the the illumination source directly back to you. Note that if you do angle the sensor a bit, you might need to position it even closer to the surface to get a strong enough signal.

- Ben

Im using the 5V pin and the Gnd pin that are next to each other on the Arduino. Im using all 6 Analog In pins and pin 13 that has the LED provided on the Arduino board. Nothing else is connected to the Arduino. Im using the USB connection as the power source for the Arduino also.

I tried your idea about changing the angle of the sensor. I went through about every possible combination of angle and height off the ground and still did not see any discernible difference in the values.

What are you using pin 13 for?

- Ben

Pin 13 controls a LED that is built on the Arduino. in the calibration part of the code, the LED will turn on when calibration is happening, and turn off when it is through

The way you phrased you response made it sound like you had pin 13 connected to something. Is there any connection between pin 13 and the sensor array?

- Ben