Skip to content

Instantly share code, notes, and snippets.

@ednisley
Created October 8, 2020 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ednisley/0219616ea751dab30b218f754695c3c1 to your computer and use it in GitHub Desktop.
Save ednisley/0219616ea751dab30b218f754695c3c1 to your computer and use it in GitHub Desktop.
Python source code: Raspberry Pi rotary encoder driver
# Rotary encoder test driver
# Ed Nisley - KE4ZNU
# Adapted from https://github.com/mivallion/Encoder
# State table from https://github.com/PaulStoffregen/Encoder
import RPi.GPIO as GPIO
class Encoder(object):
def __init__(self, A, B, T=None, Delay=None):
GPIO.setmode(GPIO.BCM)
self.T = T
if T is not None:
GPIO.setup(T, GPIO.OUT)
GPIO.output(T,0)
GPIO.setup(A, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(B, GPIO.IN, pull_up_down=GPIO.PUD_UP)
self.delay = Delay
self.A = A
self.B = B
self.pos = 0
self.state = (GPIO.input(B) << 1) | GPIO.input(A)
self.edges = (0,1,-1,2,-1,0,-2,1,1,-2,0,-1,2,-1,1,0)
if self.delay is not None:
GPIO.add_event_detect(A, GPIO.BOTH, callback=self.__update,
bouncetime=self.delay)
GPIO.add_event_detect(B, GPIO.BOTH, callback=self.__update,
bouncetime=self.delay)
else:
GPIO.add_event_detect(A, GPIO.BOTH, callback=self.__update)
GPIO.add_event_detect(B, GPIO.BOTH, callback=self.__update)
def __update(self, channel):
if self.T is not None:
GPIO.output(self.T,1) # flag entry
state = (self.state & 0b0011) \
| (GPIO.input(self.B) << 3) \
| (GPIO.input(self.A) << 2)
gflag = '' if self.edges[state] else ' - glitch'
if (self.T is not None) and not self.edges[state]: # flag no-motion glitch
GPIO.output(self.T,0)
GPIO.output(self.T,1)
self.pos += self.edges[state]
self.state = state >> 2
# print(' {} - state: {:04b} pos: {}{}'.format(channel,state,self.pos,gflag))
if self.T is not None:
GPIO.output(self.T,0) # flag exit
def read(self):
return self.pos
def read_reset(self):
rv = self.pos
self.pos = 0
return rv
def write(self,pos):
self.pos = pos
if __name__ == "__main__":
import encoder
import time
from gpiozero import Button
btn = Button(26)
enc = encoder.Encoder(20, 21,T=16)
prev = enc.read()
while not btn.is_held :
now = enc.read()
if now != prev:
print('{:+4d}'.format(now))
prev = now
@ednisley
Copy link
Author

More details on my blog at https://wp.me/poZKh-9v7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment