We have a US Digital S5-4096-250-IE-S-D rotary quadrature encoder. I use the following standard snip of Python to count signals from it:
from RPi import GPIO
PIN1 = 16
PIN2 = 18
pos = 0
state = 0
# Inspired by Paul Stoffregen's excellent Arduino library Encoder:
# https:#github.com/PaulStoffregen/Encoder
def pin_isr(whatever):
p1val = GPIO.input(PIN1)
p2val = GPIO.input(PIN2)
global pos, state
s = state & 3
if p1val > 0:
s |= 4
if p2val > 0:
s |= 8
state = s >> 2
if s in [1, 7, 8, 14]:
pos += 1
return
if s in [2, 4, 11, 13]:
pos -= 1
return
if s in [3, 12]:
pos += 2
return
if s in [6, 9]:
pos -= 2
return
def init():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN1, GPIO.IN)
GPIO.setup(PIN2, GPIO.IN)
GPIO.add_event_detect(PIN1, GPIO.BOTH, callback=pin_isr, bouncetime=1)
GPIO.add_event_detect(PIN2, GPIO.BOTH, callback=pin_isr, bouncetime=1)
# Show position every second
if __name__ == "__main__":
from time import sleep
while 1:
print('%d' % (pos / 4))
sleep(1)
init()
The problem is, if I rotate the encoder's wheel extremely slowly, we can count all the way up to ~4096 in one revolution.
But if I rotate the wheel at the speed we expect our operators to use it, like 1-3 seconds per revolution, I can only count up to ~200.
This implies the GPIO library receives too many signals for Linux to successfully schedule them all, and it throws them away.
Should we throw hardware at the problem by going to a rotary encoder with a coarser resolution?
Simple hacks like coding in C, or raising priority with sudo nice -15 ...
, don't help. And pigpio never gets a signal.