underground-software / RPi.GPIO2

GNU General Public License v3.0
22 stars 13 forks source link

edge detection nok #61

Open goshansp opened 2 years ago

goshansp commented 2 years ago

Issue

An state change (edge) on the rpi3's gpio will raise TypeError: 'list' object is not callable. Sometimes this issue requires two edges to occur and add_event_detect seems to fail to detect edges at all. I have tried a few variations in the code but the behavior seems consistent on two identical systems.

System Info

RPi.GPIO2==0.3.0a3

python3-libgpiod-1.6.3-7.fc36.aarch64

fedora-iot:fedora/stable/aarch64/iot
Version: 36.20220921.0 (2022-09-21T21:59:52Z)

Reproduction Script edge_test.py

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

GPIO_PIN=6

def my_callback():
    print(str(bool(GPIO.input(GPIO_PIN))))

def init():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(GPIO_PIN,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
    GPIO.add_event_detect(GPIO_PIN,edge=GPIO.BOTH,callback=my_callback)
    print("init " + str(bool(GPIO.input(GPIO_PIN))))

if __name__ == '__main__':
    try:
        init()
        print("now change state on gpio6 to create edge ...")
        time.sleep(9999)
    except KeyboardInterrupt:
        GPIO.cleanup()

Symptome

[hp@rpi3-2 ~]$ python3 edge_test.py 
init False
Exception in thread Thread-1 (poll_thread):
Traceback (most recent call last):
  File "/usr/lib64/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/var/home/hp/.local/lib/python3.10/site-packages/RPi/core.py", line 673, in poll_thread
    line_do_poll(channel, bouncetime, timeout)
  File "/var/home/hp/.local/lib/python3.10/site-packages/RPi/core.py", line 660, in line_do_poll
    for fn in callbacks():
TypeError: 'list' object is not callable

Can someone reproduce it or spot the issue in my code?

goshansp commented 2 years ago

This issue happens on the latest, manually installed code as well. I achieved a little progress with a small change and now the error is not thrown anymore. But edges are only detected about 75% of the time and such race / threading is exceeding my capa. Also I assume that gpiod doesn't leverage interrupts and hence edges have to be detected by polling. If someone can point me to working edge detection on Fedora IOT that would be very much appreciated.

Just found this which may be of help https://github.com/toradex/torizon-samples/issues/4

goshansp commented 2 years ago

Missed edges have been blocked by os.read(eventfd, 10000) which I've disabled. My fork seems to detect all edges now. But sometimes it will print multiple edges upon a single button switching. The same multi-print behaviour can also be seen with gpiodmon.py. I see that my setup switch bounces within 300 micro seconds.

@theyoyojo to you think the multiple detections/debounce is fixable in RPi.GPIO2 or is it originating from gpiod?

goshansp commented 2 years ago

Libgpiod does not currently support debounce and may get it in v2. We may consider to implement debounce as a workaround in RPi.GPIO2 and remove it again later. As already mentioned in line_event_wait the debounce should happen outside of a poll thread?

theyoyojo commented 12 months ago

Hi, I haven't had time to look through this until now but I will get to it soon.