Gray code is normally used in encoders instead of ordinary binary code to prevent glitches. In Gray code, the number of changing bits between successive numbers is only 1. The following table shows 2 bit Gray code from 0 to 3.
Number | 2-bit Gray Code |
---|---|
0 | 00 |
1 | 01 |
2 | 11 |
3 | 10 |
Encoders typically have two outputs called A and B. When it is turned clockwise, the waveform as shown in the following figure is produced. Its phase increases from 0 to 3. When it is turned counter-clockwise, the output phases are produced in reverse order.
I have found several example programs in the Internet to read an encoder from a microcontroller. But I think, those programs are long and inefficient. The program presented here is simple, short and efficient. The resulting resolution of the program is 4 times the pulses per revolution of the encoder.
I use the state machine design. I define the output phases of the encoder 0, 1, 2 ,and 3 as states - s0, s1, s2, and s2 respectively. Then, the counting of the encoder states is shown in the following table.
Next state | Present state | Count |
---|---|---|
s0 | s0 | No change |
s0 | s1 | Down |
s0 | s3 | Up |
s0 | s2 | Don't care |
s1 | s0 | Up |
s1 | s1 | No change |
s1 | s3 | Don't care |
s1 | s2 | Down |
s3 | s0 | Down |
s3 | s1 | Don't care |
s3 | s3 | No change |
s3 | s2 | Up |
s2 | s0 | Don't care |
s2 | s1 | Up |
s2 | s3 | Down |
s2 | s2 | No change |
When the states are replaced by the corresponding binary bits, the following truth table is obtained.
Decimal number | Next state - Present state | Up | Down |
---|---|---|---|
0 | 00 00 | 0 | 0 |
1 | 00 01 | 0 | 1 |
2 | 00 10 | 1 | 0 |
3 | 00 11 | 0 | 0 |
4 | 01 00 | 1 | 0 |
5 | 01 01 | 0 | 0 |
6 | 01 10 | 0 | 0 |
7 | 01 11 | 0 | 1 |
8 | 10 00 | 0 | 1 |
9 | 10 01 | 0 | 0 |
10 | 10 10 | 0 | 0 |
11 | 10 11 | 1 | 0 |
12 | 11 00 | 0 | 0 |
13 | 11 01 | 1 | 0 |
14 | 11 10 | 0 | 1 |
15 | 11 11 | 0 | 0 |
By considering next state and present state in the truth table as binary code, it is counting up at 2, 4, 11, and 13. Similarly, it is counting down at 1, 7,8, and 14. An array can be declared to represent the truth table as follows.
int En_TruthTable[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
Arduino UNO single board microcontroller and an optical shaft encoder from VEX Robotics Design System are used in this example.
In our circuit, pin 9 of the microcontroller is connected to channel A of the encoder and pin 10 is connected to channel B. The code to get the next state (NS) from the bitwise reading of channel A and channel B is shown below.
NS = (digitalRead(pinA)<<1) | digitalRead(pinB);
As we turn the shaft, the encoder produces a series of digital pulses and the microcontroller has to constantly check and update the position everytime the next state (NS) is different from the present state (PS). If c is a variable to keep track of the encoder position, its values should reach back to zero when the encoder has been turned a complete revolution. The number of state changes for one revolution (SPR) is four times the pulses per revolution (PPR) of the encoder (SPR = 4 . PPR) .
c=(c+En_TruthTable[(NS<<2)|PS]+SPR)%SPR;The angle (a) that corresponds to c in degree ( 0 ≤ a < 360 ) is calculated as follows.
a = c * 360.0 / SPRSimilarly, the angle (b) n degree ( -180 ≤ a < 180 ) can be calculated from the angle (a).
b = a - floor(a/180)*360.
An example program is available at Rotary Encoder using Arduino to get absolute value (on GitHub).
Arduino software (IDE) is available for free and I found it very easy to use. In my case, after I have chosen the correct board and correct COM port in the "Tools" menu, it worked without any problem.
No comments:
Post a Comment
Comments are moderated and don't be surprised if your comment does not appear promptly.