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

    if s in [2, 4, 11, 13]:
        pos -= 1

    if s in [3, 12]:
        pos += 2

    if s in [6, 9]:
        pos -= 2

def init():
    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))


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.

  • The Pi should EASILY count a slow input of 4000 pulses in a second, even using Python. If you have issues there is a problem in your hardware or software. The listed code is POOR - reading pin state in a callback caused by the pin is asking for trouble. – Milliways Aug 29 '20 at 2:03
  • when I try other quadrature decoders, including those in published packages that their authors figured were good enough to publish, I get the exact same symptoms – Phlip Aug 29 '20 at 3:26
  • If pigpio does not get a signal it is because you have not connected to the GPIO you think you are Perhaps you are using pins 16/18 which are GPIO 23/24. pigpio only uses GPIO numbering. – joan Aug 29 '20 at 7:36
  • I tried both BCM and BOARD numbering - 4,5 and 16,18 – Phlip Aug 29 '20 at 15:18

Try http://abyz.me.uk/rpi/pigpio/examples.html#Python_rotary_encoder_py

If it doesn't work your connections or hardware is faulty.

  • If the RPi.GPIO version of the software can see rotations, then the hardware and connections work. – Phlip Aug 29 '20 at 15:20
  • it turns out physical pins 16 and 18 are GPIO pins 23 and 24. A different GPIO pin chart called them 4 and 5. And we no longer drop counts when rotating at normal speeds. Tx; pigpio won! – Phlip Aug 29 '20 at 15:50
  • any tips how to also read the index channel? it's on pin 12, but "index" is very hard to google for – Phlip Aug 29 '20 at 20:09
  • 1
    Pin 12 is GPIO 18. There is no problem reading it. Personally I'd just add it to the existing callback and use it for sanity checking. The encoder count should be a multiple of 4096 each time an index arrives. The action you take is pretty much project specific. – joan Aug 29 '20 at 20:19
  • I moved it to GPIO 17 and it started working. Tx again! – Phlip Aug 29 '20 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.