code not being processed for certain values on encoder sensor

I am trying to test my encoder sensor distance calculation by making the robot move a certain distance and stop when it has reached the desired distance. In this case the distance for testing is 20cm. My problem is when I change a certain variable value nothing gets displayed on the serial monitor and the robot just keeps moving forward. The problem is with the "pprev" value. In the code below the problem occurs, however if i comment out the float pprev = 333.33; and use the line above it, it works but its not the correct distance. What could be the problem?

int encoder_pin = 3;  // The pin the encoder is connected           
unsigned int rpm;     // rpm reading
volatile byte pulses;  // number of pulses
unsigned long timeold; 
// The number of pulses per revolution
// depends on your index disc!!
//float pprev = 166.67;
float pprev = 333.33;
int distance;
float rev;
float dprev=18.84;


//motor pins
const int Motor1Pin1 = 8;
const int Motor1Pin2 = 9;
const int Motor2Pin1 = 10;
const int Motor2Pin2 = 11;

int flag;
int led=5;


void setup()
 {
   Serial.begin(9600);
     //Use statusPin to flash along with interrupts
   pinMode(encoder_pin, INPUT);
   
   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(1, counter, FALLING);
   // Initialize
   pulses = 0;
   rpm = 0;
   timeold = 0;

   //define Motor Pins
    pinMode(Motor1Pin1, OUTPUT);   
  pinMode(Motor1Pin2, OUTPUT);   
  pinMode(Motor2Pin1, OUTPUT);   
  pinMode(Motor2Pin2, OUTPUT); 
  
  pinMode(led,OUTPUT);
 }

 void loop()
 {
   
   while (flag!=1)
   {
     GoForward();
   }
  
   //Write it out to serial port
   Serial.print("PULSES = ");
   Serial.println(pulses);
//   distance = pulses/ppcm;
   Serial.print("DISTANCE = ");
   Serial.println(distance);


  }

 void counter()
 {
    //Update count
      pulses++; 
  rev=pulses/pprev; 
distance =rev*dprev; 
if (distance>=20)
{
 digitalWrite(led,HIGH) ;
Stop();
flag=1;


}

  else {
  GoForward();
 
  digitalWrite(led,LOW) ;
}
}

 
 //                MOTOR FUNCTIONS

void GoForward(){
  digitalWrite(Motor1Pin2, LOW);
  digitalWrite(Motor1Pin1, HIGH);
  digitalWrite(Motor2Pin2, LOW);
  digitalWrite(Motor2Pin1, HIGH);
}

void GoBackward(){
  digitalWrite(Motor1Pin1, LOW);
  digitalWrite(Motor1Pin2, HIGH);
  digitalWrite(Motor2Pin1, LOW);
  digitalWrite(Motor2Pin2, HIGH);
}

void GoLeft(){
  digitalWrite(Motor1Pin1, LOW);
  digitalWrite(Motor1Pin2, HIGH);
  digitalWrite(Motor2Pin2, LOW);
  digitalWrite(Motor2Pin1, HIGH);
}

void GoRight(){
  analogWrite(Motor1Pin2, LOW);
  analogWrite(Motor1Pin1, HIGH);
  analogWrite(Motor2Pin1, LOW);
  analogWrite(Motor2Pin2, HIGH);
}


void Stop(){
  digitalWrite(Motor1Pin2, LOW);
  digitalWrite(Motor1Pin1, LOW);
  digitalWrite(Motor2Pin1, LOW);
  digitalWrite(Motor2Pin2, LOW);
}

royal_flush:
I am trying to test my encoder sensor distance calculation by making the robot move a certain distance and stop when it has reached the desired distance. In this case the distance for testing is 20cm. My problem is when I change a certain variable value nothing gets displayed on the serial monitor and the robot just keeps moving forward. The problem is with the “pprev” value. In the code below the problem occurs, however if i comment out the float pprev = 333.33; and use the line above it, it works but its not the correct distance. What could be the problem?

you keep track of pulses in a byte (0…255);

pprev (pulses per revolution) = 333.3, so, 255/333.3 <1, The wheel will never rotate one Whole revolution. and since you define dprev (distance per revolution) to 18.84, the maximum calculated distance the robot moves is (255/333.3*18.84)= 14.41. It never reaches 20.

change volatile byte pulses; to volatile uint16_t pulses; this would all about 190 revolutions of the wheel to be counted.

Chuck.

This is the first time I'm getting a direct and clear answer on these forums. Thanks a lot Chuck! fixed the problem.

But on a seperate note. It seems my caibration values for pprev or the dprev. i got these values from the website indirectly.

the pprev i got based on the fact that theyve mentioned its 333.33 CPR. but im guessing it should be half that since im counting only falling. and the dprev i got by measuring the radius of the wheel, 3 cm and using to get circumference. but when i test it by making it move 20 cm it doesnt move the required distance. any better way of doing this?

actually after a series of tests i do get an approximate answer by using float pprev = 83.33; i did this by halving the above value and it gives me close to correct results now. would appreciate your feedback on how i could further improve the accuracy though

This product has an encoder which can produce 333.33 quadrature counts per revolution. These encoders can be read in different ways. Some algorithms read 1/4 of the available pulses (83.33), others read 1/2 (166.67) of them, and some can read all of them.

Your code with an interrupt FALLING on only one of the two available output pins is only reading 1 in 4 of the available pulses.

Check out http://playground.arduino.cc/Main/RotaryEncoders
for information on some alternatives to what you are doing.

royal_flush:
This is the first time I'm getting a direct and clear answer on these forums. Thanks a lot Chuck! fixed the problem.

But on a seperate note. It seems my caibration values for pprev or the dprev. i got these values from the website indirectly.
Pololu - Dagu Rover 5 Tracked Chassis with Encoders
the pprev i got based on the fact that theyve mentioned its 333.33 CPR. but im guessing it should be half that since im counting only falling. and the dprev i got by measuring the radius of the wheel, 3 cm and using to get circumference. but when i test it by making it move 20 cm it doesnt move the required distance. any better way of doing this?

You will have to post a schematic and datasheets for your robot. Those calibration value are unique to your configuration.

The dprev (distance per revolution) can be calculated by measuring the wheel. circumference = diameter * pi.

pprev (pulse per revolution) depends on your sensor( number of holes in the shadow mask, bumps on a cam, teeth on a gear (magnetic pickup))

To find these values, measure the wheel, mark that distance on a surface, move the robot over that distance while counting pulses.

chuck.