OK, last time we were getting into the surprisingly simple inner workings of the rotary encoder. What’s still an unknown is exactly how the outputs of the encoder give a consistent gray code output depending on the direction the encoder is being rotated. Previously we stated that the encoder outputs A & B are two switches. While this holds true conceptually, rotary encoders use a different concept that only mimics that of simple switches.
Early Rotary Encoders
A standard SPST switch has the unfortunate drawback of contact bounce and can cause headaches in certain applications where a switch state might be sampled at a high frequency. An early style for the rotary encoder involved having concentric copper rings/contacts around a PCB inside with a wiper for each individual ring providing an output according to the gray code pattern the rings form.
This did work fairly well, but suffered from contact bounce. The design did not scale up well when it came to increasing resolution or adding detents to the encoder. The next evolution for rotary encoders used light and in some cases magnets to produce the same results…without contact bounce!
Optical Rotary Encoders
These optical rotary encoders took advantage of light in the form of an LED and photodiode/photocell to detect the light. This worked in conjunction with a disk between the LED and detector that consisted of a pattern of transparent and opaque areas. As the disk rotates it either blocks or allows the LED light to pass through. The arrangement of these transparent and opaque areas are identical to the original style of concentric rings forming a gray code pattern. This method scaled better with increased resolution and detents as it was easier to focus as well as sense emitted light to a small point.
Rotary Encoder Resolution
With contact bounce eliminated, it also allowed for higher resolution disks. With all this talk about resolution, we better figure out exactly what resolution means to a rotary encoder. A 2-bit gray code pattern has 4 states which is a poor ‘resolution’ for sensing 360 degrees of rotation. That translates to only being able to sense 90 degrees (or 1/4 turn) at a time. Fortunately gray code has a repeating pattern that allows you repeat the pattern around the encoder wheel as many times as you see fit to increase your resolution.
For example: If you were to repeat a gray code pattern 24 times around your encoder wheel you would be able to detect rotation down to 3.75 degrees or almost 1/100th of a turn. Having a resolution that precise on what might just be a manual knob you’d rotate with your fingers is not entirely useful on its own. A highly sensitive encoder will register rotation from the slightest touch. The encoder could even register by mistake if you happen to accidentally brush the knob with your finger reaching for another button. However, the advantage of high resolution allows the device to very quickly determine direction of rotation.
Higher resolution encoders are used in conjunction with detents as a way of holding a position of the shaft/knob at a specific point. Jitter in the output is avoided with detents when releasing the knob or from accidental touches. Detents also provide a more pleasing tactile feedback to the user who can physically feel the speed with which they are rotating the knob as each detent is passed.
Above, the black disk has many detents around the perimeter. The detents match the bump in the copper ring on the mating piece. This provides distinct stopping points and tactile feedback while rotating the encoder shaft.
A Real Example
The below image shows what a disk in an optical rotary encoder might look like. The inner ring is the MSB or signal A of the graycode sequence, and the outer ring is the LSB or signal B of the sequence. As the wheel rotates, a 2-bit code is formed on the signal outputs as the solid or transparent areas block or pass light through to a photo detector. Also note the darker blue dots which represent the detents on the encoder. This encoder wheel has 24 detents.
I don’t want to say in all cases, but in most cases you will find an encoder will have the same number of detents as there are repeated graycode patterns around the wheel. This is called PPR or pulses per revolution. If you were to scope one of the outputs of the encoder you would see a square wave with 24 pulses per rotation of the knob. Looking at both outputs you would see two identical waveforms slightly out of phase.
Here is a capture from the rotary encoder outputs on my scope when rotating the encoder clockwise:
Here we have the same situation, except the encoder is being rotated counter clockwise.
Lastly, we have a capture of the encoder outputs where I have rotated the knob quickly:
This is a 24 PPR encoder, the 15 pulses on the screen mean I have turned the encoder 2/3rds of a rotation. Notice the obvious frequency shifts in the waveform through the rotation. Accelerating from the start (yellow highlight), to my maximum rotation speed in the middle (red highlight) and the quick deceleration at the end where I finished rotating the knob and let go (green highlight).
Sampling the Rotary Encoder
As you can tell, the output of a rotary encoder will be changing quite fast. You must sample the output pins of the encoder fast enough to register even the quickest fingers turning the knob. If the knob and subsequently the output values are changing faster than you are sampling them, you will miss steps. Missed steps are bad because the code will not be able to accurately determine the direction the encoder is rotating.
Fortunately, we don’t have reflexes as fast as a microcontroller and it is an easy feat to sample at such a rate. The fastest you may be able to rotate a encoder knob would be maybe 200ms for a complete turn. This would equate to (4 states between detents with 24 detents) 96 separate states in one rotation and the output changing states every 2ms. The Nyquist Sampling Theory suggests sampling at twice the highest expected frequency being sampled. Following Nyquist by reading the encoder outputs every millisecond ensures that even the quickest knob couldn’t fool your sampling code.
Now, you efficiency types might be thinking…”continuously sampling a rotary encoders outputs seems very wasteful if most of the time the encoder sits idle!”, and you would be right. It would be silly to use up all that processing power sampling something that very rarely changes. This is where interrupts become our best friend!
Interrupts act as a motion alarm when monitoring the state of the encoder to detect any changes. There is no need to reserve ANY processing power towards the encoder when it’s idle not needing sampling. The microcontroller will immediately stop what it is doing to start sampling the encoder outputs when the interrupt occurs. The interrupt handling code can then react accordingly at that moment.
There you go!
That covers it for rotary encoders as far as how and why they work. If the REAL reason you are here is to actually put one to use, fear not! Our third installment on rotary encocders will dive right into connecting one of these devices up to an Arduino. Then we will beat our encoder into submission with some code. Till then…
Read part three here: