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

Change to per-key eager debouncing for ErgoDox EZ. #1279

Merged
merged 1 commit into from
May 8, 2017
Merged

Conversation

awpr
Copy link
Contributor

@awpr awpr commented May 5, 2017

Empirically, waiting for N consecutive identical scans as a debouncing
strategy doesn't work very well for the ErgoDox EZ where scans are very
slow compared to most keyboards. Instead, debounce the signals by
eagerly reporting a change as soon as one scan observes it, but then
ignoring further changes from that key for the next N scans.

This is implemented by keeping an extra matrix of uint8 countdowns, such
that only keys whose countdown is currently zero are eligible to change.
When we do observe a change, we bump that key's countdown to DEBOUNCE.
During each scan, every nonzero countdown is decremented.

With this approach to debouncing, much higher debounce constants are
tolerable, because latency does not increase with the constant, and
debounce countdowns on one key do not interfere with events on other
keys. The only negative effect of increasing the constant is that the
minimum duration of a keypress increases. Perhaps I'm just extremely
unlucky w.r.t. key switch quality, but I saw occasional bounces even
with DEBOUNCE=10; with 15, I've seen none so far. That's around 47ms,
which seems like an absolutely insane amount of time for a key to be
bouncy, but at least it works.

(Note: I'm using DEBOUNCE=18 now since I saw intermittent bounces with 15).

Empirically, waiting for N consecutive identical scans as a debouncing
strategy doesn't work very well for the ErgoDox EZ where scans are very
slow compared to most keyboards.  Instead, debounce the signals by
eagerly reporting a change as soon as one scan observes it, but then
ignoring further changes from that key for the next N scans.

This is implemented by keeping an extra matrix of uint8 countdowns, such
that only keys whose countdown is currently zero are eligible to change.
When we do observe a change, we bump that key's countdown to DEBOUNCE.
During each scan, every nonzero countdown is decremented.

With this approach to debouncing, much higher debounce constants are
tolerable, because latency does not increase with the constant, and
debounce countdowns on one key do not interfere with events on other
keys.  The only negative effect of increasing the constant is that the
minimum duration of a keypress increases.  Perhaps I'm just extremely
unlucky w.r.t. key switch quality, but I saw occasional bounces even
with DEBOUNCE=10; with 15, I've seen none so far.  That's around 47ms,
which seems like an absolutely insane amount of time for a key to be
bouncy, but at least it works.
@fredizzimo
Copy link
Contributor

I don't have time to look at this right now, but from your description it seems like the same algorithm I described here #910, if you search for "A small possible improvement to the algorithm"

I have no idea why you need that high debounce times though, as the cherry specs states a maximum of 5 ms bouncing times. But maybe there's something with the EZ electronics that causes some kind of interference in some cases?

@awpr
Copy link
Contributor Author

awpr commented May 5, 2017

Yes, it's the same thing described in that comment. Note these are Gateron switches, not Cherry, but I agree it's pretty crazy for the signal to be bouncy for 50+ms. Nonetheless, everything I could think of to measure how long they thrash around has been giving about the same numbers -- if I turned off debouncing entirely, the worst few switches pretty consistently emitted 6-7 press/release pairs as I lifted the switch, which takes 14 scans for a total of 44.1ms (assuming 3.15ms per scan).

I'm not strongly opinionated on the actual value of the constant; I'm doubtful it's interference though, since this debouncing technique gives no protection against randomly-incorrect scans not associated with an actual change, and I haven't seen any fabricated events at all. My best guess is that the plastic in the switch stem is rough and makes the contact vibrate as it's released, which could conceivably last for 50ms.

Even if we leave the default value of the constant unchanged (or change it to 4 for equivalent behavior), I think the algorithm change is a worthwhile improvement since it gets rid of the 5 scans of latency introduced by the old algorithm, and makes it easier for users to work around weird switches by setting high DEBOUNCE values without significant side effects.

@ezuk
Copy link
Contributor

ezuk commented May 8, 2017

I personally think this is freaking awesome. Merging. Thank you, @awpr!

@ezuk ezuk merged commit 153eb95 into qmk:master May 8, 2017
@emombay
Copy link

emombay commented May 13, 2017

As a closing thought, has anyone seen this article about custom firmware, and look at the debouncing section? Wondering if his hybrid approach is doable (and beneficial). 600us delay for a clear signal sounds amazing. Though I could also be reading it wrong.

@fredizzimo
Copy link
Contributor

The algorithm in this pull request already implements something very similar to the "Quick Draw" method in the article, so that's optimal with regards to latency.

The hybrid approach looks insteresting, but unfortunately it wouldn't work on the Ergodox EZ, becasue the scanrate is so slow. For other QMK keyboards it could be worth looking at, but on the other hand, those don't suffer from the same problem, and the current debouncing algorithm works decently without too much latency.

For the EZ some ideas could potentially be taken for the key release case, where the bad contact situation could cause a false positive. Having some extra latency there would not afect normal typing, but for gaming I guess we still want very low latency for that as well.

One thing to remember is that we are talking about milliseconds, and at most a couple of tens of milliseconds, while the human reaction time is at least 200ms. A typical game has a latency of around 100 ms from input to the screen, and even more with a wireless controller, and that doesn't seem to be of a too much big disadvantage. See this for more information about that https://displaylag.com/console-latency-exploring-video-game-input-lag/

@awpr
Copy link
Contributor Author

awpr commented May 13, 2017 via email

@insidewhy
Copy link

insidewhy commented Apr 7, 2019

I really regret buying this keyboard, the issue is almost intolerable on the number keys and only stupidly high debounce can fix it. From what I can read here, it looks like there are hardware issues? Such a shame, the keyboard was almost excellent but so badly let down by this flaw.

@drashna
Copy link
Member

drashna commented Apr 7, 2019

@ohjames I'm sorry to hear that.

However, there have been some recent changes to the ergodox ez's code that may help.

Alos, if you haven't already, contact Ergodox EZ: [email protected]

@insidewhy
Copy link

@drashna I think given the number of commits about the debounce issue, and the number of comments online, it's obliterated my confidence in this keyboard. It really feels like there is a hardware issue going on.

It's such a shame, without the flaw it would be a 10/10 keyboard, with the flaw it's 0/10 :(

@insidewhy
Copy link

(Note: I'm using DEBOUNCE=18 now since I saw intermittent bounces with 15).

I have to use a DEBOUNCE of 40, and still occasionally get the problem :(

Tried two different replacement cables for the keyboard halves also, and deeply cleaned the thing. Nothing helps.

@alex-ong
Copy link
Contributor

alex-ong commented Jun 18, 2019

@ohjames
This keyboard definitely has hardware constraints due to the slow scan-rate. Have you tried the new eager-pr debounce method? It's yet another method in the long list of attempts to fix the problem. The change was made on April 4th. Should just be a matter of pulling and compiling the latest version. A DEBOUNCE of around 5-10 should suffice in this method

@insidewhy
Copy link

@alex-ong Yeah I tried that but it still didn't help.

@trunneml
Copy link

trunneml commented Jul 5, 2019

(Note: I'm using DEBOUNCE=18 now since I saw intermittent bounces with 15).

I have to use a DEBOUNCE of 40, and still occasionally get the problem :(

Tried two different replacement cables for the keyboard halves also, and deeply cleaned the thing. Nothing helps.

Is the problem on both sides or only on the left side?
What switches are in your ergodox?

I noticed that it is possible to wobble kailh copper speed switches on the trigger point. What creates multiple key presses. This isn't a real electrical bounce more a "bad" mechanical switch design.

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

Successfully merging this pull request may close these issues.

8 participants