Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Question: Optimal debouncing time in Ergodox EZ #910
Disclaimer This answer is written from a purely theoretical point of view, and I have not verified what I say in practice.
I'm also assuming that the following statement is correct, but someone with an Ergodox EZ should be able to confirm by enabling the
But before going further @okapies, you say that the default debounce is disabled, how did you come to that conclusion? It's defined as 5 in
First let's define what debouncing is, since it's often perceived as something complex and almost magical, while it's in fact a very simple concept.
Debouncing is nothing more than a method of removing the effect of electrical noise caused by mechanical switches. Or in even more practical term a way to make sure that you don't see double keystrokes when you press and release keys.
There are a couple of causes for this, and I believe the first one is the only valid one, the second one probably only happens during a huge solar storm or similar, nevertheless debouncing typically takes care of both cases.
So to make things really simple, if you see key presses that you don't want, you need debouncing.
The debouncing algorithm for the Ergodox EZ is simple. Each time it see a change in the pressed keys (including bouncing signal), it sets the
There's a slight bug in the code, it actually waits for
So in even more simple terms it does this.
As you can see the
For really high debouncing values, there's another effect. The keyboard can start to ignore key presses, since it would consider real key presses as just noise.
So let's look at the recommended value of two
So let us consider a key press, with the initial state of not pressed and we run the first scan immediately when the key is pressed.
So it shouldn't be possible for any false reports there. If the first scan is run a little bit later, it would just add 0 - 3.15ms extra latency, but the end results will be the same
In other words two is theoretically optimal
A practical way of finding the optimal value
You will end up with the optimal value for your switches. There's no need to go beyond what works, it only adds additional latency. This way of doing it would also make sure everything works in case you have constant EMI.
I'm not sure how @ezuk came to his conclusion, but in my opinion 5 is way too high.
A small possible improvement to the algorithm
The reason why we could do like that is that any change we see after a confirmed state has to be real. But changes within 5ms of that could be caused by bounces, so they should be ignored. After 5ms we should again have a stable signal, and we can report any changes that are seen again.
@fredizzimo: Thanks so much for your very very detailed explanation! Now I fully understand how the debouncing works (and its side-effect) and how to configure
Wow! Oh, my Buddha. You're absolutely right. It seems that the C parser installed on my head is contaminated by Python-like syntax and ignores the
I think there's no bug.
and this is exactly what happens. When
Setting number of scans to 0 makes no sense as clearly you need at least 1 scan to observe any change.
I don't think so.
I think the above calculation is wrong.
If this reasoning is ok then I think the comment in code should be expanded to include some of the above reasoning and the
Well, I'm pretty sure that it was originally planned to represent milliseconds an that the comment was added later. That's because the scan loop used to wait for 1 millesecond, at least for most other keyboards. And of course after @IBNobody's latest changes it really means ms . But the other reason why I believe it's a bug is what Hasu said here
Anyway, let's get to the real discussion.
And when you release a key
Pressed state is true when t < T
First let me explain why two is optimal.
With the debouncing, we want to prevent the situation where we read the wrong value, after we have read the correct one. As you already mentioned we have at most two scans inside the interval T <= t < T + 5, so let's analyse the three possible cases for those first (for keypresses, but you can reverse the logic for releases), the value inside the parenthesis is a known value, it can't be anything else.
As you can see there's no way to read a false after having read two consecutive trues, so the debouncing does it's job. Also if either D or E, is false, it can only mean that we have released the key, so we are allowed to report a release. Also note that only the second case would report a doubled keypress without debouncing.
The other case that we have is when we only have one scan inside the interval, then we have the following cases
Again, you can see that there's no reason to go higher. Is there any case that I'm missing?
For the latency calculations, I was calculating with the default of 5, while you seem to be using 3. But anyway for minimum we seem to agree as following your formula, (5-1) * 3.15 ms = 12.6 ms
But for the maximum, I think we both are wrong, it's even higher. The worst case situation occurs when a switch is just below the specs, and we read a wrongly bounced value at close to 5 ms after T, lets say at T + 4.99ms for this example.
T + 1.84 ms (4.99 - 3.15) - true or false does not matter
So the maximum latency is 20.74 ms for the example above
So we have these formulas for
So with a debounce of 5
For a debounce of 2
And for the best case optimized algorithm, which I described in my previous message would have a
You specify 3 periods ( t < T, t >= T, T >= T + 5) but 5 columns (A-E). I don't know how to match one with the other.
There's a typo, T>=T+5 should be t >=T+5, and it applies to columns, D and E, in the first table, and C, D and E in the second.
No, Im talking about all the required scans needed too, or the value to set for DEBOUNCE. We only need to read the same new state two times in a row in order to be sure that we never read an invalid value again. The third value we read has to be the correct one, so once we have read the same new state twice, we can assume that the third one will be too.
Lets take an example, if we are detecting a keypress, it's not possible to read "press, press, release", unless we really have a real keypress followed by a release. The read of release would happen after T+5, which is not physically possible unless the key is physically released. In that case we are of course allowed to report a press followed by release, but only after seeing two consecutive release states, after the two press states.
What makes you think so? Two consecutive scans span period of 3.15ms. If key was released immediately before the first scan then both scans take place during the 5ms period of signal instability so we could get false value of readout in both scans, namely the value for a pressed key although the key had been released immediately before the first scan. Only in the subsequent, 3rd scan we are guaranteed to obtain true value as this scan takes place at least 2*3.15ms=6.30ms after the key had been released so after the 5ms period of signal instability.
Since you are talking about key release, I assume that you are talking about the following case
You have a key pressed, and the keyboard currently reports that that's the case. You then release it.
So, if both scans reads the state wrongly
So, I don't see how we get a false value with a DEBOUNCE value of 2 here.
Maybe I'm still misunderstanding something, could you show a concrete example with timings to show how we the wrong state can be reported?
So what I'm searching for is a similar example, but where we get the wrong report with a DEBOUNCE value of only 2, and a value of 3 would fix the situation.
I have been using an Atreus 62 and realized thanks to this thread that my spacebar chattering issue is not due to switches (replaced it three times still some chatter), but rather due to EMI. The default setting in the config.h file was 5, so I just upped it to 6 and it went from infrequent chatter to NONE so far. I know this is different than the ergodox EZ, but it shows 5 was not too high in this situation.
I still think fredizzimo's advice is the best: start at 1 and constantly up the debounce until there is no chatter. So helpful for me!