Programming Encoders - Dagu Rover 5

I recently bought the Rover 5 from sparkfun and I am trying to create a library for the encoders. So far I am able to just do raw counts but it is the count of both encoders for 1 wheel. The motor controller has a XOR of both encoders so that you only need one pin. I have been reading this site to see how to use that and figure out my speed and distance.

http://letsmakerobots.com/node/24031

Can anyone help turn the example into code?

Or should I just use the separate outputs and use something like the Teensy encoder library.

Thanks

The XOR doesn't let you get by with one pin. It lets you get by with one interrupt. You still need two data pins to tell what direction the encoder moved.

int QEM [16] = {0,-1,1,2,1,0,2,-1,-1,2,0,1,2,1,-1,0};               // Quadrature Encoder Matrix
const int Input0A = 4; 
const int Input0B = 5;

volatile unsigned char Old0, New0;
volatile long Position0 = 0;

void ISR0()
    {
    Old0 = New0;
    New0 = digitalRead (Input0A) * 2 + digitalRead (Input0B);           // Convert binary input to decimal value
    Position0 += QEM [Old0 * 4 + New0];
    }

Repeat for a second encoder.

Ooooooohhhh really.... hmm so it would use 3 pins for 1 motor? Should I just use the separate outputs with 1 being connected to an interrupt? The Teensy library supports this.

Right now I am using a UNO with 2 interrupts but I have a Mega lying around I can try. The final build will be using a Teensy 2.0 which has 4 interrupts.

So each interrupts goes to the XOR output and then you use 2 more pins to read each encoder.

Okay this makes way more sense now.

That is a lot of pins lol. so 12 pins just for 4 encoders....

Thanks for the code I will try it.

The QEM array would be 1 for each motor?

So this just gives direction right?

How would I get distance and speed?

I am so confused lol...

I have some example code on this page for that exact device (Rover 5):

http://gammon.com.au/forum/?id=11506

Half-way down is stuff for reading the encoders.

You can use one pin (per wheel) but that just gives the speed. That might be all you need, the wheel is unlikely to be going the opposite way to the power you are applying to it.

On the Uno (and similar) you only get two external interrupts (D2/D3) so you can only read two wheels that way. However you could use pin-change interrupts, or make do with two wheel speeds (one on each side) to get the general idea of where the car is going (especially if you have the tracks version).

MobileWill: The QEM array would be 1 for each motor?

So this just gives direction right?

How would I get distance and speed?

All of the encoders can share the same QEM array. It is just used to map previous an current input states to step and direction.

The "Position0" value accumulates steps for encoder 0 so it is a measure of distance. Divide change in distance by time to get speed or measure time between steps to get speed. Time between steps gives a more immediate answer but can go wonky if you stop at a point where one of the sensors is on the edge of flipping. This can cause a stream of +1,-1,+1,-1... steps which, if you only look at the time between them might look like a very high speed. Perhaps only measure the time between steps if the direction is the same as the previous step.

[quote author=Nick Gammon link=topic=93345.msg701524#msg701524 date=1329970548] I have some example code on this page for that exact device (Rover 5):

http://gammon.com.au/forum/?id=11506

Half-way down is stuff for reading the encoders.

You can use one pin (per wheel) but that just gives the speed. That might be all you need, the wheel is unlikely to be going the opposite way to the power you are applying to it.

On the Uno (and similar) you only get two external interrupts (D2/D3) so you can only read two wheels that way. However you could use pin-change interrupts, or make do with two wheel speeds (one on each side) to get the general idea of where the car is going (especially if you have the tracks version). [/quote]

Thanks for the link to your code. I ended up creating a class for the motors and embedding the Teensy encoder class inside of it. But it only give encoder ticks+-.

I didn't use the XOR output and just the 2 encoder separate outputs with 1 being connected to a interrupt pin on the Mega 2560 and the 2nd on a regular digital pin, later will be a teensy2.0 ++

I was looking at your code to calculate speed. By having it constantly check speed does it affect encoder counts and since you reset the tick counts how would you calculate distance?

You could have more than one count. In my case I reset every 10th of a second so that a count a minute ago wouldn't affect the "current" speed. After all, speed is "ticks over time". The longer the time, the more you are averaging it.

You could simply have a second counter which is total distance.