Using QRE1113 for encoder

I am new to this as well as new to Arduino programming. I have done most of the lessons available from this as well as other sites. But I am a bit stumped.

I am attempting to use a QRE1113 IR sensor to read an optical encoder disk. I used the following tutorial sketch for the QRE1113 sensor found at bildr Line Sensing. QRE1113 Reflectance Sensor + Arduino - bildr. I regret I do not know how to provide the line numbers along the left margin. That being said I have reproduced the code from that tutorial below.

The optical disk contains 12 segments, alternating black and white. The QRE1113 is placed in close proximity to the face of the disk bearing the alternating segments.

The output from the sensor to serial monitor appears in the following format :

1310
1360
1350
1350
22
24
22
24
1330
1320
1350
1350
22
22
24

I wish to use the rise to measure in signal to measure the change in each segment, essentially providing the number of pulses per unit of time. From this I can measure RPM as well as distance. But for the life of me, I have been unable how to count the changes or rise in the signal. Anyone have any pointers?

//Code for the QRE1113 Digital board
//Outputs via the serial terminal - Lower numbers mean more reflected
//3000 or more means nothing was reflected.

int QRE1113_Pin = 2; //connected to digital 2

void setup(){
  Serial.begin(9600);
}


void loop(){

  int QRE_Value = readQD();
  Serial.println(QRE_Value); 

}


int readQD(){
  //Returns value from the QRE1113 
  //Lower numbers mean more refleacive
  //More than 3000 means nothing was reflected.
  pinMode( QRE1113_Pin, OUTPUT );
  digitalWrite( QRE1113_Pin, HIGH );  
  delayMicroseconds(10);
  pinMode( QRE1113_Pin, INPUT );

  long time = micros();

  //time how long the input is HIGH, but quit after 3ms as nothing happens after that
  while (digitalRead(QRE1113_Pin) == HIGH && micros() - time < 3000); 
  int diff = micros() - time;

  return diff;
}

Which component do you have? A plain QRE1113 you wired yourself or a board? If a board, which one? (Sounds like and the Sparkfun digital )

It’s hard to use the digital version for “fast timing”. That’s because reading the sensor will take time and that time depends on the amount of light. And one of the readings takes 1,4ms and reading the sensor is the only thing the Arduino does atm. So be aware of this limitation.

But if the movement is slow, just use a threshold. Let’s say <500 is a low and > 500 is a high. You do that for each reading and you compare that to the last. If the last was high and the new one is low you know it became low. Last low and new high, it’s now high. That’s called state change. Now simply use millis() to save and compare times like you did with micros() here. Only don’t let it hang in some loop (like a while).

A few things ...

Post a photo of the encoder disk so that we can see what size the segments are compared to the QRE

Which QRE board are you using> and how have you connected it?

How fast is the encoder disk rotating (or how many pulses per second do you wish to detect)?

I have been using a QRE1113 chip on a board I made myself. I use the connection arrangement for the Sparkfun analog board for pulse counting and I use in interrupt to detect the pulses and record the value of micros(). This is my ISR code

void revMicrosISR() {
 isrRevMicros = micros();
 isrRevCount ++;
 newRevMicros = true;
}

Note that my device (a small DC motor) only produces 1 pulse per revolution - hence the name of the ISR.

I don't think the "digital" version of the Sparkfun board is suitable for pulse counting.

...R

Thanks for your replies. They are greatly appreciated.

The device I am using is the Sparkfun QRE1113 digital attached to pins 13, 12, and 11 (different than shown). The disk is a standard DVD/CD rom with 12 black and white segments around the perimeter. It was temporarily mounted to a cork arbor attached to a dc motor operated at 0.75 volts which slowed the rpm to produce the data shown.

I gathered there was some difficulty in data collection. In portions of the code (which i did not provide) you could see some perturbations in the consistency of the output as well as intensity. I attributed this to variables introduced in my cobbling of the test system (disk not always same distance from sensor, etc.). But if it took too much time to sense and report, that can explain errors as well.

I have attached a photo showing the encoder disk, motor with arbor, and sensor attached to Arduino. The disk is attached to the arbor face down toward the sensor and positioned to be within 1/4 inch of the sensor. Not shown is the bread board and voltage divider to slowly drive the dc motor. But it did work to give me the data shown above.

The disk is a CD rom (~4.5" O.D.) with the encoder pattern glued to the face. The pattern was printed using a post script encoder generator program and printed using a laser printer to give it good saturation/contrast. As you can see there are twelve equal segments - 6 dark 6 white.

The concept is to measure the RPM of a slow moving wheel of a robot. Actually the robot to be built will be using a powered wheelchair base attached to the snow blower. Location and orientation will be controlled by a compass and GPS input… Maybe a pipe dream, but I digress. Right now I just want to be able to work on RPM.

I have both the digital and analog versions of the sensor. I will repeat the first experiment varying sensor input. I will then implement your suggests (attempt to at least) and report back. I am sure I will have something to report, and more questions. I greatly appreciate your help.

Image from Reply #4 so we don’t have to download it. See this Image Guide

82204cd78e4d37f96b00b63f25b70360a70a8b04.jpg

…R

You don't seem to have the Sparkfun board connected to Power and GND. I don't know if it is sufficient to power it from Arduino I/O pins - personally I would not even try.

From my experiments you need the reflecting surface to be no more than 1 or 2mm from the face of the QRE.

The program you are trying is appropriate for the Sparkfun digital board but it is not appropriate for detecting black and white sectors. You are not interested in how bright the reflection is - only whether it is ON or OFF (Black or White).

IMHO you should use the Sparkfun analog board and a simple digitalRead() of the output pin will tell whether it is looking at the black or white sector.

Make sure the black is matte. There is enough sheen on a piece of black cloth that I have to cause a reflection.

...R

Hi,
Have you looked at the diagram for connection of the digital sensor?

As Robin2 has said, where are you supplying power.

Can you tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom... :slight_smile: