Reading Quadrature input Encoder;Synchrous Logic

Hello. I have recently tried reading in a quadratuer input with the ardunio uno. I wrote software which sucessfull was able to read the A,B inputs and convert them to the amount of clicks the encoder had traveled. However, I have a problem in that the uno only has two interupts. My software requires two intrupt pins. Now, I want to read two encoders which requires four interupt pins.

I have decided that instead of upgrading the control, I was going to try and implement a hardware version. Although, I might take the first route, I found a few circuits online that implented a hardware version which would only require one interupted per encoder. I anaylzed the circuit in the excel spread sheet using state tables and output tables. I wanted to know if anyone had any experience with these type of hardware implementation and wheather or not it would work. Attached is an excel file

After anaylzing the circuit, theorectical and logically it does work, but I'm not sure practically. I'm just concerned because the flops will need there own clock which will be different from the uno's.

Thanks

Quadrature_Encoder.xlsx (30.1 KB)

Yes I have used this sort of thing in the past, I even havev a web page about it
http://www.thebox.myzen.co.uk/Workshop/Rotary_Max.html

[I'm just concerned because the flops will need there own clock which will be different from the uno's./quote]
why is that a worry, a clock is just the name of a flip flop signal, you don't need anything special.

Now, I want to read two encoders which requires four interupt pins.

You can utilize two encoders using just two interrupt pins. Just wire the channel A output signal of each encoder to a interrrupt pin and use normal digital input pins for the two channel B signals.

Lefty

But how can I tell when the B input changes?? A change in "A" does not nessarly mean a change in "B"?

budder8818:
But how can I tell when the B input changes?? A change in "A" does not nessarly mean a change in "B"?

You simply read the value of the B channel with a digitalRead() when the channel A ISR is triggered and run, then make the determination of which direction was made.

Lefty

So, if I get this straight, "B" only determines the direction? If the state of "B" changes, then there is no advance of the encoder?

Only a state change of "A" means that the encoder is advancing?

So if A goes from 0 -> 1 (And "B" is constant"), then the encoder click amount (this is a variable being stored in memory) will go from say 2 ->3 assuming forward direction.

But if "B" goes from 0-->1 (And "A" is constant), then the encoder click amount should not advance, i.e. if it was 2 then is will stay at 2.

Thanks

Do some reading on the out-of-phase nature of quadrature encoder tracks. When you see a picture of the two square "waves" it will all make sense.

Long story short:

When A goes high
  if B is high
    moving forward
  if B is low
    moving backward

But I still highly recommend looking at a diagram of the tracks to see why this is.

I think your confusion might arise from the fact that if you only go the one interrupt per encoder, you don't get the full benefit of quadrature encoding as your count only increments or decrements when the A line changes. If you use interrupts on both channels you get 4 events out of every "count" on your encoder.

With two interrupts you can catch the rising and falling edge of each pulse, and the two lines are out of phase, so four interrupts per physical stripe on a photo interrupter for example, each of which can either increment or decrement the encoder count depending on the state of the channel that did not cause the current interrupt.

If you go with one interrupt per encoder you only get twice as many encoder ticks as pulses if you are watching for both the rising and falling edge of your pulses which is still good enough for most uses.

Depending on how fast you CAN get pulses from the encoder its not totally crazy in my mind to do away with external interrupts entirely and just poll the state from a timer overflow ISR at a higher frequency than you can see encoder changes. Of course if you have high resolution encoders this is impractical, but if you don't you can do full quad decoding without worrying about only having two external interrupt pins.

I totally agree with growler. Use a timer interrupt instead of interrupt inputs is the way to go. Oversampling and the use of a state machine is the key. I have done this for my Ardubot robot http://code.google.com/p/robotfreak/wiki/Ardubot. Works great with a 1ms timer. For high resolution encoders you will need external hardware.
Here is the quadrature encode code http://code.google.com/p/robotfreak/source/browse/trunk/ardubot/QadratureEncoder.cpp.