Author Topic: How fast to iterate around the matrix?  (Read 2575 times)

0 Members and 1 Guest are viewing this topic.

Offline guidoism

  • Thread Starter
  • Posts: 2
  • Location: Louisville, KY
How fast to iterate around the matrix?
« on: Sat, 16 June 2018, 07:31:03 »
Howdy!

In order to really understand how these things work I'm working on a hand-wired keyboard with a micro controller running the most basic, simplified matrix decoding code ever. I've been reading around so I understand the basics, but one thing I don't understand is how fast we want to bang through each matrix loop.

But the code samples I've looked at seem to just go through everything at full-tilt, which makes my software-engineering stomach turn. Is that really what we do? Or do we sleep until some programmer-specified discrete step, like 1ms per matrix scan?


Offline vvp

  • Posts: 886
Re: How fast to iterate around the matrix?
« Reply #1 on: Sat, 16 June 2018, 07:52:22 »
Depends on your switches. Most MX switches have debounce time around 5 ms. It makes sense to iterate few times in that period. Let's say in the interval of 1 to 2 ms per iteration.

Offline Koren

  • Posts: 133
  • Location: France
Re: How fast to iterate around the matrix?
« Reply #2 on: Sat, 16 June 2018, 11:13:58 »
But the code samples I've looked at seem to just go through everything at full-tilt, which makes my software-engineering stomach turn. Is that really what we do?
Well, it's a microcontroller, with limited ressources. When you think about everything you need to do with scanned data, you'll quickly see that you won't get that high a rate anyway.

Offline Findecanor

  • Posts: 5036
  • Location: Koriko
Re: How fast to iterate around the matrix?
« Reply #3 on: Sat, 16 June 2018, 17:38:51 »
I think going "full tilt" is to shave off a fraction of a millisecond of response time ... which might happen if the key happens to start being debounced at just the right moment within the USB port's one-millisecond cycle.
But some firmwares I have seen stop scanning other keys to debounce just one key, which of course would delay events from other keys that happen to be pressed/released simultaneously.

My own (unreleased) firmware for the AVR has the microcontroller's normal mode be a sleep mode, and the main loop woken up by an interrupt every millisecond. That works fine of course. I have not actually measured it but I believe that it would use less power as well. All keys are also debounced every time using a bitfield representation of keyswitch state.

If there was an interrupt that was triggered when the host actually polled for the report, which set a timer that would weak up the mainloop so that it would finish right before the host polled again... then that code would shave off a fraction of a millisecond like a "full tilt" firmware and be able to save power and debounce all keys at once.
But you can't be sure that the host will poll at the same time within every cycle. If that happens or if more than one event would be triggered at once then the code would no longer work within bounds and the penalty could be one full millisecond extra.
And frankly, I see no reason to hunt for fractions of milliseconds....

BTW.  Right now, My code uses a timer but the AVR also has a USB interrupt that would be triggered every USB millisecond cycle while the USB port is active.
I have been thinking of instead rewriting the code to have a much slower timer (set more suitably for waking up from standby mode), and use the USB cycle interrupt to wake up the normal main loop and reset the timer. Then when USB standby mode has been entered, that USB cycle interrupt would simply stop triggering, which would let the timer run its course.
« Last Edit: Sat, 16 June 2018, 17:50:15 by Findecanor »

Offline guidoism

  • Thread Starter
  • Posts: 2
  • Location: Louisville, KY
Re: How fast to iterate around the matrix?
« Reply #4 on: Sun, 17 June 2018, 12:22:02 »
It's interesting to know that full-tilt on slower micro controllers and every-ms timers on faster processors are both approaches that are being used.

Offline vvp

  • Posts: 886
Re: How fast to iterate around the matrix?
« Reply #5 on: Sun, 17 June 2018, 15:30:28 »
If there was an interrupt that was triggered when the host actually polled for the report, which set a timer that would weak up the mainloop so that it would finish right before the host polled again... then that code would shave off a fraction of a millisecond like a "full tilt" firmware and be able to save power and debounce all keys at once.
The first thing is that this approach would be statistical in its nature anyway. But you already indicated it (we do not know how long after the start of frame (SOF) our IN token arrives; this delay can be changing).
Anyway, most of the time the response to the IN token is NAK and you can get both SOF interrupt and NAK interrupt. So you can build a statistic how late IN token is sent after the SOF token.

That being said, I do not think this makes sense. If you would scan matrix once in 1 ms, then you get average latency increase of 0.5 ms because of missing synchronization with the IN tokens. Compare this to the mandatory debounce time of 5 ms for MX switches. So you improve your average latency actually only by 0.5/5 = 10% at best. The latency after the user actually presses the key. I do not think it is worth the effort and the lost MCU ticks to build the statistic and behave based on it.

Offline JianYang

  • Posts: 114
Re: How fast to iterate around the matrix?
« Reply #6 on: Mon, 18 June 2018, 01:11:11 »
If there was an interrupt that was triggered when the host actually polled for the report, which set a timer that would weak up the mainloop so that it would finish right before the host polled again... then that code would shave off a fraction of a millisecond like a "full tilt" firmware and be able to save power and debounce all keys at once.
The first thing is that this approach would be statistical in its nature anyway. But you already indicated it (we do not know how long after the start of frame (SOF) our IN token arrives; this delay can be changing).
Anyway, most of the time the response to the IN token is NAK and you can get both SOF interrupt and NAK interrupt. So you can build a statistic how late IN token is sent after the SOF token.

That being said, I do not think this makes sense. If you would scan matrix once in 1 ms, then you get average latency increase of 0.5 ms because of missing synchronization with the IN tokens. Compare this to the mandatory debounce time of 5 ms for MX switches. So you improve your average latency actually only by 0.5/5 = 10% at best. The latency after the user actually presses the key. I do not think it is worth the effort and the lost MCU ticks to build the statistic and behave based on it.

I do not follow your math? Debounce should not add to latency. You know a switch has been pressed - just not when it is released while it is bouncing.

Offline vvp

  • Posts: 886
Re: How fast to iterate around the matrix?
« Reply #7 on: Mon, 18 June 2018, 01:42:59 »
I do not follow your math? Debounce should not add to latency. You know a switch has been pressed - just not when it is released while it is bouncing.
Depends when you do debouncing:
  • switch release only
  • switch press only
  • both switch press and release
The first option adds latency only to the key release.
The last option is the most robust.

As for as using the first option, the question is: Should the switch register as being pressed for 5 ms when it was registered as connected for e.g. 1 ms?

Offline JianYang

  • Posts: 114
Re: How fast to iterate around the matrix?
« Reply #8 on: Mon, 18 June 2018, 03:01:56 »
I do not follow your math? Debounce should not add to latency. You know a switch has been pressed - just not when it is released while it is bouncing.
Depends when you do debouncing:
  • switch release only
  • switch press only
  • both switch press and release
The first option adds latency only to the key release.
The last option is the most robust.

As for as using the first option, the question is: Should the switch register as being pressed for 5 ms when it was registered as connected for e.g. 1 ms?

I don't think it will matter at all. But I do not think there is a simple and memory-efficient software solution to measure sub-debounce periods for release-only debounce?

If your main concern is power use, then the best solution would probably be to sleep and not scan the matrix unless a button is pressed. So in that case you would need interrupts on all the either(rows|columns) so that you only wake up when you know a key is down, and then do your matrix scanning.

Are you planning on writing this for a bluetooth controller?

Offline vvp

  • Posts: 886
Re: How fast to iterate around the matrix?
« Reply #9 on: Mon, 18 June 2018, 04:10:36 »
I don't think it will matter at all.
I agree, it does not really matter. But I also think it does not make sense to build the statistic of usb IN token timing to improve key press latencies  by 0.5 ms on average.

But I do not think there is a simple and memory-efficient software solution to measure sub-debounce periods for release-only debounce?
It is impossible. By defintion (or by switch specification), we only know that the switch state changed after the debounce period. So one cannot reliably send key presses shorter than the debounce period to the host. The question is only whether key presses shorter than the debounce period should register at all.  If you do not debounce on key press then they register. From the statistics point of view of how long key are reported as pressed:
  • debounce at start only - average of reported times will be shorter by 5 ms, very short presses not registered
  • debounce at end only - average of reported times will be longer by 5 ms, very short presses registered as 5 ms presses
  • debounce at start and end - average of reported times will be the same; very short presses not registred
My opinion is that it does not really matter. I debounce both on press and release simply since it is more robust. I do not want my shaky finger or a noise to lead to spurious 5 ms key press.

Are you planning on writing this for a bluetooth controller?
No, I hate hassle with batteries more than hassle with a cable. Therefore no bluetooth for me until I change my mind :)

I responded to this thread only because I believe there is a way to build the statistics Findecanor indicated as impossible.