-
Notifications
You must be signed in to change notification settings - Fork 219
Closed
Description
In the following code, a noisy button press can cause the callback be called once, then interrupted by a second edge and called again.
def cb(gp):
print("Start");
print(gp);
print("End");
GPIO.setup("P8_17", GPIO.IN, GPIO.PUD_UP);
GPIO.add_event_detect("P8_17", GPIO.FALLING, cb, 200);
Leading to output like this...
Start
Start
P8_17
End
P8_17
End
This is not detected as a bounce because in run_py_callbacks the cb->lastcall property isn't set until after the callback returns. At the time of the second call, cb->lastcall is still equal to zero. This can be worked around by setting cb->lastcall just before calling the callback function. This does not address bounces of the other edge, which leads to incorrect callbacks.
diff --git a/source/py_gpio.c b/source/py_gpio.c
index 67f6ba4..e8e3baa 100644
--- a/source/py_gpio.c
+++ b/source/py_gpio.c
@@ -185,6 +185,10 @@ static void run_py_callbacks(unsigned int gpio)
gettimeofday(&tv_timenow, NULL);
timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec;
if (cb->bouncetime == 0 || timenow - cb->lastcall > cb->bouncetime*1000 || cb->lastcall == 0 || cb->lastcal$
+
+ // save lastcall before calling func to prevent reentrant bounce
+ cb->lastcall = timenow;
+
// run callback
gstate = PyGILState_Ensure();
result = PyObject_CallFunction(cb->py_cb, "s", cb->channel);
Metadata
Metadata
Assignees
Labels
No labels