1
|
#!/usr/bin/env python
|
2
|
#
|
3
|
# Raspberry Pi Rotary Encoder Class
|
4
|
# $Id: rotary_class.py,v 1.2 2014/01/31 13:34:48 bob Exp $
|
5
|
#
|
6
|
# Author : Bob Rathbone
|
7
|
# Site : http://www.bobrathbone.com
|
8
|
#
|
9
|
# This class uses standard rotary encoder with push switch
|
10
|
#
|
11
|
#
|
12
|
|
13
|
import RPi.GPIO as GPIO
|
14
|
|
15
|
class RotaryEncoder:
|
16
|
|
17
|
CLOCKWISE=1
|
18
|
ANTICLOCKWISE=2
|
19
|
BUTTONDOWN=3
|
20
|
BUTTONUP=4
|
21
|
|
22
|
rotary_a = 0
|
23
|
rotary_b = 0
|
24
|
rotary_c = 0
|
25
|
last_state = 0
|
26
|
direction = 0
|
27
|
|
28
|
count = 0
|
29
|
|
30
|
# Initialise rotary encoder object
|
31
|
def __init__(self,pinA,pinB,button,callback):
|
32
|
self.pinA = pinA
|
33
|
self.pinB = pinB
|
34
|
self.button = button
|
35
|
self.callback = callback
|
36
|
|
37
|
GPIO.setmode(GPIO.BCM)
|
38
|
|
39
|
# The following lines enable the internal pull-up resistors
|
40
|
# on version 2 (latest) boards
|
41
|
GPIO.setwarnings(False)
|
42
|
GPIO.setup(self.pinA, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
43
|
GPIO.setup(self.pinB, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
44
|
GPIO.setup(self.button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
45
|
|
46
|
# For version 1 (old) boards comment out the above four lines
|
47
|
# and un-comment the following 3 lines
|
48
|
#GPIO.setup(self.pinA, GPIO.IN)
|
49
|
#GPIO.setup(self.pinB, GPIO.IN)
|
50
|
#GPIO.setup(self.button, GPIO.IN)
|
51
|
|
52
|
# Add event detection to the GPIO inputs
|
53
|
GPIO.add_event_detect(self.pinA, GPIO.BOTH, callback=self.switch_event, bouncetime=2)
|
54
|
GPIO.add_event_detect(self.pinB, GPIO.BOTH, callback=self.switch_event, bouncetime=2)
|
55
|
GPIO.add_event_detect(self.button, GPIO.BOTH, callback=self.button_event, bouncetime=200)
|
56
|
return
|
57
|
|
58
|
# Call back routine called by switch events
|
59
|
def switch_event(self,switch):
|
60
|
if GPIO.input(self.pinA):
|
61
|
self.rotary_a = 1
|
62
|
else:
|
63
|
self.rotary_a = 0
|
64
|
|
65
|
if GPIO.input(self.pinB):
|
66
|
self.rotary_b = 1
|
67
|
else:
|
68
|
self.rotary_b = 0
|
69
|
|
70
|
self.rotary_c = self.rotary_a ^ self.rotary_b
|
71
|
new_state = self.rotary_a * 4 + self.rotary_b * 2 + self.rotary_c * 1
|
72
|
delta = (new_state - self.last_state) % 4
|
73
|
self.last_state = new_state
|
74
|
event = 0
|
75
|
|
76
|
if delta == 1:
|
77
|
self.direction = self.CLOCKWISE
|
78
|
event = self.direction
|
79
|
elif delta == 3:
|
80
|
self.direction = self.ANTICLOCKWISE
|
81
|
event = self.direction
|
82
|
|
83
|
self.count = self.count + 1
|
84
|
if not (self.count % 4) and event > 0:
|
85
|
self.callback(event)
|
86
|
return
|
87
|
|
88
|
|
89
|
# Push button up event
|
90
|
def button_event(self,button):
|
91
|
if GPIO.input(button):
|
92
|
event = self.BUTTONUP
|
93
|
else:
|
94
|
event = self.BUTTONDOWN
|
95
|
self.callback(event)
|
96
|
return
|
97
|
|
98
|
# Get a switch state
|
99
|
def getSwitchState(self, switch):
|
100
|
return GPIO.input(switch)
|
101
|
|
102
|
# End of RotaryEncoder class
|
103
|
|