keybrd library is an open source library for creating custom-keyboard firmware.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

debounce_unit_test.cpp 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* test debounce() function. 16/6/1 Passed test for SAMPLE_COUNT 1, 2, and 4.
  2. copied from keybrd/src/Row::debounce()
  3. to run test:
  4. $ g++ debounce_unit_test.cpp
  5. $ ./a.out
  6. */
  7. #include <inttypes.h>
  8. #include <iostream>
  9. #define SAMPLE_COUNT 4 //number of consecutive equal bits needed to change a debounced bit
  10. uint8_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings
  11. uint8_t samplesIndex = 0; //samples[] current write index
  12. uint8_t previousDebounced = 0; //bitwise, one bit per key
  13. uint8_t debounced; //1 means pressed, 0 means released
  14. uint8_t isFallingEdge; //1 means falling edge
  15. uint8_t isRisingEdge; //1 means rising edge
  16. uint8_t debounce(const uint8_t rowState)
  17. {
  18. uint8_t debouncedChanged; //bitwise
  19. uint8_t all_1 = ~0; //bitwise
  20. uint8_t all_0 = 0; //bitwise
  21. //delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce key
  22. samples[samplesIndex] = rowState; //insert rowState into samples[] ring buffer
  23. if (++samplesIndex >= SAMPLE_COUNT) //if end of ring buffer
  24. {
  25. samplesIndex = 0; //wrap samplesIndex to beginning of ring buffer
  26. }
  27. for (uint8_t j = 0; j < SAMPLE_COUNT; j++) //traverse the sample[] ring buffer
  28. {
  29. all_1 &= samples[j]; //1 if all samples are 1
  30. all_0 |= samples[j]; //0 if all samples are 0
  31. }
  32. // update newDebounce if all the samples agree with one another
  33. // if all samples=1 then debounced=1
  34. // elseif all samples=0 then debounced=0
  35. // else debounced=previousDebounced i.e. no change
  36. debounced = all_1 | (all_0 & previousDebounced);
  37. debouncedChanged = debounced xor previousDebounced;
  38. previousDebounced = debounced;
  39. return debouncedChanged;
  40. }
  41. void pressRelease(const uint8_t debouncedChanged)
  42. {
  43. //bit=1 if last debounced changed from 1 to 0, else bit=0
  44. isFallingEdge = debouncedChanged & ~previousDebounced;
  45. //bit=1 if last debounced changed from 0 to 1, else bit=0
  46. isRisingEdge = debouncedChanged & previousDebounced;
  47. }
  48. int main()
  49. {
  50. //Test input and output only shows first bit of each byte.
  51. const uint8_t pressed[] = {1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0};
  52. const uint8_t bouncy[] = {1,0,0,0,0,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0};
  53. const uint8_t expectDebounced[]= {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0}; //SAMPLE_COUNT 4
  54. const uint8_t SCAN_COUNT = sizeof(bouncy)/sizeof(*bouncy);
  55. uint8_t i;
  56. uint8_t debouncedChanged; //1 means debounced changed
  57. std::cout << "button pressed: ";
  58. for (i=0; i<SCAN_COUNT; i++)
  59. {
  60. std::cout << (int)pressed[i];
  61. }
  62. std::cout << std::endl;
  63. std::cout << "bouncy signal: ";
  64. for (i=0; i<SCAN_COUNT; i++)
  65. {
  66. std::cout << (int)bouncy[i];
  67. }
  68. std::cout << std::endl;
  69. std::cout << "debounced signal: ";
  70. for (i=0; i<SCAN_COUNT; i++)
  71. {
  72. debouncedChanged = debounce(bouncy[i]);
  73. //pressRelease(debouncedChanged);
  74. std::cout << (int)debounced;
  75. }
  76. std::cout << std::endl;
  77. std::cout << "expected debounced signal: ";
  78. for (i=0; i<SCAN_COUNT; i++)
  79. {
  80. std::cout << (int)expectDebounced[i];
  81. }
  82. std::cout << std::endl;
  83. std::cout << "isFallingEdge: ";
  84. for (i=0; i<SCAN_COUNT; i++)
  85. {
  86. debouncedChanged = debounce(bouncy[i]);
  87. pressRelease(debouncedChanged);
  88. std::cout << (int)isFallingEdge;
  89. }
  90. std::cout << std::endl;
  91. std::cout << "isRisingEdge: ";
  92. for (i=0; i<SCAN_COUNT; i++)
  93. {
  94. debouncedChanged = debounce(bouncy[i]);
  95. pressRelease(debouncedChanged);
  96. std::cout << (int)isRisingEdge;
  97. }
  98. std::cout << std::endl;
  99. }
  100. void loop() { }