Menu

#139 Reading pin status in callback does not give expected result (even with long bounce times)

Invalid
None
Medium
Other
2016-10-15
2016-10-02
Mr.Mitchell
No

I have been having some issues with reading the pin status in the event callback (actually I had the issue with Home Assistant, but drilling down I can reproduce the same issue with only RPi.GPIO code)

Basically I add and event callback for both edges. In the callback I need to figure out the current value so I read it. It returns always 1 in my case. I thought it might be a glitch so I did some experiments with longer bouncetimes, but it still comes back as 1. In my test program I also poll the pin every 100 ms and that gives back the expected values.

I am expecting that with a bouncetime of 1000ms that the callback gets called 1 second after the actual transition happened (restarting the bouncetime on any transition that happens within that time period).

My test program:

#! /usr/bin/python3

import sys
import time
import RPi.GPIO as GPIO


print("PI VERSION: ",GPIO.RPI_INFO)
print("GPIO VERSION: ", GPIO.VERSION)
print("PYTHON VERSION: ", sys.version)

pin_trigger = 22

# Setup GPIOs (using BCM numbering, not board!)
def gpio_event(channel):
    print("EVENT GPIO CALLBACK FOR CHANNEL:", channel, " status:", GPIO.input(pin_trigger))

GPIO.setmode(GPIO.BCM)
GPIO.setup(pin_trigger, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

# Exception here when trying to add event detection
GPIO.add_event_detect(pin_trigger, GPIO.BOTH, callback=gpio_event, bouncetime=1000)

# Read the input a few times
count = 10000
while count > 0:

    active = "NO"
    if GPIO.input(pin_trigger) == 1:
        active = "YES"

    print(count, active)

    time.sleep(0.1)
    count = count - 1

# Done
GPIO.cleanup()

The program sets up a callback for both edges and then goes into a loop that reads the input every 100ms and prints the state. In the attached logs (with varieng bounce times) I turn on my projector (which triggers the pin), wait for it to become active and then switch it off again.

In the logs you will see

  • Number of active NO
  • Callback triggered (pin reads 1)
  • Number of active YES
  • Callback triggered (pin reads 1)
  • Number of active NO

I would expect the callback to read 0 in the second case. Also with the bouncetime of 1000ms I would expect the main loop to already print a few times YES before the callback is called the first time.

I might be doing something wrong here, or just have wrong expectations, but not sure what to do from here.

3 Attachments

Discussion

  • Mr.Mitchell

    Mr.Mitchell - 2016-10-02

    Hmm, I can't seem to edit my posts.

    This is on a Raspberry Pi 1B

    More detailed version info from GPIO.PRI_INFO and GPIO.VERSION:
    PI VERSION: {'REVISION': '000d', 'MANUFACTURER': 'Egoman', 'TYPE': 'Model B', 'RAM': '512M', 'PROCESSOR': 'BCM2835', 'P1_REVISION': 2}
    GPIO VERSION: 0.6.2
    PYTHON VERSION: 3.4.2 (default, Oct 19 2014, 13:31:11)
    [GCC 4.9.1]

    I also found out that duplicating the print in the callback results in the second print to print the expected value. Not sure what to think of that...

     
  • Ben Croston

    Ben Croston - 2016-10-15
    • status: New --> Invalid
    • assigned_to: Ben Croston
    • Priority: High --> Medium
     
  • Ben Croston

    Ben Croston - 2016-10-15

    I think you are confused by the way bouncetime works. Setting a bouncetime will make RPi.GPIO ignore all edges after the edge that caused the trigger for the time stated by bouncetime. Your callback is called immediately on detecting the edge.
    As to why the pin is still reading 1 on the second event, I'm not sure why. It is probably reading the state mid-bounce.

     

Log in to post a comment.

Auth0 Logo