PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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.

128 lines
3.7KB

  1. // Please read Bounce2.h for information about the liscence and authors
  2. #if defined(ARDUINO) && ARDUINO >= 100
  3. #include "Arduino.h"
  4. #else
  5. #include "WProgram.h"
  6. #endif
  7. #include "Bounce2.h"
  8. #define DEBOUNCED_STATE 0
  9. #define UNSTABLE_STATE 1
  10. #define STATE_CHANGED 3
  11. Bounce::Bounce()
  12. : previous_millis(0)
  13. , interval_millis(10)
  14. , state(0)
  15. , pin(0)
  16. {}
  17. void Bounce::attach(int pin) {
  18. this->pin = pin;
  19. state = 0;
  20. if (digitalRead(pin)) {
  21. state = _BV(DEBOUNCED_STATE) | _BV(UNSTABLE_STATE);
  22. }
  23. #ifdef BOUNCE_LOCK_OUT
  24. previous_millis = 0;
  25. #else
  26. previous_millis = millis();
  27. #endif
  28. }
  29. void Bounce::attach(int pin, int mode){
  30. pinMode(pin, mode);
  31. this->attach(pin);
  32. }
  33. void Bounce::interval(uint16_t interval_millis)
  34. {
  35. this->interval_millis = interval_millis;
  36. }
  37. bool Bounce::update()
  38. {
  39. #ifdef BOUNCE_LOCK_OUT
  40. state &= ~_BV(STATE_CHANGED);
  41. // Ignore everything if we are locked out
  42. if (millis() - previous_millis >= interval_millis) {
  43. bool currentState = digitalRead(pin);
  44. if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
  45. previous_millis = millis();
  46. state ^= _BV(DEBOUNCED_STATE);
  47. state |= _BV(STATE_CHANGED);
  48. }
  49. }
  50. return state & _BV(STATE_CHANGED);
  51. #elif defined BOUNCE_WITH_PROMPT_DETECTION
  52. // Read the state of the switch port into a temporary variable.
  53. bool readState = digitalRead(pin);
  54. // Clear Changed State Flag - will be reset if we confirm a button state change.
  55. state &= ~_BV(STATE_CHANGED);
  56. if ( readState != (bool)(state & _BV(DEBOUNCED_STATE))) {
  57. // We have seen a change from the current button state.
  58. if ( millis() - previous_millis >= interval_millis ) {
  59. // We have passed the time threshold, so a new change of state is allowed.
  60. // set the STATE_CHANGED flag and the new DEBOUNCED_STATE.
  61. // This will be prompt as long as there has been greater than interval_misllis ms since last change of input.
  62. // Otherwise debounced state will not change again until bouncing is stable for the timeout period.
  63. state ^= _BV(DEBOUNCED_STATE);
  64. state |= _BV(STATE_CHANGED);
  65. }
  66. }
  67. // If the readState is different from previous readState, reset the debounce timer - as input is still unstable
  68. // and we want to prevent new button state changes until the previous one has remained stable for the timeout.
  69. if ( readState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
  70. // Update Unstable Bit to macth readState
  71. state ^= _BV(UNSTABLE_STATE);
  72. previous_millis = millis();
  73. }
  74. // return just the sate changed bit
  75. return state & _BV(STATE_CHANGED);
  76. #else
  77. // Read the state of the switch in a temporary variable.
  78. bool currentState = digitalRead(pin);
  79. state &= ~_BV(STATE_CHANGED);
  80. // If the reading is different from last reading, reset the debounce counter
  81. if ( currentState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
  82. previous_millis = millis();
  83. state ^= _BV(UNSTABLE_STATE);
  84. } else
  85. if ( millis() - previous_millis >= interval_millis ) {
  86. // We have passed the threshold time, so the input is now stable
  87. // If it is different from last state, set the STATE_CHANGED flag
  88. if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
  89. previous_millis = millis();
  90. state ^= _BV(DEBOUNCED_STATE);
  91. state |= _BV(STATE_CHANGED);
  92. }
  93. }
  94. return state & _BV(STATE_CHANGED);
  95. #endif
  96. }
  97. bool Bounce::read()
  98. {
  99. return state & _BV(DEBOUNCED_STATE);
  100. }
  101. bool Bounce::rose()
  102. {
  103. return ( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
  104. }
  105. bool Bounce::fell()
  106. {
  107. return !( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
  108. }