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

[Bug] Debounce can happen at (DEBOUNCE - 1)ms due to >= check #21734

Closed
andrebrait opened this issue Aug 11, 2023 · 1 comment
Closed

[Bug] Debounce can happen at (DEBOUNCE - 1)ms due to >= check #21734

andrebrait opened this issue Aug 11, 2023 · 1 comment

Comments

@andrebrait
Copy link
Contributor

(From #21667, opening this as an issue to discuss it separately without interfering with that PR more than it already has)

It seems that, for most platforms, we get the time from ISRs or hardware clocks and we (or the platform) integer-divide them to get the number of milliseconds the clock is currently at.

Using AVR as an example, and considering the usage of prescalers and integer division, we have a timing problem, because the current checks are basically (in all algorithms) timer_elapsed >= DEBOUNCE, and that >= will possibly be true anywhere starting from DEBOUNCE - 1 + (1 clock cycle above the prescaler), not at DEBOUNCE milliseconds or greater.

As an example (frequency of 16MHz and prescaler of 64, getting us 1 interrupt every 1ms, or 1 interrupt every 250 CPU cycles, and a DEBOUNCE of 5).

  1. During debounce, we check (and store) the timer at clock 10 * 250 + 230 getting (for example) a value of 10.
  2. On another matrix scan, during debounce, we read the timer at exactly 15 * 250 + 10 clock cycles, meaning we get 15 as return.
  3. We consider 15 >= 10 + 5, and send the matrix update.
  4. The total debouncing time was thus 4.001875ms (4 * 250 + 30 cycles), not 5

We finished debouncing at less than 5 ms here. Currently, our approach only guarantees the debounce will happen at >= DEBOUNCE -1 time.

So we have two choices here:

  1. Move the checks back to >
  2. Let go of the timer being in ms and count in either us or ns, and bit-shift the value gotten from the interrupts if necessary, and then the check becomes more precise since we'll have the actual time. 32-bit should be enough for the purposes of debouncing, so even in ns precision we're talking about 4 seconds before it rolls over.

Originally posted by @andrebrait in #21667 (comment)

@andrebrait
Copy link
Contributor Author

Closing this to reopen it with the proper tags

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

1 participant