I am again reposting my question.

I am working on a hobby project and I have written the code to take encoder data and calculate the motor RPM which works fine. But sometimes it is very strange that I stop getting any data from the harware interrupts and I just get "0" even through the motor is spinning. This is a very irregular behaviour. When it works, it works pretty nicely, but sometimes it gives nothing at all. What can be the problem here?

My code is as follows


l_mot_1 = 6; GPIO.setup(l_mot_1,GPIO.OUT);
l_mot_2 = 13; GPIO.setup(l_mot_2,GPIO.OUT)

r_mot_1 = 19; GPIO.setup(r_mot_1,GPIO.OUT);
r_mot_2 = 26; GPIO.setup(r_mot_2,GPIO.OUT)

#=========== SETUP ENCODER PINS ===============

enc_L = 4; tick_L = 0;  # Left motor 

enc_R = 17; tick_R = 0; # Right motor

ppr = 990; RPM_limit = 5 # RPM below which we read "0"

num_avg_point = 10 # Number of points to be used for exponential avergaing and smoothing out RPM data 

beta = 1- 1/num_avg_point # parameter used for exponential averaging

alpha = 0.985; # Complimentary filter control parameter


def my_callback_R(channel):
    global tick_R

def my_callback_L(channel):
    global tick_L

GPIO.setup(enc_L, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set Pull left encoder pin to up 

GPIO.add_event_detect(enc_L, GPIO.RISING, callback=my_callback_L) # Set the interrupt functions for left motor

GPIO.setup(enc_R, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set Pull right encoder pin to up

GPIO.add_event_detect(enc_R, GPIO.RISING, callback=my_callback_R) # Set the interrupt functions for right motor

class my_motors:

    def __init__(self, beta, ppr, position, RPM_limit):

        self.t_prev = datetime.now() # Time during object initialisation

        self.beta = beta; # parameter used for exponential averaging

        self.RPM_prev = 0; # Starting RPM value

        self.n_prev = 0; # Starting encoder count

        self.ppr = ppr # Number of pulses generated per revolution

        self.position = position # motor position "L" or "R"

        self.RPM_limit = RPM_limit # Below this RPM, send RPM = 0

    def get_RPM(self, units = 'rad/s'): # Get motor RPM 

        global tick_L, tick_R

        if self.position == "L":

            n_now = tick_L

        elif self.position == "R":

            n_now = tick_R            

        t_now = datetime.now() # Find what time is it now

        delta_t = t_now - self.t_prev  # Calculate time difference between consecutive readings 

        dt = delta_t.total_seconds() # Total time difference in seconds

        dn = n_now - self.n_prev # Difference between motor encoder counts

        # Calculate RPMs and smooth out the data usinge exponential averaging
        ''' From Andrew Ngs lectrues

        V_t = beta * V_(t-1) + (1-beta) * Theta_t 

        i.e. more weight is given to previous value and less weight to the present value


        RPM_now = self.beta*self.RPM_prev + (1 - self.beta)*(dn / dt)*(60.0 / self.ppr) # This is Revolutions / min

        if RPM_now < self.RPM_limit:

            RPM_now = 0 # If RPM is less than the limiting RPM, make it "0"

        #RPM_dot = (RPM_now - self.RPM_prev) / dt # Time derivative of omega

        self.t_prev = t_now # Make previous time equal to present time

        self.n_prev = n_now # Make previous encoder counts equal to present encoder counts 

        self.RPM_prev = RPM_now # Make previous RPM equal to present RPM

        if units == 'rpm':
            dd = RPM_now # Return RPM in RPM
            dd = (RPM_now*2*3.14/60) # Return rpm in [rad/s]        

        return dd

#====================MAIN COMPUTING LOOP ===================

my_mpu = mpu6050(0x68) # Initialize MPU to get acceleration and rotation data

left_motor = my_motors(beta, ppr, "L", RPM_limit) # Class / object to get RPM data

right_motor = my_motors(beta, ppr, "R", RPM_limit) # Class / object to get RPM data

while 1:

    my_rpm = left_motor.get_RPM()
  • Do you get the same problem with different software? E.g. have you tried the software I linked to an earlier question of yours? – joan Aug 22 '18 at 9:06
  • Hi Joan. I have tried the libraries you had pointed me to earlier. Seems like I had a small bug in my code and then I compared my results to those libraries and they perfectly matched. But now I don't understand why it suddenly stops reading the values. It doesn't even show encoder signals changing. – Nischal Aug 22 '18 at 9:23
  • Okay, but does the software I linked also stop working? If it does it is likely to be a hardware problem. If it does not it is likely to be a software problem. – joan Aug 22 '18 at 9:57

Your Answer

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

Browse other questions tagged or ask your own question.