Digital QRE1113

So just to air out the details, I have little programming experience. I have been face down in books trying to cram as much information into my brain as i can, and have been able to work though most issues as i learn, granted very slowly.

So I am working on a line following robot, and am using the Digital QRE1113 IR sensors. I’ve read some sample codes online, and have looked over the bildr and pololu but have been beating my head against my desk for 11 plus hours, and am begging for some direction.

With using the Bildr code template, I try to stick in an if statement to make a motor advance depending on what the sensor sees. What i can not comprehend is what do i use for my variable in the if statement. Like…

If(QRE1113_Pin > 1500);
{
advance(155,155);
}

If i stick it before the “return diff;” in the bildr code then the motor spins weather a white paper is under the sensor or not, if i stick it after the motor will not do anything no matter what happens. I know im looking at the time it takes the capacitor to discharge to determine weather im looking at a white or black surface… But i’m unsure of what input i should be referencing with an if statement, and where in the code that if statement should be put. I’ve also tried If(diff < 1500);

I really appriciate any help or even a direction to run in at this point, I’m tempted to cave and use analog sensors but now its more of a “This thing will not beat me” situation.

-DD

Get rid of the semicolon on the “if”

In future, it’s best if you post all your code.

The code im using is the digital sample from http://bildr.org/2011/06/qre1113-arduino/

I tried removing the ; still no joy.

Is the code from builder just what is needed to get a response and then my "if" statements would follow after the return diff; portion?

Apologies if im using incorrect terminology, I'm trying to crawl my way up a steep learning curve.

You need to post your code; we're not psychic.

//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;

//When i place an if statement here the motors run continuous no matter what is under the sensor

return diff;
}

// When an if statement is placed here nothing happens - Im assuming because it is outside of the loop?

What motors?

They are just cheapies that came with a DF Robot 2wd robot chassis, im using a DF Robot RoMeo Arduino controller.

I have had the motors working previously, triggered by either a prox switch or push button on the board.

I just can’t figure out how to utilize the output from the QRE in a statement to simply turn the motor on and off. Once i get one working i want to progress to having an array of 4 for a line follower, when either one of the inside sensors see black tape → cut the PWM of that sides motor in half to make a turn, and if it does not correct enough and it trips an outside sensor, completely shut that motor off to correct the direction of the bot.

I can’t wrap my brain around what to use for an If statement just to turn the motors on when it sees either white or black.

I have been putting…

int E1 = 5; //M1 Speed Control
int E2 = 6; //M2 Speed Control
int M1 = 4; //M1 Direction Control
int M2 = 7; //M1 Direction Control

void advance(char a,char b) //Move forward
{
analogWrite (E1,a); //PWM Speed Control
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}

at the top of my code, then calling out the advance in an If statement like…

If(prox = 1)
{
advance(155,155)
}

when i was getting them to turn on when the prox switch was tripped. With the QRE I don’t know what to put in place of “prox” in the If statement, and where in the bildr code it should be placed ie. After the “return diff;” or directly after the

while (digitalRead(QRE1113_Pin) == HIGH && micros() - time < 3000);
int diff = micros() - time;

section of code.

Thanks for the replies so far.

No, you really post all the code.

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

int E1 = 5; //M1 Speed Control
int E2 = 6; //M2 Speed Control
int M1 = 4; //M1 Direction Control
int M2 = 7; //M1 Direction Control
int QRE1113_Pin = 2; //connected to digital 2

void advance(char a,char b) //Move forward
{
analogWrite (E1,a); //PWM Speed Control
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}

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;

if(QRE1113_Pin < 1500)
{
advance(155,155);
}

return diff;
}


With this setup motors turn continuous no matter what is under the sensor. I have tried values from 3000 to 0 just trying to get motors to change state based on something the QRE1113 sees. I have also tried putting the If(QRE1113_Pin < 1500) statement after the return diff; and then nothing happens.

You haven't set pin M1 to be an output. Or M2.

If a pin (correctly setup) is written HIGH, it will stay that way until written LOW.

Please use code tags when posting code. Use the # icon on the editors toolbar.

Sorry if the code is tough to read, im working on it on one PC and am on the net on another.

Tried calling them out as outputs, same result. I think my error is in the if statement, like im not calling the right value.

With this board and these motors ive never had to call M1 and M2 out as outputs before.

By default, the pins are inputs, so writing HIGH to them just enables the pull up resistors. If you never write LOW to them, how do you expect to turn the motors off?

If your reffering to the

line 1-> pinMode( QRE1113_Pin, OUTPUT );
line 2-> digitalWrite( QRE1113_Pin, HIGH );
line 3-> delayMicroseconds(10);
line 4-> pinMode( QRE1113_Pin, INPUT );

section of the code, i thought that line 1 defined the pin as an output, then line 2 drove it high to charge the cap, then the little delay and then line 4 turns the pin to an input.

Then…

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;

watches that pin and times how long it takes the input to go low, and then turns that into a number between 3000 and 0. Once that number is calculated where does it go?? I want to reference that number in an If statement to control the motor weather or not its over white or black paper, so there must be a threshold in there to use as the turning point. Like "white paper gives a value of 900, so i will say if(QRE1113_Pin < 1000) i must be on white paper.

Maybe im just way too out in left field at this point.

No, I'm talking about M1 and M2. The ones presumably connected to your motor.

If you put some debug prints, you could see what is going on, without relying on untested wiring and hardware.

(What does "left field" mean?)

I guess i thought with using an if statement the motors would only run when the QRE met the desired condition. I have been able to do it like that with the prox sensor, i was assuming that if the code looped though and the sensor was not true, then the if condition would not be met and it would skip by it.

The bigger problem is getting the QRE to control the reaction of anything. I've been grappling with different values or trying different arguments in the if statement thinking the returned timed value was getting written to a different location other than QRE1113_Pin as an input once it timed the microseconds it took to discharge the cap and returned a value.

I ment "Left field" as in im so far off base that the way im trying to use the code from bildr it will never work as the example i have provided.

So, debug prints are the way to go.

("off base"?)

Yea ill have to do some research and see how to add those in, the first thing i ever programmed was a servo conrtoller last fall and that was in Basic. Arduino has been quite the challenge so far.

"Out in left field" must be an American expression, i see you have the UK listed as your location.

An example i can think of is say you asked someone what 2 + 2 was, and their response was 452. A joking reply would be "Your answer is way out in left field"

Thanks for the help so far and the quick replies. Ill post any updates as they come...

You know you're a computer nerd when someone asks you "what is two and two?", and you reply (correctly) "two".

It was a co-workers 60th birthday a few weeks ago, so in the card i put "Happy sqrt 3600 th Birthday"

Still getting ripped on for that one.

Serial prints were a dream come true, finally got it working, so i figured i would post here for others who may use this sensor. Be kind to the code, I’m sure it still needs a lot of tweaking, and its only the second program i have worked on.

int E1 = 5;     //M1 Speed Control
int E2 = 6;     //M2 Speed Control
int M1 = 4;    //M1 Direction Control
int M2 = 7;    //M1 Direction Control
int QRE1113_LI = 2; //connected to digital 2
int QRE1113_RI = 8; // connected to digital 8
int QRE1113_B = 9; // connected to digital 9

void advance(char a,char b)          //Move forward
        {
          analogWrite (E1,a);      
          digitalWrite(M1,HIGH);    
          analogWrite (E2,b);    
          digitalWrite(M2,HIGH);
        }  
void turn_L (char a,char b)             //Turn Left
        {
          analogWrite (E1,a);
          digitalWrite(M1,LOW);    
          analogWrite (E2,b);    
          digitalWrite(M2,HIGH);
        }
void turn_R (char a,char b)             //Turn Right
        {
          analogWrite (E1,a);
          digitalWrite(M1,HIGH);    
          analogWrite (E2,b);    
          digitalWrite(M2,LOW);
        }
void halt(void)                    //Stop
        {
          digitalWrite(E1,LOW);   
          digitalWrite(E2,LOW);      
        }           
        
void setup(){
  pinMode(M1, OUTPUT);
  pinMode(M2, OUTPUT);
  pinMode(E1, OUTPUT);
  pinMode(E2, OUTPUT);
  Serial.begin(9600);
}

void loop(){

  int QRE_ValueLI = LIread();
  int QRE_ValueRI = RIread();
  int QRE_ValueB = Bread();
  
  Serial.println(QRE_ValueLI);
  
if (QRE_ValueB < 500)
  {
  if (QRE_ValueLI < 500 && QRE_ValueRI < 500) //If surface under both sensors is White actuate motors forward at PWM rate of 155
    {
      advance(155,155);
    }
  else if (QRE_ValueLI > 500 && QRE_ValueRI < 500) //If surface under Right sensor is Black turn right to correct
    {
      turn_R(155,155);
    }
  else if (QRE_ValueLI < 500 && QRE_ValueRI > 500) //If surface under Left sensor is Black turn left to correct
    {
      turn_L(155,155);
    }
  else  
    {
      digitalWrite(E1,LOW);   
      digitalWrite(E2,LOW); 
    }
  }  
    
if (QRE_ValueB > 1000)
  {
  if (QRE_ValueLI > 1000 && QRE_ValueRI > 1000) //If surface under both sensors is White actuate motors forward at PWM rate of 155
    {
      advance(155,155);
    }
  else if (QRE_ValueLI < 1000 && QRE_ValueRI > 1000) //If surface under Right sensor is Black turn right to correct
    {
      turn_R(155,155);
    }
  else if (QRE_ValueLI > 1000 && QRE_ValueRI < 1000) //If surface under Left sensor is Black turn left to correct
    {
      turn_L(155,155);
    }
  else  
    {
      digitalWrite(E1,LOW);   
      digitalWrite(E2,LOW); 
    }
  }  
    
}

int LIread(){
  //Returns value from the QRE1113 
  //Lower numbers mean more refleacive -- White Surface value under 300 -- Black Surface value over 2500
  //More than 3000 means nothing was reflected.
  pinMode( QRE1113_LI, OUTPUT );
  digitalWrite( QRE1113_LI, HIGH );
  delayMicroseconds(10);
  pinMode( QRE1113_LI, INPUT );
  long timeLI = micros();

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

int RIread(){
  //Returns value from the QRE1113 
  //Lower numbers mean more refleacive -- White Surface value under 300 -- Black Surface value over 2500
  //More than 3000 means nothing was reflected.
  pinMode( QRE1113_RI, OUTPUT );
  digitalWrite( QRE1113_RI, HIGH );
  delayMicroseconds(10);
  pinMode( QRE1113_RI, INPUT );
  long timeRI = micros();

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


int Bread(){
  //Returns value from the QRE1113 
  //Lower numbers mean more refleacive -- White Surface value under 300 -- Black Surface value over 2500
  //More than 3000 means nothing was reflected.
  pinMode( QRE1113_B, OUTPUT );
  digitalWrite( QRE1113_B, HIGH );
  delayMicroseconds(10);
  pinMode( QRE1113_B, INPUT );
  long timeB = micros();

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