You want to detect rotation using a rotary encoder.
Use a rotary (quadrature encoder) connected to two GPIO pins, as shown in Figure 11-9.
To make this recipe, you will need:
• Breadboard and jumper wires (see “Prototyping Equipment” on page 380)
• Rotary encoder (quadrature type; see “Miscellaneous” on page 382)
This type of rotary encoder is called a quadrature encoder, and it behaves like a pair of switches. The sequence in which they open and close as the rotary encoder’s shaft is turned determines the direction of rotation.
The rotary encoder shown has the center lead as the common lead and the two leads on either side as A and B. Not all rotary encoders use this layout, so check the pinout on the datasheet for the rotary encoder that you are using. The issue is often confused further because many rotary encoders include a push switch, which will have a separate pair of contacts.
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called rotary_encoder.py.
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) input_A = 18 input_B = 23 GPIO.setup(input_A, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(input_B, GPIO.IN, pull_up_down=GPIO.PUD_UP) old_a = True |
The test program simply counts up as you turn the rotary encoder clockwise and counts down when you rotate it counterclockwise.
pi@raspberrypi ~ $ sudo python rotary_encoder.py 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 |
Discussion
Figure 11-10 shows the sequence of pulses that you will get from the two contacts, A and B. You can see that the pattern repeats itself after four steps (hence the name quadrature encoder).
When rotating clockwise (left to right in Figure 11-10), the sequence will be:
When rotating in the opposite direction, the sequence of phases will be reversed.
The Python program listed previously implements the algorithm for determining the rotation direction in the function get_encoder_turn. The function will return 0 (if there has been no movement), 1 for a rotation clockwise, or -1 for a rotation counterclockwise. It uses two global variables, old_a and old_b, to store the previous states of the switches A and B; by comparing them with the newly read values, it can determine (using a bit of clever logic) which direction the encoder is turning.
The sleep period of 1 millisecond is to ensure that the next new sample does not occur too soon after the previous sample; otherwise, the transitions can give false readings.
The test program should work reliably no matter how fast you twiddle the knob on the rotary encoder; however, try to avoid doing anything time-consuming in the loop, or you may find that turn steps are missed.
See Also
You can also measure the rotated position of a knob by using a variable resistor with the step response method (Recipe 12.1) or by using an analog-to-digital converter (Recipe 12.4).
Table A-3. Prototyping equipment | |
Description | Suppliers |
M-M jumper wires | SparkFun: PRT-08431, Adafruit: 759 |
M-F jumper wires | SparkFun: PRT-09140, Adafruit: 825 |
F-F jumper wires | SparkFun: PRT-08430, Adafruit: 794 |
Half-sized breadboard | SparkFun: PRT-09567 Adafruit: 64 |
Pi Cobbler | Adafruit: 1105 |
Table A-9. Miscellaneous | |
1200mAh LiPo battery | Adafruit: 258 |
5V relay | SparkFun: COM-00100 |
5V panel meter | SparkFun: TOL-10285 |
Servo motor | SparkFun: ROB-09065, Adafruit: 1449 |
5V 1A power supply | Adafruit: 276 |
Low power 6V DC motor | Adafruit: 711 |
0.1 inch header pins | SparkFun: PRT-00116, Adafruit: 392 |
5 V 5-pin unipolar stepper motor | Adafruit: 858 |
12 V, 4-pin bipolar stepper motor | Adafruit: 324 |
Magician chassis with gearmotors | SparkFun: ROB-10825 |
Tactile push switch | SparkFun: COM-00097, Adafruit: 504 |
Miniature slide switch | SparkFun: COM-09609, Adafruit: 805 |
Rotary encoder | Adafruit: 377 |
4×3 keypad | SparkFun: COM-08653 |
Piezo buzzer | SparkFun: COM-07950, Adafruit: 160 |
Phase | A | B |
1 | 0 | 0 |
2 | 0 | 1 |
3 | 1 | 1 |
4 | 1 | 0 |
Phase | A | B |
4 | 1 | 0 |
3 | 1 | 1 |
2 | 0 | 1 |
1 | 0 | 0 |