0

I have the following circuit hooked up with a big button. Note: I am actually using a Pi Zero, not a Pi 2. Here is my circuit

I took some code from this example to run the following python script:

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
switch = 18

# Define a threaded callback function to run in another thread when events are detected  
def my_callback(channel):
    print GPIO.input(switch)
    if GPIO.input(switch):     # if port 18 == 1  
        print "Rising edge detected on {0}".format(switch)
    else:                  # if port 18 != 1  
        print "Falling edge detected on {0}".format(switch)

GPIO.setup(switch, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(switch,GPIO.BOTH,callback=my_callback,bouncetime=300)
try:
    print "When pressed, you'll see: Rising Edge detected on 25"
    print "When released, you'll see: Falling Edge detected on 25"
    time.sleep(30)         # wait 30 seconds  
    print "Time's up. Finished!"

finally:
    GPIO.cleanup()

The problem is, when I push and release the button, I get the "Rising edge detected" message on both the push and release! Why is this? Is my circuit silly? I tried to make it as simple as possible. Did I goof up the code? It seems straightforward.

  • 1
    I did not try this but if you have voltage on the button and it's 0 when fully pressed. maybe you have to keep track of was it pressed or is it being released. have you reached 0 yet or not – MadeInDreams May 5 '16 at 1:13
  • 1
    The callback function reads the pin state TWICE, one for the direct print of its state and then as input to the following if - really you should read it once and store the result in a variable and refer to THAT for both. Also, as others have remarked there is no guarantee that the read(s) you are doing reflect the state of the pin at the time the edge was detected. Does the library you are using allow you to define TWO callbacks, one for the rising edge and one for the falling - or does the callback handler has a two argument version where one of the arguments shows what was detected? – SlySven May 6 '16 at 19:19
  • Good point regarding the double reading of the pin state. The library I am using does not allow both a rising interrupt and a falling interrupt on the same pin. It was updated to include a BOTH interrupt, but it doesn't seem possible to specify 2 callbacks depending on rising or falling edge. Maybe I should just do a while loop instead of using interrupts? That seems worse than my current code, though, in terms of detecting the current state accurately. – ScheissSchiesser May 9 '16 at 21:41
1

It may be a known fault. See https://sourceforge.net/p/raspberry-gpio-python/tickets/121/

On a general point there is little reason to expect that the level of the GPIO when read in the callback has any relationship to the level which caused the callback.

The callback code may be executed many milliseconds after the actual event during which time the switch level may have changed.

  • Absolutely true about the level possibly changing between the time the callback starts and the reading of the level, but if I simply hold the button, the level should be what I expect (0V), correct? And thus I can tell whether we triggered the interrupt with a rising or falling edge? – ScheissSchiesser May 4 '16 at 22:30
  • 1
    Probably. Of course you may also see switch bounce with mechanical switches. – joan May 4 '16 at 22:48
0

use this === GPIO.add_event_detect(25, GPIO.RISING, callback=my_callback)

you are using GPIO.BOTH thats why you are getting the "Rising edge detected" message on both the push and release.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.