source: rtos_arduino/trunk/arduino_lib/libraries/ZumoShield/Pushbutton.cpp@ 232

Last change on this file since 232 was 232, checked in by ertl-honda, 8 years ago

Zumo用ライブラリの追加

File size: 5.2 KB
Line 
1#include "Pushbutton.h"
2
3// constructor; takes arguments specifying whether to enable internal pull-up
4// and the default state of the pin that the button is connected to
5Pushbutton::Pushbutton(unsigned char pin, unsigned char pullUp, unsigned char defaultState)
6{
7 _pin = pin;
8 _pullUp = pullUp;
9 _defaultState = defaultState;
10 gsdpState = 0;
11 gsdrState = 0;
12 gsdpPrevTimeMillis = 0;
13 gsdrPrevTimeMillis = 0;
14 initialized = false;
15}
16
17// wait for button to be pressed
18void Pushbutton::waitForPress()
19{
20 init(); // initialize if necessary
21
22 do
23 {
24 while (!_isPressed()){delay(1);}; // wait for button to be pressed
25 delay(10); // debounce the button press
26 }
27 while (!_isPressed()); // if button isn't still pressed, loop
28}
29
30// wait for button to be released
31void Pushbutton::waitForRelease()
32{
33 init(); // initialize if necessary
34
35 do
36 {
37 while (_isPressed()){delay(1);}; // wait for button to be released
38 delay(10); // debounce the button release
39 }
40 while (_isPressed()); // if button isn't still released, loop
41}
42
43// wait for button to be pressed, then released
44void Pushbutton::waitForButton()
45{
46 waitForPress();
47 waitForRelease();
48}
49
50// indicates whether button is pressed
51boolean Pushbutton::isPressed()
52{
53 init(); // initialize if necessary
54
55 return _isPressed();
56}
57
58// Uses a finite state machine to detect a single button press and returns
59// true to indicate the press (false otherwise). It requires the button to be
60// released for at least 15 ms and then pressed for at least 15 ms before
61// reporting the press. This function handles all necessary debouncing and
62// should be called repeatedly in a loop.
63boolean Pushbutton::getSingleDebouncedPress()
64{
65 unsigned long timeMillis = millis();
66
67 init(); // initialize if necessary
68
69 switch (gsdpState)
70 {
71 case 0:
72 if (!_isPressed()) // if button is released
73 {
74 gsdpPrevTimeMillis = timeMillis;
75 gsdpState = 1; // proceed to next state
76 }
77 break;
78
79 case 1:
80 if ((timeMillis - gsdpPrevTimeMillis >= 15) && !_isPressed()) // if 15 ms or longer has elapsed and button is still released
81 gsdpState = 2; // proceed to next state
82 else if (_isPressed())
83 gsdpState = 0; // button is pressed or bouncing, so go back to previous (initial) state
84 break;
85
86 case 2:
87 if (_isPressed()) // if button is now pressed
88 {
89 gsdpPrevTimeMillis = timeMillis;
90 gsdpState = 3; // proceed to next state
91 }
92 break;
93
94 case 3:
95 if ((timeMillis - gsdpPrevTimeMillis >= 15) && _isPressed()) // if 15 ms or longer has elapsed and button is still pressed
96 {
97 gsdpState = 0; // next state becomes initial state
98 return true; // report button press
99 }
100 else if (!_isPressed())
101 gsdpState = 2; // button is released or bouncing, so go back to previous state
102 break;
103 }
104
105 return false;
106}
107
108// Uses a finite state machine to detect a single button release and returns
109// true to indicate the release (false otherwise). It requires the button to be
110// pressed for at least 15 ms and then released for at least 15 ms before
111// reporting the release. This function handles all necessary debouncing and
112// should be called repeatedly in a loop.
113boolean Pushbutton::getSingleDebouncedRelease()
114{
115 unsigned int timeMillis = millis();
116
117 init(); // initialize if necessary
118
119 switch (gsdrState)
120 {
121 case 0:
122 if (_isPressed()) // if button is pressed
123 {
124 gsdrPrevTimeMillis = timeMillis;
125 gsdrState = 1; // proceed to next state
126 }
127 break;
128
129 case 1:
130 if ((timeMillis - gsdrPrevTimeMillis >= 15) && _isPressed()) // if 15 ms or longer has elapsed and button is still pressed
131 gsdrState = 2; // proceed to next state
132 else if (!_isPressed())
133 gsdrState = 0; // button is released or bouncing, so go back to previous (initial) state
134 break;
135
136 case 2:
137 if (!_isPressed()) // if button is now released
138 {
139 gsdrPrevTimeMillis = timeMillis;
140 gsdrState = 3; // proceed to next state
141 }
142 break;
143
144 case 3:
145 if ((timeMillis - gsdrPrevTimeMillis >= 15) && !_isPressed()) // if 15 ms or longer has elapsed and button is still released
146 {
147 gsdrState = 0; // next state becomes initial state
148 return true; // report button release
149 }
150 else if (_isPressed())
151 gsdrState = 2; // button is pressed or bouncing, so go back to previous state
152 break;
153 }
154
155 return false;
156}
157
158// initializes I/O pin for use as button inputs
159void Pushbutton::init2()
160{
161 if (_pullUp == PULL_UP_ENABLED)
162 pinMode(_pin, INPUT_PULLUP);
163 else
164 pinMode(_pin, INPUT); // high impedance
165
166 delayMicroseconds(5); // give pull-up time to stabilize
167}
168
169// button is pressed if pin state differs from default state
170inline boolean Pushbutton::_isPressed()
171{
172 return (digitalRead(_pin) == LOW) ^ (_defaultState == DEFAULT_STATE_LOW);
173}
Note: See TracBrowser for help on using the repository browser.