In the previous post, a program keeps executing a while loop checking to see if a button has been pressed. This is called polling, and it's not very efficient because the program can't do anything else while waiting for the button to be pressed. It would be better if the program could do something else while it was waiting.
This can be achieved using interrupt driven IO. An interrupt is a signal generated by a peripheral device that lets the processor know that an event has happened. The RPi GPIO library makes this easy. You simply need to use the add_event_detect function to specify what type of event you're waiting for, and add_event_callback to specify what should happen when the event occurs.
In this exercise I used the same circuit as in the previous exercise, and I used the code below:
#!/usr/bin/env python import time import RPi.GPIO as GPIO # handle the button event def buttonEventHandler (pin): print "handling button event" # turn the green LED on GPIO.output(25,True) time.sleep(1) # turn the green LED off GPIO.output(25,False) # main function def main(): # tell the GPIO module that we want to use # the chip's pin numbering scheme GPIO.setmode(GPIO.BCM) # setup pin 23 as an input # and set up pins 24 and 25 as outputs GPIO.setup(23,GPIO.IN) GPIO.setup(24,GPIO.OUT) GPIO.setup(25,GPIO.OUT) # tell the GPIO library to look out for an # event on pin 23 and deal with it by calling # the buttonEventHandler function GPIO.add_event_detect(23,GPIO.FALLING) GPIO.add_event_callback(23,buttonEventHandler,100) # turn off both LEDs GPIO.output(25,False) GPIO.output(24,True) # make the red LED flash while True: GPIO.output(24,True) time.sleep(1) GPIO.output(24,False) time.sleep(1) GPIO.cleanup() if __name__=="__main__": main()
This program tells the GPIO library to look out for an event on pin 23 of the GPIO header. The event to look out for is a falling edge, where the voltage goes from 1 to 0. This example detects the GPIO.FALLING event, but it's also possible to detect GPIO.RISING and GPIO.BOTH. The function named buttonEventHandler is registered as the callback for the event.
The program then goes round the while loop making the red LED blink. When the button is pressed, buttonEventHandler is called, and the green LED is turned on for one second. The event is handled by a different thread, so while the green button is on, the red light continues to blink uninterrupted.
If your program doesn't need to do anything while its waiting for an event, you can call GPIO.wait_for_edge() which will make your program sleep until an event wakes it up. If your program no longer needs to wait for an event, you can unregister it by calling GPIO.remove_event_detect().