Friday, January 9, 2015

Ready to move forward again!

After being stalled for about a week on the interrupt problem, I was given some insights by the posters at the Raspberry Pi forum and was able to get my primary issue resolve. Unfortunately, I did not ever reach a point of truly learning why there was a problem.
However, I think I came close. One poster suggested that there might be an issue with disabling the interrupt in the middle of an interrupt. He used two terms that I don't fully understand: reentrant and thread-safe. Reentrancy has to do with the ability of a program to jump out of a thread in the middle of execution and reenter without problem. Thread safety has to do with the manipulation of shared data when it's being run on multiple threads. I can vaguely see that disabling the interrupt inside of the interrupt may cause some problems here.
But the functional resolution that came about was to introduce a "busy" variable that tells the interrupt that it's already in the middle of an interrupt. This avoids the problem of needing to disable the interrupts in the first place. The variable starts off being false and the first line of the interrupt checks the busy variable. If it's not busy, then it sets the variable to true and begins to run the flashing program. Here's the full code:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)

busy = False

def LEDflash(channel):
    global busy
    if busy == False:
        busy = True
        for i in range(1,5):
            if channel == button[i]:
                GPIO.output(LED[i], GPIO.HIGH)
                time.sleep(0.5)
                GPIO.output(LED[i], GPIO.LOW)
        busy = False

# Label buttons and pins
button = [4, 12, 16, 20, 21]
LED = [22, 5, 6, 13, 19]

# Set GPIO pins
for i in range (0,5):
    GPIO.setup(button[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(LED[i], GPIO.OUT)

for i in range (1,5):
    GPIO.add_event_detect(button[i], GPIO.FALLING, callback=LEDflash, bouncetime=200)

GPIO.output(LED[0], GPIO.HIGH)
GPIO.wait_for_edge(button[0], GPIO.FALLING)
GPIO.output(LED[0], GPIO.LOW)
GPIO.cleanup()

I don't think I'll have the time to play with this some more tonight, but the next thing I need to do is to start recording the button presses in a list and create a checking protocol. It shouldn't take long, but I've got some other stuff to do tonight before I jump into that.

No comments:

Post a Comment