Using Analog Encoder On Interupts (Arduino Uno - robotshop version)

Hello.

I have a set of single pin analog encoders that are suppose to attach to pins A0 and A1. I would like to use interupts to read them.
As the code is I have them on the digital pins anyway, and they seem to read properly when rotated by hand (The current motor speed matches what my hand was doing).

I've timed the speed of the delay and motors to give me a 20cm distance. I've calculated 20cm to be 1.59 rotations (20/(4cmPi)), which should be ~13 triggers (rotations8). I've also counted them as it ran and got the proper number.

I'm getting hundreds of triggers. and even though I set the motor speeds to match, the triggers differ greatly.

I haven't found much information on the encoders so,

  • Is it possible to use them with interrupts?
  • If not is there a better choice of encoder for two motors on a board with only two interrupts?(Uno)

These are the parts:

Encoders - http://www.robotshop.com/ca/productinfo.aspx?pc=RB-Rbo-122&lang=en-US
Rover - http://www.robotshop.com/ca/dfrobotshop-rover-tracked-robot-xbee-kit-14.html

Here is a simple code setup I'm using to figure them out:

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control
int cmL = 0;
int cmR = 0;
int leftspeed = 128; //255 is maximum speed
int rightspeed = 113;
boolean done = false;
void setup() {  
  int i;
  for (i=5;i<=8;i++)
  {
    pinMode(i, OUTPUT); 
  }
  Serial.begin(9600);
  attachInterrupt(0, LeftEncoderEvent, RISING);
  attachInterrupt(1, RightEncoderEvent, RISING);
  Serial.println("Setup complete");
}
void loop() 
{
  if (!done)
  {
    forward(leftspeed, rightspeed);
    delay(6200);
    stop();
    Serial.print("cmL:cmR - ");
    Serial.print(cmL);
    Serial.print(":");
    Serial.println(cmR);
    Serial.print("rover moved: ");
    float t = (cmR+cmL)/2;
    float r = t/8;
    float d = r*12.56627;
    Serial.println(d);
    done = true;
  }
}
void LeftEncoderEvent ()
{
  cmL ++;
}
void RightEncoderEvent ()
{
  cmR ++;
}

//Motion commands---------------------------------------------
void stop(void) //Stop
{
  digitalWrite(E1,LOW);
  digitalWrite(E2,LOW);
}
void forward(char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}
void left (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}
void right (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}

Here is the serial utput:
Setup complete
cmL:cmR - 377:899
rover moved: 1002.16(cm)

You are incrementing cmL and cmR in the ISRs, and referencing them in loop(). And, yet, they are not declared volatile. That's not good.

You never bother to reset cmL or cmR, so after a while, they will overflow and become negative. That probably won't give you values that you expect.

Hmm I need to research this volatile thing, also they are reset when the program is. Everything is supposed to stop when they reach a set value and wait for reset.

Thank you for the assistance.

Edit: I should mention that the values should only reach 15 at the most so I wasn't worried about overflow.