Page 1 of 1

single GPIO event, multiple callbacks

Posted: Fri Feb 14, 2014 1:52 pm
by mitch845
I have a 2 buttons that connects gpio to ground when pressed.
I want to assign 2 different function to button1, and another function to button2, like this example:
button1 press --> function A
button1 press --> function B
button1 press --> function A
button1 press --> function B

whenever i press button 2 --> function C.

I tried with this code:

Code: Select all

#!/usr/bin/env python2.7
import RPi.GPIO as GPIO
import os
import time
GPIO.setmode(GPIO.BCM)

# setting gpios
GPIO.setup(14, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def my_callback(channel):
    print "\n button2 pressed"

GPIO.add_event_detect(17, GPIO.FALLING, callback=my_callback, bouncetime=500)

try:
 while True:
      GPIO.wait_for_edge(14, GPIO.FALLING)
      print "\n button 1 pressed"
      sleep.time(0.5)
      GPIO.wait_for_edge(14, GPIO.FALLING)
      print "\n button 1 pressed again"
      sleep.time(0.5)
except KeyboardInterrupt:
    GPIO.cleanup()
    GPIO.cleanup()
But I discovered that when the main thread is in the "while" infinite loop, the other thread listening for button2 is not working.

Is there another way for doing what I want?
I figured that using GPIO.add_event_detect allow me to call just a single callback, so i moved on GPIO.wait_for_edge in an infinite loop, although this method is not working.

Re: single GPIO event, multiple callbacks

Posted: Fri Feb 14, 2014 2:20 pm
by paddyg
Put event callback for both pins (ie my_callback_1() and my_callback_2()). Why are you differentiating between button 1 and button 2, is it purely a test to see what happens or is there a more fundamental reason?

There is an issue (aka bug) with using the same callback function to respond to different gpio pin changes. The design of the module makes it look as though this would be fine, as the pin number is specified as an argument to the function. However if a second callback happens during the execution of a previous one it scrambles the action. See here

Re: single GPIO event, multiple callbacks

Posted: Fri Feb 14, 2014 2:35 pm
by mitch845
I would use callback also for button1, but I don't know how to manage the different functions assigned to the same button.
A gpio event can call just a unique callback. How can I assign different callbacks to the same GPIO event? (if i press the button it has to call a callback, then if i press again it has to call another callback, and so on).
This is why i didn't used callbacks for button1.

Re: single GPIO event, multiple callbacks

Posted: Fri Feb 14, 2014 3:04 pm
by paddyg
You have to have 'flags' that hold the state of the button pressing. You're probably stuck with global variables which are generally a bad idea but there's no real way round them with the gpio callbacks. You might need to put a time check in to avoid getting multiple presses if it's not a clean make/break switch.

Code: Select all

BUTTON_STATE = 0
N_STATES = 2

def mycallbackA(channel):
  if BUTTON_STATE == 0:
    print("here you put the code for function 1")
  elif BUTTON_STATE == 1:
    print("code for function 2"
  else:
    print("etc (shouldn't actually get here!)")
  BUTTON_STATE = (BUTTON_STATE + 1) % N_STATES
those print() functions could be calls to your different functions if you wanted to keep the code in its own packet.