Detecting and Comparing GPIO events in Beaglebone using Python
Question: I am trying to detect two events in two different GPIOs in the Beaglebone
Black, and then decide which one happened first. I am using Adafruit_BBIO.GPIO
for the code which is written in Python. It is not working properly, and have
no idea why. Here is the code:

    
    
    import sys
    import thread
    import time
    from datetime import datetime
    import bitarray
    import Adafruit_BBIO.GPIO as GPIO
    
    gpio_state = [0, 0]
    gpio_time = [0, 0]
    ir_recv = ['GPIO0_26', 'GPIO1_12']
    
    def checkEvent(index):
        while True:
            if GPIO.event_detected(ir_recv[index]): 
                if (gpio_state[index] == 0):
                    gpio_state[index] = 1
                    gpio_time[index] = datetime.now()
                    print ir_recv[index]
                    time.sleep(5) # time to avoid rebounces
    
    for gpio in ir_recv:
        GPIO.setup(gpio, GPIO.IN)
        GPIO.add_event_detect(gpio, GPIO.RISING)
    
    try:
        thread.start_new_thread(checkEvent, (0, ) )
        thread.start_new_thread(checkEvent, (1, ) )
    except:
        print "Error: unable to start thread"
    
    while True:
        if (gpio_state[0] == 1) and (gpio_state[1] == 1):
            if gpio_time[0] > gpio_time[1]:
                print "1"
            if gpio_time[0] < gpio_time[1]:
                print "2"
            if gpio_time[0] == gpio_time[1]:
                print "???"
            gpio_state[0] = 0
            gpio_state[1] = 0
            gpio_time[0] = 0
            gpio_time[1] = 0
    

I don't get any error. The main problem is that the events are not compared
correctly, e.g. although event in GPIO0_26 happens first than the one in
GPIO1_12 (i.e. gpio_time[0] is smaller than gpio_time[1]), the output in the
last While loop does not print out "2". Also sometimes the code prints out
twice the GPIO pin from the threads.

Thanks in advance for any suggestion to find a solution.


Answer: I'd recommend using [PyBBIO](https://github.com/graycatlabs/PyBBIO) for this
(granted, I am the author). It has an interrupt API which is based on
[epoll](http://linux.die.net/man/4/epoll) (for kernel level interrupt
signalling), and would greatly simplify this. Something like this should do
the trick (I haven't tested it):

    
    
    from datetime import datetime
    from bbio import *
    
    gpio_state = [0, 0]
    gpio_time = [0, 0]
    ir_recv = ['GPIO0_26', 'GPIO1_12']
    
    def getInterrupt(index):
        gpio_time[index] = datetime.now()
        gpio_state[index] = 1
        print "received interrupt from {} at {}".fomrat(ir_recv[index],
                                                        gpio_time[index]
                                                        )
    
    def setup():
        for i in range(len(ir_recv)):
          pinMode(ir_recv[i], INPUT, pull=-1)
          # The optional pull=-1 enables the internal pull-down resistor
    
        attachInterrupt(ir_recv[0], lambda: getInterrupt(0), RISING)
        attachInterrupt(ir_recv[1], lambda: getInterrupt(1), RISING)
    
    
    def loop():
        # You can do other stuff here while you're waiting...
        delay(1000)
    
    run(setup, loop)
    

And you should make sure your PyBBIO is up to date with:

    
    
    # pip install -U PyBBIO
    

