EENG 383
Rotary Encoders
A rotary encoder is an input device which a user can
rotate. The rotation of the input knob is usually
accompanied by the knob settling into a preferred
position with a sort of snap. This preferred
position is referred to as a detent. The number of
detents per rotation is an attribute which varies
between rotary encoders. Typical values include 24
and 36 detents per rotation.
Beyond its input knob, a rotary encoder will usually
have 3 pins. These three pins can be thought of as
part of a simple switching system. The schematic
below shows a rotary encoder in yellow and the
external parts added to make it function correctly.
From this figure you can see that when a switch is open
the corresponding output signals is pulled high to logic
1. The resistors and capacitors are put in this circuit
at the manufactures recommendation in order to eliminate
switch bouncing. When a switch is open, the corresponding
output signal goes to logic 0. The correspondence between
the rotation of the input know and the pattern of outputs
displayed on the two signal outputs forms what is called
a quadrature output.
The two switches inside of a rotary encoder is built from
an encoder wheel, which is a a circular plate with a funny
shaped copper pattern. This copper pattern is attached to
the common pin of the encoder. The two other pins are
attached to copper contacts which drag against the encoder
wheel. Sometimes these contacts make contact with the common
pin and sometimes they don't. In the figure below a section
of the encoder wheel has been removed. The shaded section
of the wheel is attached to the common pin. The two other
contact pins (called channel a and channel b) are shown.
In their current configuration, the contact pins are not
attached to the common pin, hence output a logic 1. Imagine
that the contacts both moved to the left, over the 7.5
degree mark. Then channel a would output a 1, while
channel 0 would output a zero. As the contacts progressed
further to the left they would sweep out the pattern
shown in the table below.
angle | channel a | channel b |
11.25 | 1 | 1 |
7.50 | 0 | 1 |
3.75 | 0 | 0 |
0.00 | 1 | 0 |
The binary pattern shown in this table should look
familiar, its the order used in the arrangement of cells in a
kmap. Why is this significant? Because the cells of a
kmap were arranged so that
adjacent cells had
binary representation that differed by a single bit.
This is important, because if a rotary encoders outputs
changed by two bits then its entirely possible that
one of the two bits would change first, possibly causing
confusion about the current state of the encoders position.
Its clear that the figure above only shows a segment
of the encoder wheel, but how did we arrive at the
angles shown. Well, this encoder has 24 detents per
revolution. This implies
that there are 15 degrees between consecutive detents.
Since the transition between consecutive detents takes
the encoder through 4 patterns, then there are 3.75 degrees
between consecutive patterns.
Now, lets get back to a statement that was made earlier,
"the rotation of the input know and the pattern of outputs
displayed on the two signal outputs forms what is called
a quadrature output." What does it mean to say a rotary
encoder has quadrature outputs. Well if you plot a
timing diagram of the channel a and channel b outputs
through time as the encoder know is rotated, you would see
that the two channel are 90 degree out of phase with one
another. This means that if we shifted one of the channels
90 degree the two channels would be congruent.
The phase of the two channels of output gives the engineer
valuable information about the direction of rotation.
For example in the figure above, assume that the encoder
knob is hooked up to the encoder wheel and that the
contacts are stationary. If the wheel was rotated
in a clockwise (cw) direction then the outputs would
change from 00 to 10 (outputs are listed with
channel a in the msb and channel b in the lsb). Hence
anytime that you see a 00 to 10 transition on the
outputs you know that the know has been rotated in
a clockwise direction. Similarly, if you see the encoder
outputs transition from 00 to 01 then you know that the
know has been rotated in a cc direction.
Firmware
The encoder is assume to be configured with all
the external hardware required to make it operate correctly.
Furthermore, the PIC is assume to be configured as follows.
Channel a and channel b to the port b are wired up to the
interrupt on change pins (RB4-RB7). The PIC is configured
to generate an interrupt when one of these inputs changes.
Assume that the encoder pins are aliased to
A and
B.
Write a program which sets a global variable
dir
to 1 when the encoder rotates in a cw direction and -1 when
rotated in a ccw direction. Main may clear the
dir
variable so that it be notified when the wheel is
moved.
#int INT_RB
//------------------------------------
// RB_ISR
// output: 1 if rotation was cw (smaller angles)
// -1 if rotation was ccw (larger angles)
// 0 if rotation was illegal
//------------------------------------
void RB_ISR() {
static unsigned int8 oldA, oldB;
if (oldA == 0) {
if (oldB == 0) {
if (A == 0) {
if (B == 1) dir = -1;
else dir = 1;
} else {
.
.
.
} // end RB_ISR
#int INT_RB
//------------------------------------
// RB_ISR
// output: 1 if rotation was cw (smaller angles)
// -1 if rotation was ccw (larger angles)
// 0 if rotation was illegal
//------------------------------------
void RB_ISR() {
encoder[16]={0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static unsigned int8 index;
index = (index << 2) & 0x0F;
index = index | (A << 1);
index = index | B;
dir = encoder[index];
} // end DIR