# How to calculate how far the robot has traveled using two encoders?

Hi! I am still new to Arduino. I really need help for how to calculate the distance that the wheels that have traveled using two encoders. I have been reading many different tutorials about the encoders, but I am still really confused for how to approach it. So far I have two codes for the left side and right side of the wheels.

Left

``````//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 6;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

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

pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);

digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
//Do stuff here

Serial.println(encoderValue);
delay(100); //just here to slow down the output, and show it will work  even during a delay
}

void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit

int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

lastEncoded = encoded; //store this value for next time
}
``````

Right

``````//these pins can not be changed 2/3 are special pins
int encoderPin1 = 3;
int encoderPin2 = 5;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

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

pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);

digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
//Do stuff here

Serial.println(encoderValue);
delay(100); //just here to slow down the output, and show it will work  even during a delay
}

void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit

int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

lastEncoded = encoded; //store this value for next time
}
``````

Thank you very much

Moderator edit:
`</mark> <mark>[code]</mark> <mark>`

`</mark> <mark>[/code]</mark> <mark>`

Which Arduino are you using? The comments about the interrupt pin numbers are correct for the 328-based Arduinos, but do not match the pins you actually use.

Do you really have two Arduinos? One for the left side and one for the right side?

The encoders are not measuring distance. They are counting turns. If the wheels being turned never slip (an unrealistic assumption), then the encoder values can tell you how far the vehicle has moved, IF you know the wheel diameter and the number of pulses per revolution.

PaulS: Which Arduino are you using? The comments about the interrupt pin numbers are correct for the 328-based Arduinos, but do not match the pins you actually use.

Do you really have two Arduinos? One for the left side and one for the right side?

The encoders are not measuring distance. They are counting turns. If the wheels being turned never slip (an unrealistic assumption), then the encoder values can tell you how far the vehicle has moved, IF you know the wheel diameter and the number of pulses per revolution.

I'm only using one Arduino, the Arduino that I'm using is Arduino Duemilanove w/ Atmega328. The encoder has 24 pulses per revolution, so with two encoders, overall will have 48 pulses per revolution. My idea is that the robot will travel in a curve path where the steering angle is fixed, so the wheels on the left and right, one will travel more and one will travel less. I am trying to combine these two codes to get the actual distance that the robot is traveling.

I think the best approach here is to use pin change interrupts (is there a library for these?).

Pin change interrupts let you have a single interrupt routine that is triggered whenever any of a set of pins you specify changes - you could then in the routine test the left encoder and right encoder separately and maintain the counts.

The body of the code just has to add left distance to right distance to get a true measure of the distance travelled by the centre of the axle.

My idea is that the robot will travel in a curve path where the steering angle is fixed, so the wheels on the left and right, one will travel more and one will travel less. I am trying to combine these two codes to get the actual distance that the robot is traveling.

As if it were not difficult enough to determine how far the robot has travelled when it is moving in a straight line, you want to do it when it is moving on a curved path. Is there a reason for this ? How are you going to control the curve ?

I have been experimenting with a 2 wheeled robot with an encoder on each wheel which uses a PID to attempt to keep it running straight. Even when the wheels rotate at the same rate, compensated for by the PID, the robot does not exactly move in a straight line. Part of the reason will be the wheels slipping and also the fact that the wheels are not exactly the same diameter.

Good luck with controlling and measuring a curved path.

Hi! I am still new to Arduino. I really need help for how to calculate the distance that the wheels that have traveled using two encoders. I have been reading many different tutorials about the encoders, but I am still really confused for how to approach it. So far I have two codes for the left side and right side of the wheels.

Left

``````//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 6;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

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

pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);

digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
//Do stuff here

Serial.println(encoderValue);
delay(100); //just here to slow down the output, and show it will work  even during a delay
}

void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit

int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

lastEncoded = encoded; //store this value for next time
}
``````

Right

``````//these pins can not be changed 2/3 are special pins
int encoderPin1 = 3;
int encoderPin2 = 5;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

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

pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);

digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
//Do stuff here

Serial.println(encoderValue);
delay(100); //just here to slow down the output, and show it will work  even during a delay
}

void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit

int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

lastEncoded = encoded; //store this value for next time
}
``````

I’m only using one Arduino, the Arduino that I’m using is Arduino Duemilanove w/ Atmega328.
The encoder has 24 pulses per revolution, so with two encoders, overall will have 48 pulses per revolution.
Each encoder is mounted by robot’s two back wheels, as the wheel moves, the rotary encoder will move to.
My idea is that the robot will travel in a curve path where the steering angle is fixed, so the wheels on the left and right, one will travel more and one will travel less.
I am trying to combine these two codes to get the actual distance that the robot is traveling.
Thank you very much

Moderator edit:
`</mark> <mark>[code]</mark> <mark>`

`</mark> <mark>[/code]</mark> <mark>`

Distance = number of turns * circumference of wheel

johnwasser: Distance = number of turns * circumference of wheel

I know that, but I just don't know how to build the relationship between these two codes.

@OrzII, do not cross-post.

I think that you are making this too complicated, at least to start with. Forget using 2 encoders for now and concentrate on one of them on one wheel.

Connect the encoder to an interrupt pin on the Arduino Write an ISR that adds 1 to a volatile variable when the interrupt is triggered by a change on that pin then

``````start of loop
if the interrupt counter equals number of interrupts per revolution
distance travelled = wheel circumference
set interrupt counter to zero
end of if
end of loop
``````

You can extend this to using an encoder on each wheel and average the distance each of them travels over time or use the difference between them for other purposes if that is what you want to do.

So far I have two codes for the left side and right side of the wheels.

But, you don't have two Arduinos, so having two codes is pointless. Unless you plan to acquire a second one.

Each of those codes makes erroneous assumptions about how the encoders are connected.

How are the encoders actually connected?

Unless your Arduino is a Mega, it only has 2 external interrupt pins, and you need 4 to read two encoders the way that you are reading them (assuming that they are wired per the code rather than the names/comments).