1
votes

I have a little problem with my little raspberry project, I have hooked up an LCD screen and a bunch of buttons to it, from my university course about micro-controllers I've learned that interrupts always trigger, no matter where the code is (but it was an actual microprocessor written in C). I found an "equivalent" in python, GPIO library. Normally a program is in a infinite loop waiting for an interrupt.

GPIO.add_event_detect(4, GPIO.RISING, callback=interrupt, bouncetime=200)

I set them up this way, they all go to the same method and check which button was pressed and run another method that I want (e.g one is for displaying time, another for IP address etc). A thing is, one of those methods I've done is in an infinite loop that another button press should break, but from this point a method

while not GPIO.event_detected(4):

doesn't work (calling this method in any other doesn't either if its in this loop, and all other button that I have set up will not react at all too), if it was my default while loop it does tho. I don't have much experience in either micro-controllers and python, its just hobby thing at the moment. If needed I'll share my entire code but I think its quite tangled.

Ok I am providing a simplified example, same same thing happens as in my original code. After an interrupt happens, buttons will not react, doesn't matter if I use while not GPIO.event_detected(19) or GPIO.add_event_callback(26, callback=second_interrupt).

import RPi.GPIO as GPIO
import time


GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # Button 1
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # Button 2


def interrupt(channel):
    print "interrupt"
    if channel == 26:
        print "in loop"
        GPIO.add_event_callback(26, callback=second_interrupt)  #Trying to use this won't trigger second interrupt
        while not GPIO.event_detected(19):                      #and this wont ever trigger
            time.sleep(1)
            print "inside loop"


def second_interrupt():
    print "second interrupt"


GPIO.add_event_detect(26, GPIO.RISING, callback=interrupt, bouncetime=200)  # add rising edge detection on a channel
GPIO.add_event_detect(19, GPIO.RISING, callback=interrupt, bouncetime=200)  # add rising edge detection on a channel


while (True):
    time.sleep(1)
    if GPIO.event_detected(19):         #this version works if I wont enter an interrupt first
        second_interrupt()
1
This question is hard to answer without seeing the actual code involved. If your code is long or tangled, the best course of action would be to create a smaller demonstration that reproduces the problem. We call this a "minimal, complete, verifiable example" (stackoverflow.com/help/mcve), and the idea is that it provides us with something to more fully understand your problem without requiring us to wade through lots of unrelated code. - larsks
I have written a simple example mimicking my original code, it does exactly the same - jakubek278
I'm not clear on something here: what do you expect your code to do when an interrupt is triggered on pin 19? You've set up an event callback with add_event_detect, but you're also using GPIO.event_detected and calling a second method. Do you intend to call both? That is, I'm not sure I understand the logic you're trying to implement. - larsks

1 Answers

2
votes

There are several things going on in your code. I suspect that what's really causing the problem is that you need to exit the interrupt handler before another interrupt callback can be triggered...but there is also a confusing mix of callback-based handlers and the GPIO.event_detected method.

I think you can simplify things by performing less manipulation of your interrupt configuration. Just have a state variable that starts at 0, increment it to 1 on the first interrupt, so the next time the interrupt method is called you know it's the second interrupt. No need to try setting multiple handlers like that.

Keeping in mind that I don't actually know what you're trying to do...I imagine something like this:

import RPi.GPIO as GPIO
import time

state = 0

GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def interrupt_handler(channel):
    global state

    print("interrupt handler")

    if channel == 19:
        if state == 1:
            state = 0
            print("state reset by event on pin 19")
    elif channel == 26:
        if state == 0:
            state = 1
            print("state set by event on pin 26")


GPIO.add_event_detect(26, GPIO.RISING,
                      callback=interrupt_handler,
                      bouncetime=200)

GPIO.add_event_detect(19, GPIO.RISING,
                      callback=interrupt_handler,
                      bouncetime=200)


while (True):
    time.sleep(0)