keybrd library is an open source library for creating custom-keyboard firmware.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

Debouncer_Samples.cpp 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* debounce() function
  2. Debounce uses multiple samples to debounces switch states,
  3. where each sample contains the switch states for a row of switches, one bit per switch.
  4. Debounce uses Dr. Marty's debounce algorithm from
  5. http://drmarty.blogspot.com.br/2009/05/best-switch-debounce-routine-ever.html
  6. SPI, I2C, and TWI protocols do not include any Packet Error Checking (PEC).
  7. The goal of Marty's debounce routine is to reject spurious signals,
  8. which is useful when connecting split keyboards with a cable using SPI, I2C, or TWI.
  9. This class was tested on split keyboard with a 3-meter long telephone wire to I/O expander.
  10. Dr. Marty's debounce algorithm:
  11. Periodically read samples and update the state when a number consecutive sample bits are equal.
  12. Output from keybrd/examples/debounce_unit_test.cpp with SAMPLE_COUNT 4:
  13. button pressed: 100000001111111110000
  14. bouncy signal: 100001001111011110000
  15. debounced signal: 000000000001111111110
  16. isFallingEdge: 000000000000000000001
  17. isRisingEdge: 000000000001000000000
  18. There is a latency equal to SAMPLE_COUNT, between button press and debounced signal.
  19. samples[SAMPLE_COUNT] is a ring buffer. samplesIndex is it's current write index.
  20. SAMPLE_COUNT is the number of consecutive equal samples needed to debounce.
  21. SAMPLE_COUNT is defined in config_keybrd.h and should be at lease 1.
  22. SAMPLE_COUNT = 4 is very reliable for a keyboard.
  23. Split keyboards with a long connecting wire or in environment with
  24. strong electromagnetic interference (EMI) may need a larger SAMPLE_COUNT for reliability.
  25. */
  26. #include "Debouncer_Samples.h"
  27. /* debounce() sets debounced and returns debouncedChanged.
  28. All parameters and variables are bit patterns.
  29. For parameters, 1 means pressed, 0 means released.
  30. For return, 1 means debounced changed.
  31. */
  32. read_pins_t Debouncer_Samples::debounce(const read_pins_t rawSignal, read_pins_t& debounced)
  33. {
  34. read_pins_t previousDebounced; //bits, 1 means pressed, 0 means released
  35. read_pins_t all_1 = ~0; //bits
  36. read_pins_t all_0 = 0; //bits
  37. samples[samplesIndex] = rawSignal; //insert rawSignal into samples[] ring buffer
  38. if (++samplesIndex >= SAMPLE_COUNT) //if end of ring buffer
  39. {
  40. samplesIndex = 0; //wrap samplesIndex to beginning of ring buffer
  41. }
  42. for (uint8_t j = 0; j < SAMPLE_COUNT; j++) //traverse the sample[] ring buffer
  43. {
  44. all_1 &= samples[j]; //1 if all samples are 1
  45. all_0 |= samples[j]; //0 if all samples are 0
  46. }
  47. previousDebounced = debounced;
  48. // update debounced if all the samples agree with one another
  49. // if all samples=1 then debounced=1
  50. // elseif all samples=0 then debounced=0
  51. // else debounced=previousDebounced i.e. no change
  52. debounced = all_1 | (all_0 & previousDebounced);
  53. return debounced xor previousDebounced;
  54. }