Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: city1082-capsense-sw2-tft-leds CITY1082-TFT-basic_sw2_ctr 4180_final_project_github mRotaryEncoder_HelloWorld-os ... more
PinDetect.h
00001 /* 00002 Copyright (c) 2010 Andy Kirkham, 2018 Christopher Arndt 00003 Permission is hereby granted, free of charge, to any person obtaining a copy 00004 of this software and associated documentation files (the "Software"), to deal 00005 in the Software without restriction, including without limitation the rights 00006 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00007 copies of the Software, and to permit persons to whom the Software is 00008 furnished to do so, subject to the following conditions: 00009 The above copyright notice and this permission notice shall be included in 00010 all copies or substantial portions of the Software. 00011 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00012 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00013 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00014 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00015 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00017 THE SOFTWARE. 00018 */ 00019 00020 #ifndef PIN_DETECT_H 00021 #define PIN_DETECT_H 00022 00023 #include "mbed.h" 00024 00025 #ifndef PINDETECT_PIN_ASSERTED 00026 #define PINDETECT_PIN_ASSERTED 1 00027 #endif 00028 00029 #ifndef PINDETECT_SAMPLE_PERIOD 00030 #define PINDETECT_SAMPLE_PERIOD 20000 00031 #endif 00032 00033 #ifndef PINDETECT_ASSERT_COUNT 00034 #define PINDETECT_ASSERT_COUNT 1 00035 #endif 00036 00037 #ifndef PINDETECT_HOLD_COUNT 00038 #define PINDETECT_HOLD_COUNT 50 00039 #endif 00040 00041 namespace AjK { 00042 00043 /** PinDetect adds mechanical switch debouncing to DigitialIn and interrupt callbacks. 00044 * 00045 * This is done by sampling the specified pin at regular intervals and detecting any 00046 * change of state ( 0 -> 1 or 1 -> 0 ). When a state change is detected the attached 00047 * callback handler is called. Additionally, if the pin stays in the same state after 00048 * a state change for a defined period of time, an extra callback is made allowing a 00049 * program to detect when a "key is pressed and held down" rather than a momentary 00050 * key/switch press. 00051 * 00052 * All parameters are customisable which include:- 00053 * <ul> 00054 * <li> The sampling frequency. </li> 00055 * <li> The number of continuous samples until a state change is detected. </li> 00056 * <li> The number of continuous samples until a key is assumed held after a state change. </li> 00057 * <li> The logic level which is assumed to be asserted (0volts or +volts). </li> 00058 * </ul> 00059 * 00060 * Only callbacks that have been attached will be called by the library. 00061 * 00062 * Example: 00063 * @code 00064 * #include "mbed.h" 00065 * #include "PinDetect.h" 00066 * 00067 * PinDetect pin(p30); 00068 * DigitialOut led1(LED1); 00069 * DigitialOut led2(LED2); 00070 * DigitialOut led3(LED3); 00071 * DigitialOut led4(LED4); 00072 * 00073 * void keyPressed(void) { 00074 * led2 = 1; 00075 * led3 = 0; 00076 * led4 = 0; 00077 * } 00078 * 00079 * void keyReleased(void) { 00080 * led2 = 0; 00081 * led3 = 0; 00082 * led4 = 0; 00083 * } 00084 * 00085 * void keyPressedHeld(void) { 00086 * led3 = 1; 00087 * } 00088 * 00089 * void keyReleasedHeld(void) { 00090 * led4 = 1; 00091 * } 00092 * 00093 * int main() { 00094 * pin.mode(PullDown); 00095 * pin.attach_asserted(keyPressed); 00096 * pin.attach_deasserted(keyReleased); 00097 * pin.attach_asserted_held(keyPressedHeld); 00098 * pin.attach_deasserted_held(keyReleasedHeld); 00099 * 00100 * // Sampling does not begin until you set a frequency. 00101 * // The default is 20ms. If you want a different frequency 00102 * // then pass the period in microseconds for example, for 10ms :- 00103 * // pin.setSampleFrequency(10000); 00104 * // 00105 * pin.setSampleFrequency(); // Defaults to 20ms. 00106 * 00107 * while (1) { 00108 * led1 = !led1; 00109 * wait(0.2); 00110 * } 00111 * } 00112 * @endcode 00113 * 00114 * This example will flash led1 in a similar to a standard starting program. 00115 * 00116 * Applying a "1" (switch on) to pin 30 will switch on led2, removing the "1" to "0" 00117 * (switch off) led2 goes out. Holding the "switch" at one for one second will switch 00118 * on led3. An unasserted P30 (switched off) will, after one second illuminate led4 00119 * when the deasserted calledback is called. 00120 * 00121 * The above is a very basic introduction. For more details:- 00122 * @see example.h 00123 */ 00124 class PinDetect { 00125 00126 protected: 00127 DigitalIn *_in; 00128 Ticker *_ticker; 00129 int _prevState; 00130 int _sampleTime; 00131 int _assertValue; 00132 int _samplesTillAssertReload; 00133 int _samplesTillAssert; 00134 int _samplesTillHeldReload; 00135 int _samplesTillHeld; 00136 Callback<void()> _callbackAsserted; 00137 Callback<void()> _callbackDeasserted; 00138 Callback<void()> _callbackAssertedHeld; 00139 Callback<void()> _callbackDeassertedHeld; 00140 00141 /** initialise class 00142 * 00143 * @param PinName p is a valid pin that supports DigitalIn 00144 * @param PinMode m The mode the DigitalIn should use. 00145 */ 00146 void init(PinName p, PinMode m) { 00147 _sampleTime = PINDETECT_SAMPLE_PERIOD; 00148 _samplesTillAssert = PINDETECT_ASSERT_COUNT; 00149 _samplesTillHeld = 0; 00150 _samplesTillAssertReload = PINDETECT_ASSERT_COUNT; 00151 _samplesTillHeldReload = PINDETECT_HOLD_COUNT; 00152 _assertValue = PINDETECT_PIN_ASSERTED; 00153 00154 _in = new DigitalIn(p); 00155 _in->mode(m); 00156 _prevState = _in->read(); 00157 _ticker = new Ticker; 00158 } 00159 00160 public: 00161 friend class Ticker; 00162 00163 PinDetect() { 00164 error("You must supply a PinName"); 00165 } 00166 00167 /** PinDetect constructor 00168 * 00169 * By default the PinMode is set to PullDown. 00170 * 00171 * @see http://mbed.org/handbook/DigitalIn 00172 * @param p PinName is a valid pin that supports DigitalIn 00173 */ 00174 PinDetect(PinName p) { 00175 init(p, PullDown); 00176 } 00177 00178 /** PinDetect constructor 00179 * 00180 * @see http://mbed.org/handbook/DigitalIn 00181 * @param PinName p is a valid pin that supports DigitalIn 00182 * @param PinMode m The mode the DigitalIn should use. 00183 */ 00184 PinDetect(PinName p, PinMode m) { 00185 init(p, m); 00186 } 00187 00188 /** PinDetect destructor 00189 */ 00190 ~PinDetect() { 00191 if (_ticker) delete(_ticker); 00192 if (_in) delete(_in); 00193 } 00194 00195 /** Set the sampling time in microseconds. 00196 * 00197 * @param int The time between pin samples in microseconds. 00198 */ 00199 void setSampleFrequency(int i=PINDETECT_SAMPLE_PERIOD) { 00200 _sampleTime = i; 00201 _prevState = _in->read(); 00202 _ticker->attach_us(callback(this, &PinDetect::isr), _sampleTime); 00203 } 00204 00205 /** Set the value used as assert. 00206 * 00207 * Defaults to 1 (i.e. if pin == 1 then pin asserted). 00208 * 00209 * @param int New assert value (1 or 0) 00210 */ 00211 void setAssertValue(int i=PINDETECT_PIN_ASSERTED) { 00212 _assertValue = i & 1; 00213 } 00214 00215 /** Set the number of continuous samples until assert assumed. 00216 * 00217 * Defaults to 1 (1 * sample frequency). 00218 * 00219 * @param int The number of continuous samples until assert assumed. 00220 */ 00221 void setSamplesTillAssert(int i) { 00222 _samplesTillAssertReload = i; 00223 } 00224 00225 /** Set the number of continuous samples until held assumed. 00226 * 00227 * Defaults to 50 * sample frequency. 00228 * 00229 * @param int The number of continuous samples until held assumed. 00230 */ 00231 void setSamplesTillHeld(int i) { 00232 _samplesTillHeldReload = i; 00233 } 00234 00235 /** Set the pin mode. 00236 * 00237 * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode 00238 * @param PinMode m The mode to pass on to the DigitalIn 00239 */ 00240 void mode(PinMode m) { 00241 _in->mode(m); 00242 } 00243 00244 /** Attach a callback function 00245 * 00246 * @code 00247 * 00248 * DigitalOut led1(LED1); 00249 * PinDetect pin(p30); 00250 * 00251 * void myCallback(void) { 00252 * led1 = 1; 00253 * }; 00254 * 00255 * main() { 00256 * pin.attach_asserted(myCallback); 00257 * } 00258 * 00259 * @endcode 00260 * 00261 * Call this function when a pin is asserted. 00262 * @param function A C function pointer 00263 */ 00264 void attach_asserted(Callback<void()> cb) { 00265 _callbackAsserted = cb; 00266 } 00267 00268 /** Attach a callback function 00269 * 00270 * @code 00271 * 00272 * DigitalOut led1(LED1); 00273 * PinDetect pin(p30); 00274 * 00275 * void myCallback(void) { 00276 * led1 = 0; 00277 * }; 00278 * 00279 * main() { 00280 * pin.attach_deasserted(myCallback); 00281 * } 00282 * 00283 * @endcode 00284 * 00285 * Call this function when a pin is deasserted. 00286 * @param function A C function pointer 00287 */ 00288 void attach_deasserted(Callback<void()> cb) { 00289 _callbackDeasserted = cb; 00290 } 00291 00292 /** Attach a callback function 00293 * 00294 * @code 00295 * 00296 * DigitalOut led2(LED2); 00297 * PinDetect pin(p30); 00298 * 00299 * void myCallback(void) { 00300 * led2 = 1; 00301 * }; 00302 * 00303 * main() { 00304 * pin.attach_asserted_held(myCallback); 00305 * } 00306 * 00307 * @endcode 00308 * 00309 * Call this function when a pin is asserted and held. 00310 * @param function A C function pointer 00311 */ 00312 void attach_asserted_held(Callback<void()> cb) { 00313 _callbackAssertedHeld = cb; 00314 } 00315 00316 /** Attach a callback function 00317 * 00318 * @code 00319 * 00320 * DigitalOut led3(LED3); 00321 * PinDetect pin(p30); 00322 * 00323 * void myCallback(void) { 00324 * led3 = 1; 00325 * }; 00326 * 00327 * main() { 00328 * pin.attach_deasserted_held(myCallback); 00329 * } 00330 * 00331 * @endcode 00332 * 00333 * Call this function when a pin is deasserted and held. 00334 * @param function A C function pointer 00335 */ 00336 void attach_deasserted_held(Callback<void()> cb) { 00337 _callbackDeassertedHeld = cb; 00338 } 00339 00340 /** operator int() 00341 * 00342 * Read the value of the pin being sampled. 00343 */ 00344 operator int() { 00345 return _in->read(); 00346 } 00347 00348 protected: 00349 /** The Ticker periodic callback function 00350 */ 00351 void isr(void) { 00352 int currentState = _in->read(); 00353 00354 if (currentState != _prevState) { 00355 if (_samplesTillAssert == 0) { 00356 _prevState = currentState; 00357 _samplesTillHeld = _samplesTillHeldReload; 00358 if (currentState == _assertValue) { 00359 if (_callbackAsserted) 00360 _callbackAsserted(); 00361 } else if (_callbackDeasserted) 00362 _callbackDeasserted(); 00363 } 00364 else { 00365 _samplesTillAssert--; 00366 } 00367 } 00368 else { 00369 _samplesTillAssert = _samplesTillAssertReload; 00370 } 00371 00372 if (_samplesTillHeld) { 00373 if (_prevState == currentState) { 00374 _samplesTillHeld--; 00375 if (_samplesTillHeld == 0) { 00376 if (currentState == _assertValue) { 00377 if (_callbackAssertedHeld) 00378 _callbackAssertedHeld(); 00379 } else if (_callbackDeassertedHeld) 00380 _callbackDeassertedHeld(); 00381 } 00382 } 00383 else { 00384 _samplesTillHeld = 0; 00385 } 00386 } 00387 } 00388 00389 }; 00390 00391 }; // namespace AjK ends. 00392 00393 using namespace AjK; 00394 00395 #endif
Generated on Tue Jul 12 2022 16:27:20 by
1.7.2