0

I'm wiring my Raspberry pi to a USdigital encoder , especifically this model "H6BM-1000-500-IE-S-H" , it has 1000 signals per revolution , I've followed the tutorial on

http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3

It works , however if I spin it fast (with my hand not attached to a motor), I miss some interrupts ,The encoder outputs a ~5v signal , so I made the a circuit to lower it to ~3v Resistors used to lower 5v to 3v3 for interrupt

The question here is , are the missing interrupts due to software (good RPi.GPIO alternatives?), or probably hardware (I was thinking switching the circuit to a voltage regulator IC ) and if so , which is the best solution for interrupts thanks in advance

here is my code

import RPi.GPIO as GPIO  
import time
GPIO.setmode(GPIO.BCM)

class Signal(object):
    """docstring for Encoder"""
    def __init__(self, pin):
        self.pin = pin
        self.count = 0
        GPIO.add_event_detect(self.pin, GPIO.RISING, callback=interrupt, bouncetime=1)

    def interrupt(self,pin):
        self.count += 1
        print "Interrupts detected = %s"% self.count


def main():
    a = Signal(21)
    while 1:
        time.sleep(1)


if __name__ == '__main__':
     main()

EDIT :

I've tried joan's solution , and alone works perfectly , but when I introduce python code it stops working as good , and y then have the same problem as before , should I use a wrapper from C to python and write my whole class there ?? if so which is the fastest and better way to do it ?

heres my modified code if it helps anyone , it is the interrupt handling for the encoder , the idea is to make a velocity PID afterwards thanks in advance

class Signal(object):
    """docstring for Interrupt"""
    def __init__(self, pinA , pinB):
        self.pinA      = pinA
        self.pinB      = pinB
        self.gpio      = pigpio.pi()
        self.perimetro = 40*m.pi
        self.cuenta    = 0
        self.estado    = 0
        self.tiempo_actual = 0 
        self.tiempo_anterior = time.time()
        self.velocidad = 0

        #Definicion de funciones que correran al interrumpirse en los pines
        self.interrupcionA  = self.gpio.callback(self.pinA, edge = pigpio.FALLING_EDGE ,func = self.guia)
        self.interrupcionB = self.gpio.callback(self.pinB, edge = pigpio.EITHER_EDGE , func = self.referencia)


    def guia(self,a,b,c):
        self.tiempo_actual = time.time()
        if self.estado:
            self.cuenta += 1

        if not self.estado:
            self.cuenta -= 1

        tiempo = self.tiempo_actual-self.tiempo_anterior
        self.tiempo_anterior  = self.tiempo_actual
        self.velocidad = (self.perimetro/1000)/tiempo
        print "cuenta en %s" % self.cuenta    

    def referencia(self,a,b,c):
        if int(self.gpio.read(self.pinB)):
            self.estado = 1

        if not int(self.gpio.read(self.pinB)):
            self.estado = 0                         

def main():

    encoder = Signal(21,20)
    try:
        while 1:
            time.sleep(1)       
    except KeyboardInterrupt:
        self.gpio.clear_bank_1(bin(2**20+2**21))

if __name__ == '__main__':
    main() 
2

Python may not be the best choice if you have high or sustained data rates. You would be much better off using C.

Try the following Python. It should capture all the interrupts although if you have sustained high interrupt rates it may take time for them all to be processed.

#!/usr/bin/env python

import time

import pigpio # http://abyz.me.uk/rpi/pigpio/python.html

pi = pigpio.pi()
if not pi.connected:
   exit(0)

cb = pi.callback(21)

while True:
   print(cb.tally())
   cb.reset_tally()
   time.sleep(1)

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.