This post inspired me a few years ago to start a very impractical learning side project. Most keyboards don't overly prioritize latency. Development of a keyboard is easy using a USB stack from the manufacturer, but it might not prioritize latency.
I'm working on making my own FPGA based USB 2.0 HID device that will let me minimize any latency in the stack. PCB layout is mostly done, I'm working on a DECA FPGA board to prove out the USB hid software now. I started this pre covid though when Mach XO2s were inexpensive and available, so I have no idea who I will need to fight these days to get parts when I get to that point.
There is lots of wiggle room too in how you implement your debounce algorithm to optimize latency too. I'm excited to control the whole stack to try to make this as fast as possible. The Logitech lightspeed products came out after I started this project though and are far more practical for most people. I have one of those at home and will try to benchmark and compare them when I get there.
I have written USB device firmware for AVR, and read docs for a bunch of microcontroller families' with different internal HID device units that I wanted to port to.
If you do take suggestions for your next version, there are some hardware features that I would like:
* Let the MCU replace the next unsent input report, and atomically. Many USB devices can only queue reports, not replace them.
* Allow the microcontroller to know when a input report has been received. (ACK)
The first would make it possible to get the lowest latency with reports such as keyboard reports that contains only the state of momentary switches.
The second would make it possible to ensure that an event has been received, even if the host would poll at a slower rate than what the firmware works at.
The situation is especially complex for mice, where the reports have inputs that are relative — to the previous report.
I'm not familiar with that definition, I typically see debouncing used as any means to filter out the state as it is changing from the mechanical action.
I've seen simple BSP debounce example code that affects latency for both press/release. For example you can make sure the IO hasn't changed in X ms before accepting it as settled and reporting the event up. This way would incur latency on both press and release. In fact, the first answer I see on google does this:
https://www.beningo.com/7-steps-to-create-a-reusable-debounc...
You could report the event right away when there is an activation, and just not allow a deactivation event to be reported until the debounce time has expired. I suspect this is what you mean by debounce only applying on deactivation, but I'll bet some of the keyboards tested on that list are not doing this.
I mean, sure, there if you're looking for a general-purpose way of doing things then that example is fine. If you have a normally-open switch and a latency sensitive application then there's one pretty clear implementation.
I've seen implementations where the CPU gets the pulse, waits for debounce interval, check whether the pulse is still happening and only then sends "the button is on" signal, which obviously is terrible for latency.
Proper debounce will send signal immediately then ignore the state for few milliseconds.
> Debouncing is about preventing inappropriate deactivation, and is unrelated to time to initial activation.
It's both. Contacts generate noise on both press and depress.
I thought it's about preventing inappropriate reactivation? As in, the key slightly bouncing back and forth when you press it, thereby registering two (or more) activations per press
I suppose we should really talk about changes in state rather than activation/deactivation as it's the same problem. But the basic point is that detecting an edge on an "armed" switch is all that's necessary to fire the related event and confirm the state change definitively.
The debouncing logic is about how we determine when to re-arm the switch for the next transition - i.e. how to reject the "false" reversions to the prior state. So it shouldn't have any impact on the "physical action to key-down event" latency in systems with a reasonable steady state. I guess for cases where "pound on the same key again and again as quickly as possible" are in scope it does?
I'm working on making my own FPGA based USB 2.0 HID device that will let me minimize any latency in the stack. PCB layout is mostly done, I'm working on a DECA FPGA board to prove out the USB hid software now. I started this pre covid though when Mach XO2s were inexpensive and available, so I have no idea who I will need to fight these days to get parts when I get to that point.
There is lots of wiggle room too in how you implement your debounce algorithm to optimize latency too. I'm excited to control the whole stack to try to make this as fast as possible. The Logitech lightspeed products came out after I started this project though and are far more practical for most people. I have one of those at home and will try to benchmark and compare them when I get there.