Debouncing not working - wrong clock used
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
lg-gpio (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
This is really an upstream bug, but I found no upstream bug tracker or contact address, so I'm hoping the upstream maintainer might be reading along here (and it's a bug in the Ubuntu version as well, so not entirely off here).
The problem is that when I set a debounce time on an input pin (with a button attached), that debounce time is not actually applied. If I set a 0.5s timeout, input events are registered immediately (and a lot of them in succession if I press the button a lot of times), instead of only reporting changes when the pin has been stable for 0.5s.
To reproduce, I have used the attached program (monitor.c), which is exactly the "monitor GPIO" example from http://
This line sets a bounce time of 500,000 μs (or 0.5 second).
When I compile and run it, and press a button attached to gpio 7 a few times quickly, I get:
$ gcc -Wall -o monitor monitor.c -llgpio
$ ./monitor 7
chip=0 gpio=7
chip=0 gpio=7 level=1 time=116.935984428
chip=0 gpio=7 level=0 time=122.184483056
chip=0 gpio=7 level=1 time=122.311010973
chip=0 gpio=7 level=0 time=122.385752598
chip=0 gpio=7 level=1 time=122.495776931
chip=0 gpio=7 level=0 time=122.536279723
chip=0 gpio=7 level=1 time=122.634267723
^C
Note that the timestamps are a lot less than 500ms apart, which should not be possible if the debouncing was working.
I investigated more closely, using the most recent version (downloaded from http://
- When an event occurs, the timestamp passed by the gpio event is used: https:/
- When no event occurs (for 1ms, I think), the `xNowTimestamp` is used. This is returned by `lguTimestamp()` and uses CLOCK_REALTIME (https:/
- I noticed that both timestamps are really not comparable. IIRC one had about twice as many digits as the other (so I guess one of them is walltime and the other might be time since boot or something). I checked the code and both should be correctly in nanosecond precisions.
- The xDebWatEvt compares these two timestamps to decide about bouncing. Since the now timestamp is always bigger than the event timestamps, this effectively disables the debouncing.
- If I change `lguTimestamp()` to use CLOCK_MONOTONIC, debouncing works as expected, so all of the code seems to be correct otherwise.
I'm not sure if changing `lguTimestamp()` is the right fix here, since it might be used elsewhere that does need CLOCK_REALTIME (I haven't checked closely).
The gpio docs (https:/
* By default the @timestamp_ns is read from %CLOCK_MONOTONIC and is
* intended to allow the accurate measurement of the time between events.
* It does not provide the wall-clock time.
*
* If the %GPIO_V2_
* @timestamp_ns is read from %CLOCK_REALTIME.
So maybe another fix is to always set the GPIO_V2_
Assuming that debouncing has been tested to work when this code was originally written, I wonder if the default gpio clock was changed at some point, the clock used by lgTimestamp was changed, or maybe this was originally tested on hardware where both clocks are identical? I would dig in a bit deeper, but lacking a version control repo and also changelogs AFAICS, I'm going to just leave this here.
I've been testing this on an Orange Pi PC board, running a Ubuntu Jammy-based Armbian image.
I've found the upstream git repo and resubmitted this report there: https:/ /github. com/joan2937/ lg/issues/ 18