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.