By: Ling Dian Miao

RH2T Magazine Vol.7 Dec2010

Rotary encoder is a sensor attached to a rotating object (such as a shaft or motor) to measure rotation. By measuring rotation your robot can do things such as determine any displacement, velocity, acceleration, or the angle of a rotating sensor.


1.0 Introduction


A typical rotary incremental encoder consists of a light-emitting diode (LED), a disk, and a light detector on the opposite side of the disk (see next figure). The disk, which is mounted on the rotating shaft, has patterns of opaque and transparent sectors coded into the disk. As the disk rotates, the opaque segments block the light and, where the glass is clear, light is allowed to pass. This generates square-wave pulses, which can then be interpreted into position or motion. These pulses can be read by microcontroller as part of a PID feedback control system to determine translation to distance, rotational velocity, and/or angle of a moving robot or robot part. For instance, if you have a wheel rotating, and you want to measure the time it takes to rotate exactly 40 degrees, or if you want to know when you have traveled X distance, you can use an rotary encoder. The encoder will be fixed on your robot, and the mechanical part (the encoder wheel) will rotate with the wheel. Since the output of an encoder is a square wave, you can then count the pulses if you hook up this signal to a digital counter or microcontroller. Knowing the distance/angle between each pulse, and the time from start to finish, you can easily determine position or angle or velocity or whatever. Encoders are necessary for making robot arms, and very useful for acceleration control of heavier robots. They are also commonly used in robot for maze navigation.

clip_image004Rotary Incremental Encoder Basic working model

Rotary Encoders usually offer 100 to 6,000 segments per revolution. This means the encoder can provide 3.6 deg of resolution for 100 segments and 0.06 deg of resolution for 6,000 segments. Linear encoders work under the same principle as rotary encoders except that instead of a rotating disk, there is a stationary opaque strip with transparent slits along its surface, and the LED-detector assembly is attached to the moving body.

2.0 Quadrature Encoder

An encoder with one set of pulses is sometime not sufficient because it cannot indicate the direction of rotation. Using two code tracks with sectors positioned 90 degree out of phase (see next figure); the two output channels of the quadrature encoder indicate both position and direction of rotation. For example, if A leads B, the disk is rotating in a clockwise direction. If B leads A, the disk is rotating in a counter-clockwise direction. Therefore, by monitoring both the number of pulses and the relative phase of signals A and B, the microcontroller can track both the position and direction of rotation. In addition, some quadrature encoders include a third output channel – called a zero or reference signal – which supplies a single pulse per revolution. This single pulse can be used for precise determination of a reference position. This signal is called the Z-Terminal or the index in most of encoder. A typical, ideal quadrature signal looks like this:

clip_image006Quadrature Encoder Output

With incremental encoders, you can measure only changes in position (from which you can determine velocity and acceleration), but it is not possible to determine the absolute position of an object. Another type of encoder, called an absolute encoder, is capable of determining the absolute position of an object. Its function is similar to position feedback using variable resistor (analog output), the only differences are that it can be rotated in 360 degree and digital output. This type of encoder has alternating opaque and transparent segments like the incremental encoder, but the absolute encoder uses multiple groups of segments that form concentric circles on the encoder wheel like a bull’s-eye on a target or dartboard. The concentric circles start in the middle of the encoder wheel and, as the rings go out toward the outside of the ring, each of them has doubled the number of segments than the previous inner ring.

To make encoder measurements, you need a basic electronic component called a counter. Based on its several inputs, a basic counter emits a value that represents the number of edges (low to high or high to low transitions in the waveform) counted. Most of the Microchip PICs have this peripheral; normally Timer 0 or Timer 1 is used as external input counter. External interrupt pins (INT) can also be used for counting the pulse; the rising edge (low to high) or falling edge (high to low) is configurable. Once the edges are counted, the next thing you need to take care is how those values are converted to position, further to speed and etc. The process by which edge counts are converted to position depends on the type of encoding used. There are three basic types of encoding, X1, X2, and X4.

2.1 1X Encoding

You will be able to see the signals shown in the next figure if we are scanning from left to right ; and reverse the direction or scan from right to left on previous figure. This is a quadrature cycle and the resulting increments and decrements for X1 encoding. When channel A leads channel B, the increment occurs on the rising edge of channel A. When channel B leads channel A, the decrement occurs on the falling edge of channel A.

clip_image0081X Encoding

2.2 2X Encoding

A shortcoming of the previous method is that the count frequency is the same as the frequency of channel A. Thus, an encoder is said to have a resolution of 500 pulses per revolution (ppr) does exactly that. We can do better by using both edges of Channel A. This is not too hard to arrange in hardware but this uses up valuable board space. The equality test described just now works just as well if we are detecting falling edges. Thus we can use the same routine for both rising and falling edges and detect twice as many transitions. With 2X decoding our 500 ppr encoder can generate 1000 pulses per revolution.

clip_image0102X Encoding

2.3 4X Encoding

It is possible to do even better if we examine the edges of both channel A and channel B. There are four edges for each phase of channel A and it is possible to get 2000 pulses per revolution from our 500 ppr encoder.

clip_image0124X Encoding

When I cut out the middle part of this signals which shown in the next figure, we can see clearly that the two bit encoder field (A, B) is Gray Code Encoded. Only one of the two bits changes for any given state transition.

clip_image0144X Encoding State Transition

Furthermore, we can tell whether the wheel is turning clockwise or counter-clockwise based on the state transitions, which are mutually exclusive for the two directions, as shown in the table below.

clip_image0164X Encoding State Transition Table

Most engineers will be more comfortable with the table above representing a state transition diagram, as shown in figure below.

clip_image0184X Encoding State Transition Diagram

If you have a microcontroller with the ability to generate interrupt form external source, it is pretty simple to get the count we want. But at least it must has two external interrupt pins for 4X encoding, let’s say we use PIC18F4520 (3 external interrupt pins). Channel A is connected to the INT1/RB1 pin and channel B is connected to the INT0/RB0 pin. The sense of the interrupt is changed after each interrupt so that the routine responds alternately to rising and falling edges. On each interrupt, after determining the current state, we can get the direction by checking back the previous state and Count Value will be increased or decreased. Listing below is the example interrupt routine for PIC18F4520 and the sequence is based on the previous state transition diagram.

clip_image0204X Encoding Interrupt Routine Listing

Angle of rotation (degree) = (CountValue/XN) x 360 where N = number of pulses generated by the encoder per shaft revolution, X is the encoding type. Let’s say Rotary Encoder B-106-23983 (available from Cytron Technologies) is used, N=500ppr and we use 4X encoding, so our angle of rotation (degree) = CountValue x 0.18. This encoder outputs capable to produce up to 100 kHz pulse, it is good enough for a normal mobile robot. Your microcontroller speed might limit the maximum angular speed of your encoder due to the time for serving interrupt routine. Some of the 8-bit Microchip PIC has Quadrature Encoder Interface (QEI) feature with noise filters like PIC18F2331, PIC18F2431, PIC18F4331 and PIC18F4431. With this model of microcontroller, configure some of the related registers is sufficient; position and velocity of your encoder can be obtained directly without serving the interrupt routine. Hope this article helps in using rotary encoder. If you have any feedback, please discuss in our technical forum:


* If you like to have faster response from author regarding your inquiry/comments/feedback, please do post in our technical forum as we seldom check the comment section in tutorial site 🙂



22 thoughts on “Quadrature Encoder”

  1. I like the helpful info you supply for your articles. I’ll
    bookmark your weblog and take a look at again right here frequently.
    I’m rather sure I will learn many new stuff right here!

    Best of luck for the following!

  2. Very great post. I simply stumbled upon your blog and
    wanted to say that I’ve really loved browsing your blog posts.

    In any case I will be subscribing on your rss feed
    and I hope you write once more very soon!

  3. Thanks for the code,
    How XOR between RB1 & RB0 gives the 4 cases 0,1,2,3?As I know it should give the binary value only.

  4. It is perfect time to mak ssome plans for the future and it’s
    time to be happy. I have learn this post and if I may I wish to suggest you
    some fascinating things or tips. Maybe you could write next articles referring
    to this article. I wish to learn more things approximately it!

  5. Your state diagram is not comprehensively represented by your code;

    If there was a state change from 0, 0 to 0, 1 it would behave correctly and increment +1. However, if the next state change was 0, 1 to 0, 0 the interrupt flag is watching the other pin, so you miss it.

    The resulting symptom is a +/- 1 uncertainty is added to your count each time you change direction.

    Thanks for the code though, I’m going to use it (with two interrupts running concurrently!)

  6. Handy article.

    Remember, it is pointless buying an encoder with high resolution if your attached item can only make more course adjustments.

    Bournes also has low-tech encoders, such as the 3315, which are quite adequate for some applications and use mimal power.

  7. i’m using the incremental(RE22I) encoder in an fpga, i need to find at what velocity is the shaft rotating?
    using A and B and Z signals can i find the velocity, i have a system clock in my device(fpga) will it be useful please help.

  8. Very good work. I tested your code. It works perfectly. My requirement is like Dennis.

    (how i would be able to control a motor while having an encoder take note of the distance its traveling. when its going clockwise or anticlockwise, it shows the distance but displaying CW or CCW respectively. To be more specific could you elaborate it using an PIC16F877A or 18F452 and a MD motor driver.)

    Thanks a lot.

  9. i understand the logic, and its a good work. could you please advice on how i would be able to control a motor while having an encoder take note of the distance its traveling. when its going clockwise or anticlockwise, it shows the distance but displaying CW or CCW respectively. To be more specific could you elaborate it using an PIC16F877A and a MD motor driver.

Leave a Comment

Your email address will not be published.

Share this Tutorial

Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest
Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest

Latest Tutorial

TinyML on Arduino using Edge Impulse
DIY Interactive Robot Using REKA:BIT With Micro:bit
BLTouch Installation for Ender 3 with 32-bit V4.2.2 Board
Pick and Send Random Meal’s Option and Locations through Telegram Bot Using Grove WiFi 8266 on micro:bit
DIY Automated Vacuum Cleaner Using REKA:BIT With Micro:bit
Tutorials of Cytron Technologies Scroll to Top