Why are four states needed with Quadratuer encoders?

I did a search and I couldn’t find an answer to this.

First of all I want to know if my idea of how these things work is right. For each Quadratuer encored there are two digitial pins used set as inputs. So each pin can be 1 or 0 which means there are four possible combinations right? To me a wheel can have three states: forward, backward, and at rest. So what is the forth combination used for? Or is it used at all!

you are looking at the input to the encoder. The two signals are needed so the encoder can determine which way it is moving, as well as how fast its moving.

It gets better. The encoder also remembers the previous level of those two signals. Based on how they change it can then determine which way its rotating.

The output of the encoder is not really a set of states, its a vector speed (signed variable), or for some, a vector distance, clocked out at fixed intervals…

look at an actual encoder disk, think about what happens as it rotates, and it will make more sense to you.

there is a good illustration in this thread, about 3 or 4 posts down:

http://www.chiefdelphi.com/forums/showthread.php?t=40205&highlight=quadrature+encoder

Expanding on what Ken said, and using the encoder wheel he linked to (note that there are many different types of encoder wheels)…

Imagine that you have two sensors , A and B, that are placed on the radius of the encoder such that A is over the inner encoded band and B is over the outer. The way that the encoder wheel is laid out, if sampled properly, A and B will never change states at the same time.

Knowing this, the following table describes the valid state transitions. (assume 0 = dark and 1 = light)

Previous AB     Current AB
     00               01         - Counterclockwise               
     00               10         - Clockwise

     01               11         - Counterclockwise
     01               00         - Clockwise         

     11               10         - Counterclockwise              
     11               01         - Clockwise

     10               00         - Counterclockwise              
     10               11         - Clockwise

Transitions such as 00->11, 01->10, 10->01, 11->00 tell you that there was rotation, but you don’t know which direction the rotation was.

So to answer your original question, you have 4 states because there are 4 states that your encoder is reporting. :rolleyes:

Issues,
Building on what has already been presented, a quadrature encoder is one in which the outputs ( in this case two) are electrically 90 degrees apart. It is common to divide a circle into four parts and these are normally called quadrants. Quadrature is a term to show that signals are in adjacent quadrants but not opposite.
A simple encoder can be built using a wheel with half the rotation colored black and half white. By using two light sensors placed such that one is 90 degrees of rotation behind the other one you can determine not only how fast the shaft is turning but what direction. For this simple encoder, it will require at least 180 degrees (one half the wheel) of rotation to get one tach pulse and 270 degrees (more than one half the wheel) of rotation to get two tach pulses and determine the direction the shaft is moving. (See Dave’s table above.) This type of encoding is simple to use and decode with software or a few logic gates. If you add more light and dark spaces one the wheel you increase the accuracy.
For instance if you are sensing a wheel that has a circumference of 10 inches and you use a disk that is half white and half black, the minimum distance you can measure is 5 inches (10"/2 sections). If you divide the disk into 10 sections, alternating white and black, you can measure 1 inch (10"/10 sections), etc.

A good whitepaper, written by Dan Katanski of FRC240, discussing quadrature encoders can be found at http://www.chiefdelphi.com/forums/papers.php?s=&action=single&paperid=283

Thank you for the feedback. The colored wheel illistration was helpful. I still have a question. I looked at how you set up the code and I think I get it, but what edge should be set for interupt? For the machine to keep up with the state changes wouldn’t you want to interupt both when it goes from white to black and from black to white?

Absolutely, you need to catch both the rising and falling edge.

If you watch only one edge,for the sake of argument let’s use the rising edge (0->1) , you will only ever be looking at the following transitions…
00->01 00->10 01->11 10->11
Compare that to the table above and you’ll see that you’re only getting half the story. Watching only one edge will definately not work for the normal usage.

how you decode the signals will determine the resolution and max input speed of your ‘speedometer’.

Note that the drawing on the other page is only a crude illustration to show how it works. Most encoder wheels have hundreds, or thousands of marks, instead of 4 or 8.

I think you can use one of the signals as a clock, and the other as the data, if you register on both edges of the clock. Using interrupts will lower your max speed reading (when the interrrupts start to overrun each other).

Some times, you don’t always have 90 degrees between the two sensors or you don’t always have exactly 50% duty cycles (a.k.a. even ON and OFF times). In these cases, folks often ignore edges to improve on velocity calculations.

By calculating velocities based on rising edge to rising edge of the same channel (or falling to falling) you can avoid the problems associated with non-50% duty cycles and variations in phasing between A & B*.

Note that we don’t always get to spec out the encoder we’d like in an ideal world so we sometimes end up with the phasing and the duty cycle of the sensors being non-constant due to changes in velocity, temperature, voltage, etc. It is not ideal, but what is?

This tends to be more of a problem with calculating velocities than positions.

Joe J.

*you can still get a velocity calc at every edge, but you have to keep 4 different times in memory and subtract the appropriate past time from the current time. Also, you need to be careful during transitions from CCW to CW or vise versa. It is surprisingly easy to write code that blows up (or at a mininum gets the wrong answer) during direction changes.

It turns out that you only need to generate an interrupt based on one edge of one of the phases. If you set things up to interrupt on the rising edge of the A phase, you will be be notified about two state transitions: 00->10 and 01->11. The level of the B phase at the time tells you immediately which direction the encoder is turning. You only get information for one transition out of four, but that’s usually more than enough. In order to track the relative motion of the encoder continuously, the interrupt service routine just needs to increment or decrement a value based on what the B phase is.

Occasionally details in the imperfect real world make it necessary to get fancier than that, but the very simple scheme is generally sufficient.

Just to pile on, and expand a bit on what Alan says above, you only need to interrupt on one edge. Here’s the entire interrupt handler from some code I wrote:

v**oid** **Left_Encoder_Int_Handler**(**void**)
{

*// The left encoder's phase-A signal just transitioned*
*// from zero to one, causing this interrupt service*
*// routine to be called. We know that the encoder just*
*// rotated one count or "tick" so now check the logical*
*// state of the phase-B signal and increment or decrement*
*// the Left_Encoder_Count variable.*
**if** (LEFT_ENCODER_PHASE_B_PIN **==**0)
{
Left_Encoder_Count **-=** LEFT_ENCODER_TICK_DELTA;
}

**else**
****
{
Left_Encoder_Count **+=** LEFT_ENCODER_TICK_DELTA;
}

}

LEFT_ENCODER_TICK_DELTA is #define’d as either 1 or -1. This works great for velocity control and most of the time for position control. If I remember correctly, several months ago Alan mentioned that he had a problem using this scheme in his position control application because his mechanism would sometimes stop right on a tick mark and generate a bunch of spurious interrupts, which would cause problems because the phase-b signal might change before the ISR could read it. In this case you need to add some hysteresis in the form of a state machine to track the states and increment/decrement the counter correctly. This approach increases reliability at the cost of greatly increasing the time spent in the ISR, which will decrease the maximum tick-tracking rate of your encoder software. I’ll add this capability to my encoder code in the near future and update the documentation.

-Kevin

That’s not quite how the problem manifested itself. The B phase isn’t going to be changing at all when the encoder is hovering at an A phase transition, so the time it takes to read it isn’t really an issue. The actual problem is that this simple scheme only notices the 0->1 transition, and ignores the 1->0 transition that accompanies a miniscule reverse motion of the encoder. Instead of recognizing that the encoder is “vibrating” at one spot, the software ends up counting things as if the encoder were continuously moving in one direction. Our solution was to set the hardware to interrupt on both the rising and falling edges, and complicate the interrupt service routine accordingly to recognize all four possibilities instead of just two. (That was difficult because our position tracking system used three encoders, and the RC only has two digital inputs capable of being configured to interrupt on both edges.)

Kevin, Alan, thanks for your clarification.

I guess I should have been a little more clear when I used the word “absolutely”. My interpretation was that Issues intended to use both channels of the encoder to get the best resolution possible, which to my understanding, was to catch both edges of both channels.

Okay, got it. I’ll incorporate a fix in a new version of my ISRs.