Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push button event itself without pushing #134

Closed
LudovicGuerra opened this issue Feb 13, 2017 · 16 comments
Closed

Push button event itself without pushing #134

LudovicGuerra opened this issue Feb 13, 2017 · 16 comments
Assignees

Comments

@LudovicGuerra
Copy link

Hi all.
I am working on BBG. Im using Python2
I got a problem link to Adafruit driver.
I got a Beaglebone with a push button on a GPIO.
I plug on the GPIO a oscilloscope.
And on a console I print if the event is detected ty to the function GPIO.event_detected
The problem is :
Sometimes I don't push the button, the oscilloscope show nothing but I got a message "Button pushed".
Can someone relate this problem or cross-check ?
Thanks.

@pdp7
Copy link
Collaborator

pdp7 commented Feb 13, 2017

I'd like to know more about what system software is running on your BeagleBone. Please paste the output of:

cat /etc/dogtag

cat /etc/debian_version

uname -a

Please ensure your running the latest version of Adafruit_BBIO which is 1.0.3:

debian@beaglebone:~$ sudo pip install --upgrade Adafruit_BBIO
Collecting Adafruit_BBIO
Installing collected packages: Adafruit-BBIO
Successfully installed Adafruit-BBIO-1.0.3

Finally, please post the Python code that you are running so that I can attempt to reproduce the issue.

@pdp7 pdp7 self-assigned this Feb 13, 2017
@LudovicGuerra
Copy link
Author

LudovicGuerra commented Feb 13, 2017

Hi
I cannot install the latest version of adafruit because it is not working at all for reason.
Linux beaglebone 4.4.30-ti-r64 #1 SMP Fri Nov 4 21:23:33 UTC 2016 armv7l GNU/Linux
Debian version : 8.6
BeagleBoard.org Debian Image 2016-11-06

The code I use :

from datetime import datetime
import time
import csv
import Adafruit_BBIO.GPIO as GPIO

GPIO.cleanup()
def test(tutu):
        print("test")

GPIO.setup("P8_15", GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup("P8_16", GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup("P8_17", GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

GPIO.add_event_detect("P8_16", GPIO.RISING)

print("Ready\n")
starttime = datetime.now()
while(1):
        if GPIO.event_detected("P8_16"):
                file = open('result.csv', 'w')
                file.write(str(starttime) + "," + str(datetime.now()) + "," + "wrong detection\n")
                print("Event detected\n")
                file.close()

When I push intentionally the button, Sometimes I get two event detected, sometimes one, even if I wrote GPIO.RISING. Random behaviour.
My version of Adafruit is 1.0.0

@pdp7
Copy link
Collaborator

pdp7 commented Feb 13, 2017

I cannot install the latest version of adafruit because it is not working at all for reason.

Do you get an error when trying to upgrade to v1.0.3 via pip?

Alternatively, have you tried cloning this repo and installing it?

@LudovicGuerra
Copy link
Author

Installing is not the problem. My program (not this one, this one is jsut for test) is not working and I get a specific error, everytime the same. Didn't investigate further. I don't remember the error exactly, but it was an error about pyserial if I remember well.
And on my environment we don't often update version (fighted hard to be able to have the latest debian version...)
But I don't think it is a real problem, version 1.0.3 don't touch the GPIO if i didn't miss the update.

@pdp7
Copy link
Collaborator

pdp7 commented Feb 13, 2017

I've run your example and I see the issue you describe. I think the issue is that there needs to be debouncing.

add_event_detect() does have bouncetime parameter in milliseconds.

add_event_detect() also supports a callback function.

Could you replace the while loop with a callback to handle the button press?

@LudovicGuerra
Copy link
Author

LudovicGuerra commented Feb 13, 2017

I did it's what the "test" function is for.
The behaviour is really strange.
And if i change the boucetime, then i get more event detected.
Best is to try yourself to see. Didn't see any pattern.
if i use GPIO.add_event_detect("P8_16", GPIO.RISING, test, 100)
Then i get one time print test for 5 events, then "test" again. Sometime i got 10 event before having the word "test".
And the bouncetime parameter make me having more event...
As i said, on oscilloscope the signal is perfect.

@LudovicGuerra
Copy link
Author

I believe you should have a look on event_detected.
event_occurred[gpio] = 1; happen without checking the raising or falling event. It seems.

@pdp7
Copy link
Collaborator

pdp7 commented Feb 14, 2017

Ok, thanks, I'll investigate further.

@LudovicGuerra
Copy link
Author

Super. Keep me inform when you get news. If you need some help don't hesitate.

@LudovicGuerra
Copy link
Author

Hi do you have news ?

@pdp7
Copy link
Collaborator

pdp7 commented Feb 28, 2017

@LudovicGuerra Sorry for the delay. I've been traveling but have returned home now. I'll follow up by tomorrow (March 1).

@pdp7
Copy link
Collaborator

pdp7 commented Mar 2, 2017

@LudovicGuerra To test, I modified source/event_gpio.c in order to gain insight into what is happening.

Here is the test program test-issue-134.py based on your program above:

from datetime import datetime
import time
import csv
import Adafruit_BBIO.GPIO as GPIO

def test(tutu):
        print("test")

GPIO.cleanup()
GPIO.setup("P8_16", GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#GPIO.add_event_detect("P8_16", GPIO.RISING)
GPIO.add_event_detect("P8_16", GPIO.RISING, test, 100)

print("Ready\n")
starttime = datetime.now()
while(1):
        if GPIO.event_detected("P8_16"):
                file = open('result.csv', 'w')
                file.write(str(starttime) + "," + str(datetime.now()) + "," + "wrong detection\n")
                print("Event detected\n")
                file.close()

I run the program with P8_16 disconnected and then I connect wire to 3.3V:

debian@beaglebone:~/adafruit-beaglebone-io-python$ sudo python ../test-issue-134.py 
DEBUG: add_edge_detect()
DEBUG: gpio_event_add()
Ready

DEBUG: poll_thread()
DEBUG: run_callbacks()
test
Event detected

Do you get these same results?

@LudovicGuerra
Copy link
Author

Hi.
At the moment we are re-architecturing the software on the beaglebone.
For example, we are updating to python 3.6.
So I cannot test right now due to this.
Sorry for the inconvenience.
I will tell you when I can lauch a test.

@JesseMcL
Copy link
Contributor

JesseMcL commented Mar 3, 2017

Hi,

The debounce parameter is not strictly a debounce, it is a throttle - which can be a bit misleading. This means that button presses, particularly with mechanical buttons or connecting wires will generate many high and low glitches until the button is steady (which could take hundreds of milliseconds, and glitches can occur on microsecond periods).

If these glitches take a long time to settle, longer than the throttle window you will get multiple events.

On the other hand, a pure debounce will not trigger until the glitches have stopped for more than the debounce time. A continuously glitching line will never trigger the event, as the debounce windows is continuously pushed out.

I have used a simple debounce decorator from @walkermatt on gitHub which i wrap around my

from threading import Timer
"""Thanks to https://gist.github.com/walkermatt/2871026"""

def debounce(wait):
    """ Decorator that will postpone a functions
        execution until after wait seconds
        have elapsed since the last time it was invoked. """
    def decorator(fn):
        def debounced(*args, **kwargs):
            def call_it():
                fn(*args, **kwargs)
            try:
                debounced.t.cancel()
            except(AttributeError):
                pass
            debounced.t = Timer(wait, call_it)
            #TODO: does this spawn too many threads on repeated calls and t.cancels?
            debounced.t.start()
        return debounced
    return decorator

@debounce(0.1) #debounce to call event only after stable for 0.1s
def gpioEventDebounce(gpio):
    """gpioEventDebounce is a wrapper around gpioEvent which fires after a resettable delay
    the debounce decorator sets the delay time in seconds"""
    print('event on',gpio)

GPIO.add_event_detect("P8_17", GPIO.RISING, gpioEventDebounce) #no 'debounce' arg, use decorator on callback instead

@pdp7
Copy link
Collaborator

pdp7 commented Mar 4, 2017

@JesseMcL thanks for the insights and the code example. I'll try it out. This seems like something I should add as an example in the documentation.

@pdp7
Copy link
Collaborator

pdp7 commented Apr 4, 2017

@LudovicGuerra I'm going to close this but please re-open if you are able to test again and have problems

@pdp7 pdp7 closed this as completed Apr 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants