Pushbutton library
Pushbutton.cpp
1 // Copyright Pololu Corporation. For more information, see http://www.pololu.com/
2 
3 #include "Pushbutton.h"
4 
5 // \cond
6 
7 PushbuttonStateMachine::PushbuttonStateMachine()
8 {
9  state = 0;
10 }
11 
12 // state 0: The value is considered to be true.
13 // state 1: The value was considered to be true, but there
14 // was a recent false reading so it might be falling.
15 // state 2: The value is considered to be false.
16 // state 3: The value was considered to be false, but there
17 // was a recent true reading so it might be rising.
18 //
19 // The transition from state 3 to state 0 is the point where we
20 // have successfully detected a rising edge an we return true.
21 //
22 // The prevTimeMillis variable holds the last time that we
23 // transitioned to states 1 or 3.
24 bool PushbuttonStateMachine::getSingleDebouncedRisingEdge(bool value)
25 {
26  uint16_t timeMillis = millis();
27 
28  switch (state)
29  {
30  case 0:
31  // If value is false, proceed to the next state.
32  if (!value)
33  {
34  prevTimeMillis = timeMillis;
35  state = 1;
36  }
37  break;
38 
39  case 1:
40  if (value)
41  {
42  // The value is true or bouncing, so go back to previous (initial)
43  // state.
44  state = 0;
45  }
46  else if ((uint16_t)(timeMillis - prevTimeMillis) >= 15)
47  {
48  // It has been at least 15 ms and the value is still false, so
49  // proceed to the next state.
50  state = 2;
51  }
52  break;
53 
54  case 2:
55  // If the value is true, proceed to the next state.
56  if (value)
57  {
58  prevTimeMillis = timeMillis;
59  state = 3;
60  }
61  break;
62 
63  case 3:
64  if (!value)
65  {
66  // The value is false or bouncing, so go back to previous state.
67  state = 2;
68  }
69  else if ((uint16_t)(timeMillis - prevTimeMillis) >= 15)
70  {
71  // It has been at least 15 ms and the value is still true, so
72  // go back to the initial state and report this rising edge.
73  state = 0;
74  return true;
75  }
76  break;
77  }
78 
79  return false;
80 }
81 
82 // \endcond
83 
85 {
86  do
87  {
88  while (!isPressed()); // wait for button to be pressed
89  delay(10); // debounce the button press
90  }
91  while (!isPressed()); // if button isn't still pressed, loop
92 }
93 
95 {
96  do
97  {
98  while (isPressed()); // wait for button to be released
99  delay(10); // debounce the button release
100  }
101  while (isPressed()); // if button isn't still released, loop
102 }
103 
105 {
106  waitForPress();
107  waitForRelease();
108 }
109 
111 {
112  return pressState.getSingleDebouncedRisingEdge(isPressed());
113 }
114 
116 {
117  return releaseState.getSingleDebouncedRisingEdge(!isPressed());
118 }
119 
120 Pushbutton::Pushbutton(uint8_t pin, uint8_t pullUp, uint8_t defaultState)
121 {
122  initialized = false;
123  _pin = pin;
124  _pullUp = pullUp;
125  _defaultState = defaultState;
126 }
127 
128 void Pushbutton::init2()
129 {
130  if (_pullUp == PULL_UP_ENABLED)
131  {
132  pinMode(_pin, INPUT_PULLUP);
133  }
134  else
135  {
136  pinMode(_pin, INPUT); // high impedance
137  }
138 
139  delayMicroseconds(5); // give pull-up time to stabilize
140 }
141 
143 {
144  init(); // initialize if needed
145  return digitalRead(_pin) != _defaultState;
146 }
void waitForRelease()
Waits until the button is released and takes care of debouncing.
Definition: Pushbutton.cpp:94
virtual bool isPressed()
indicates whether button is currently pressed without any debouncing.
Definition: Pushbutton.cpp:142
bool getSingleDebouncedPress()
Uses a state machine to return true once after each time it detects the button moving from the releas...
Definition: Pushbutton.cpp:110
void waitForPress()
Waits until the button is pressed and takes care of debouncing.
Definition: Pushbutton.cpp:84
Pushbutton(uint8_t pin, uint8_t pullUp=PULL_UP_ENABLED, uint8_t defaultState=DEFAULT_STATE_HIGH)
Definition: Pushbutton.cpp:120
void waitForButton()
Waits until the button is pressed and then waits until the button is released, taking care of debounc...
Definition: Pushbutton.cpp:104
bool getSingleDebouncedRelease()
Uses a state machine to return true once after each time it detects the button moving from the presse...
Definition: Pushbutton.cpp:115
virtual bool isPressed()=0
indicates whether button is currently pressed without any debouncing.
#define PULL_UP_ENABLED
Definition: Pushbutton.h:20