enter image description hereHi I have a DC motor with encoder which has a PPR count of 990 (No load RPM = 107). However, I tried to read the number of ticks (on a Raspberry Pi 3B) by rotating the wheel 1 turn and I get a PPR count way too low, let's say 200 (It varies each time). The following is my Python code.

import RPi.GPIO as GPIO
from time import sleep


enc_L = 4; tick_L = 0;  # Left motor encoder pin


def my_callback_L(channel):
    global tick_L

GPIO.setup(enc_L, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.add_event_detect(enc_L, GPIO.RISING,callback=my_callback_L)

Now I tried to do the same thing on an Arduino Nano and to my surprise, the Nano gave exactly 990 PPR. The following is my Arduino code.

const int enc_pin1 = 2;

volatile long ticks1 = 0;

int tpr = 990;     

void setup() {
  // put your setup code here, to run once:


  pinMode(enc_pin1, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(enc_pin1),countTicks1, RISING); 


void loop() {
  // put your main code here, to run repeatedly:


void countTicks1(){


So my question is why is the Pi missing encoder counts? Is it due to bouncetime? Or is there some other issue?, and how do I get the correct tick values? I need it so that I can calculate motor RPM.

3 Answers 3


Bouncetime may be part of the problem. Do you expect pulses to be received at a rate of more than one per bouncetime? I don't know what the default is.

An encoder normally has two outputs. You appear to only use one.

If you actually have an encoder try


If you are only interested in RPM try


There are at least two other factors to consider.

  1. The Arduino program is (compiled) C++, the Pi program is (interpreted) Python. A compiled program is likely to be more responsive and faster than an interpreted program.
  2. Linux is a multi-user, multi-process, multi-tasking operating system with many activities acting in parallel. The Arduino is neither multi-user, multi-process, nor multi-tasking. The one Arduino script has total control of the CPU.
  • Hi Joan, Yes the encoder has 2 outputs, but I am not interested in direction, but only in getting RPM which should be possible by using just 1 pin.
    – ArkanSaaS
    Jul 11, 2018 at 9:18
  • Also, I saw these in the morning so will give them a try. But I was thinking that I wrote a small and simple code on Arduino and it gave me correct RPM and tick counts. What might be going wrong with an RPi.
    – ArkanSaaS
    Jul 11, 2018 at 9:22
  • @Nischal Added info to answer.
    – joan
    Jul 11, 2018 at 10:17
  • Thanks Joan. Will try the class you referred earlier in the eveing. But then should I read sensor data from arduino and just just use the Pi for computing ? Does it make the Pi less powerful when dealing with Sensors ?
    – ArkanSaaS
    Jul 11, 2018 at 10:22
  • The Pi should be fine. For some tasks you might have to use C rather than Python. I expect that pigpio code will capture all the edges.
    – joan
    Jul 11, 2018 at 11:52

Bouncing means you have extra edges in the signal, so the error you get from it can only be a higher count, not lower.

De-bouncing means your software ignores the edges which come faster than expected, so it can remove those extra edges, or, if the de-bounce time is too high, ignore legitimate edges, leading to a lower count. As far as I can tell there is no de-bounce present in your code.

Since Arduino counts the edges correctly, I'd say that bouncing is not a problem here. Your Python code is simply too slow to count the pulses, so it misses most of them.

Using both A and B inputs is necessary if you need to detect rotation direction in addition to speed. If your code is already too slow to process one input, trying to use two inputs will only make things worse.


I will only cover one issue (that is not covered is existing answer).

You are only looking at one of the outputs of the encoder. This output can bounce, therefore you have a bounce filter. This filter can cause you to miss edges, and get a low count.

If you take into consideration both outputs, then you can let it bounce (you need no filter). You may get a little back and forth jitter, but that is all. You will want to put on a bounce filter to remove very high frequencies, so as to reduce load on the software (not too many events to process). However when you use only one output, then no value for the bounce filter can ever be good enough ( e.g. a stopped motor, can easily produce an oscillating output that looks like a high RPM).

Design filter value, so that it works if motor is going at some good margin faster than maximum.

  • Actually bouncetime is not mentioned in the script in the question. I believe the default to be no bouncetime but can't find any documentation (and can not be bothered to find and read the source code).
    – joan
    Jul 12, 2018 at 14:24
  • Are we talking about a hardware filter?
    – Seamus
    Aug 13, 2018 at 16:26
  • Where I said “You will want to put on a bounce filter to remove very high frequencies, so as to reduce load on the software”, then yes a hardware filter. You will need just a capacitor, and maybe a resister. (someone here should be able to direct to how to work this out.) Aug 14, 2018 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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