Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Reflection sensor, stuck in while loop! urgent


#1

Hi.

I’m making a program for a robot that corrects it’s position when it does not go perpendicular over a line. I’m using the pololu reflectance sensors and the pololu library.

The plan is to stop the motor on the side that sees the line first, until the other motor/sensor sees the line. I’m using a while loop to do this.

This is the code for one scenario:

unsigned int sensor_1 = (sensorValues[1] * 10 / 1001);
unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
if (sensor_6 >= 5)
    {
      
      printvalues();
      unsigned int sensor_1 = (sensorValues[1] * 10 / 1001);
      unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
      
      while (sensor_1 < 5)
       {
         printvalues();
         brake_A();
         motor_control(motor_B,FORWARD,50);
         unsigned int sensor_1 = (sensorValues[1] * 10 / 1001);
         unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
       }
          motor_control(motor_A,FORWARD,50);
           motor_control(motor_B,FORWARD,50);
           delay(1000);
           motor_brakefast();
           delay(1000000);
       
      }  
}

for some reason it will not go out of the while loop, even though the sensor1 clearly reads above 5.

Can you see what I’m doing wrong!? :frowning:

I would really appreciate some help


#2

Hello, steinidna.

Are you actually updating sensorValues[] by calling the appropriate Pololu library function at some point in your while loop? You didn’t post enough code for me to tell. Please read this post for tips on how to ask for help:

Also, please tell us what Pololu products you have and what type of device this code is running on.

–David


#3

Thank you for your a quick reply!
I see now that I didn’t give you enough information, I wrote this in a hurry.

The library I am using is the Pololu Reflection PololuQTRSensors.h.

I thought I was updating the sensor values by defining sensor6 in the end of the while loop to help him update his values.
unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
It looks like it doesn’t work.

Here’s the whole code:

[code]#include <PololuQTRSensors.h>

//mótorar
#define PWMA 10
#define AIN1 2
#define AIN2 3
#define BIN1 7
#define BIN2 5
#define PWMB 11
//flagg
#define CIN1 42
#define CIN2 40
#define PWMC 8
#define STBY 38
#define VCC_flagg 34
//breytur

#define motor_C 1
#define motor_A 0
#define motor_B 1
#define FORWARD 1
#define REVERSE 0
#define RIGHT 1
#define LEFT 0

//takkar
#define BUTTON_4 27
int buttonState4 = 0;

#define NUM_SENSORS 6 // number of sensors used
#define TIMEOUT 2500 // waits for 2500 us for sensor outputs to go low
#define EMITTER_PIN 35 // emitter is controlled by digital pin 2
#define VCC_skynjari 45

PololuQTRSensorsRC qtrrc((unsigned char[]) {41, 43, 37, 39, 46, 48},
NUM_SENSORS, TIMEOUT, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

int DOT = 0;
volatile int sensor_1=0;
volatile int sensor_6=0;

void setup()
{
pinMode(CIN1,OUTPUT);
pinMode(CIN2,OUTPUT);
pinMode(PWMC,OUTPUT);
pinMode(STBY,OUTPUT);
pinMode(PWMA,OUTPUT);
pinMode(AIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(PWMB,OUTPUT);
pinMode(BIN1,OUTPUT);
pinMode(BIN2,OUTPUT);
pinMode(VCC_skynjari,OUTPUT);
pinMode(VCC_flagg,OUTPUT);
//BUTTON
pinMode(BUTTON_4,INPUT);

digitalWrite(VCC_skynjari,HIGH);
digitalWrite(VCC_flagg,HIGH);
digitalWrite(STBY,HIGH);
Serial.begin(9600);
void calibration()
motor_bremsahratt();
delay(1000);
halda_flaggi();
delay(1000);
}

void loop()
{
buttonState4 = digitalRead(BUTTON_4);
motor_fastbrake();
if (buttonState4 == HIGH) {

DOT = 1;

while (DOT =1)   

{
motor_control(motor_A,FORWARD,50);
motor_control(motor_B,FORWARD,50);
unsigned int sensor_1 = (sensorValues[1] * 10 / 1001);
unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
printvalues();
if (sensor_6 >= 5)
{
printvalues();
unsigned int sensor_1 = (sensorValues[1] * 10 / 1001);
unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
while sensor_1 < 5)
{
printvalues();
brake_A();
motor_control(motor_B,FORWARD,50);
unsigned int sensor_1 = (sensorValues[1] * 10 / 1001);
unsigned int sensor_6 = (sensorValues[6] * 10 / 1001);
}
motor_control(motor_A,FORWARD,50); //the plan here is that when the robot is perpendicular to the line
motor_control(motor_B,FORWARD,50); //it drives forward for 1 second and brakes.
delay(1000);
motor_fastbrake();
delay(1000000);

  }  

}
}
}

//------ below are functions for motors and the printvalue funtion-------//

void motor_control(char motor, char direction, unsigned char speed)
{
if (motor == motor_A)
{
if (direction == FORWARD)
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
}
else
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
}
analogWrite(PWMA,speed);
}
else
{
if (direction == REVERSE) //Notice how the direction is reversed for motor_B
{ //This is because they are placed on opposite sides so
digitalWrite(BIN1,LOW); //to go FORWARD, motor_A spins CW and motor_B spins CCW
digitalWrite(BIN2,HIGH);
}
else
{
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
}
analogWrite(PWMB,speed);
}
}

void brake_A()
{
digitalWrite(AIN1,1);
digitalWrite(AIN2,1);
digitalWrite(PWMA,HIGH);
}

void brake_B()
{
digitalWrite(BIN1,1);
digitalWrite(BIN2,1);
digitalWrite(PWMB,HIGH);
}

void motor_fastbrake()
{
digitalWrite(AIN1,1);
digitalWrite(AIN2,1);
digitalWrite(PWMA,HIGH);
digitalWrite(BIN1,1);
digitalWrite(BIN2,1);
digitalWrite(PWMB,HIGH);
}

void motor_slowbrake()
{
digitalWrite(AIN1,1);
digitalWrite(AIN2,1);
digitalWrite(PWMA,LOW);
digitalWrite(BIN1,1);
digitalWrite(BIN2,1);
digitalWrite(PWMB,LOW);
}

void calibration()
{
int i;
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
for (i = 0; i < 400; i++) // make the calibration take about 10 seconds
{
qtrrc.calibrate(); // reads all sensors 10 times at 2500 us per read (i.e. ~25 ms per call)
}
digitalWrite(13, LOW);
// print the calibration minimum values measured when emitters were on

 for (i = 0; i < NUM_SENSORS; i++)
{
  Serial.print(qtrrc.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(qtrrc.calibratedMaximumOn[i]);
  Serial.print(' ');
}
Serial.println();
Serial.println();

}

void printvalues()
{
int position = qtrrc.readLine(sensorValues);
volatile int skynjari_1 = (sensorValues[1] * 10 / 1001);
volatile int skynjari_6 = (sensorValues[6] * 10 / 1001);

//qtrrc.read(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] * 10 / 1001);
Serial.print(’ ');
}
Serial.print(" ");
Serial.println(position);

}
[/code]

Some of the definitions are in Icelandic but most of it is in English.

Iv’e read something about volatile, is that something that could help me?

regards, steinidna.


#4

You are suffering from a pretty subtle problem. You’ve repeated this line of code many times in your program:

First of all, it’s bad to repeat code so much. Second, every time you write “unsigned int sensor_6” you are actually defining a NEW variable named sensor_6, which hides the other variables of the same name. Here’s an example:

int i = 0;
while(i < 5)
{
  int i = 8;
  i = i + 1;
}

The code above actually defines two variables named i. Since the two variables are different and not connected at all, this code is equivalent to:

int i = 0;
while (i < 5)   // infinite loop!
{
    int j = 8;
    j = j + 1;
}

That’s just how variable scoping works in C++. Some languages will warn you or prevent you from doing things like this, and I think GCC’s -Wshadow option will detect it and warn you.

I recommend that you stop scaling the sensorValues down. Get rid of your sensor_N variables, and just read directly from the sensorValues array. Take advantage of the full resolution the library and sensors provide.

If you really want to scale the values down, then I recommend making your own global array ( unsigned char sensor[6]; ) and using a loop to update all of its values in one place, right after you read the sensors.

–David