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: Programa_juego_info
Fork of PinDetect by
PinDetect.h
00001 /* 00002 Copyright (c) 2010 Andy Kirkham 00003 00004 00005 Copyright (c) 2010 Andy Kirkham 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a copy 00008 of this software and associated documentation files (the "Software"), to deal 00009 in the Software without restriction, including without limitation the rights 00010 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00011 copies of the Software, and to permit persons to whom the Software is 00012 furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00020 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00022 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00023 THE SOFTWARE. 00024 */ 00025 00026 #ifndef AJK_PIN_DETECT_H 00027 #define AJK_PIN_DETECT_H 00028 00029 #ifndef MBED_H 00030 #include "mbed.h" 00031 #endif 00032 00033 #ifndef PINDETECT_PIN_ASSTERED 00034 #define PINDETECT_PIN_ASSTERED 1 00035 #endif 00036 00037 #ifndef PINDETECT_SAMPLE_PERIOD 00038 #define PINDETECT_SAMPLE_PERIOD 20000 00039 #endif 00040 00041 #ifndef PINDETECT_ASSERT_COUNT 00042 #define PINDETECT_ASSERT_COUNT 1 00043 #endif 00044 00045 #ifndef PINDETECT_HOLD_COUNT 00046 #define PINDETECT_HOLD_COUNT 50 00047 #endif 00048 00049 namespace AjK { 00050 00051 /** PinDetect adds mechanical switch debouncing to DigitialIn and interrupt callbacks. 00052 * 00053 * This is done by sampling the specified pin at regular intervals and detecting any 00054 * change of state ( 0 -> 1 or 1 -> 0 ). When a state change is detected the attached 00055 * callback handler is called. Additionally, if the pin stays in the same state after 00056 * a state change for a defined period of time, an extra callback is made allowing a 00057 * program to detect when a "key is pressed and held down" rather than a momentary 00058 * key/switch press. 00059 * 00060 * All parameters are customisable which include:- 00061 * <ul> 00062 * <li> The sampling frequency. </li> 00063 * <li> The number of continuous samples until a state change is detected. </li> 00064 * <li> The number of continuous samples until a key is assumed held after a state change. </li> 00065 * <li> The logic level which is assumed to be asserted (0volts or +volts). </li> 00066 * </ul> 00067 * 00068 * Only callbacks that have been attached will be called by the library. 00069 * 00070 * Example: 00071 * @code 00072 * #include "mbed.h" 00073 * #include "PinDetect.h" 00074 * 00075 * PinDetect pin( p30 ); 00076 * DigitialOut led1( LED1 ); 00077 * DigitialOut led2( LED2 ); 00078 * DigitialOut led3( LED3 ); 00079 * DigitialOut led4( LED4 ); 00080 * 00081 * void keyPressed( void ) { 00082 * led2 = 1; 00083 * led3 = 0; 00084 * led4 = 0; 00085 * } 00086 * 00087 * void keyReleased( void ) { 00088 * led2 = 0; 00089 * led3 = 0; 00090 * led4 = 0; 00091 * } 00092 * 00093 * void keyPressedHeld( void ) { 00094 * led3 = 1; 00095 * } 00096 * 00097 * void keyReleasedHeld( void ) { 00098 * led4 = 1; 00099 * } 00100 * 00101 * int main() { 00102 * 00103 * pin.mode( PullDown ); 00104 * pin.attach_asserted( &keyPressed ); 00105 * pin.attach_deasserted( &keyReleased ); 00106 * pin.attach_asserted_held( &keyPressedHeld ); 00107 * pin.attach_deasserted_held( &keyReleasedHeld ); 00108 * 00109 * // Sampling does not begin until you set a frequency. 00110 * // The default is 20ms. If you want a different frequency 00111 * // then pass the period in microseconds for example, for 10ms :- 00112 * // pin.setSampleFrequency( 10000 ); 00113 * // 00114 * pin.setSampleFrequency(); // Defaults to 20ms. 00115 * 00116 * while( 1 ) { 00117 * led1 = !led1; 00118 * wait( 0.2 ); 00119 * } 00120 * } 00121 * @endcode 00122 * 00123 * This example will flash led1 in a similar to a standard starting program. 00124 * 00125 * Applying a "1" (switch on) to pin 30 will switch on led2, removing the "1" to "0" 00126 * (switch off) led2 goes out. Holding the "switch" at one for one second will switch 00127 * on led3. An unasserted P30 (switched off) will, after one second illuminate led4 00128 * when the deasserted calledback is called. 00129 * 00130 * The above is a very basic introduction. For more details:- 00131 * @see example.h 00132 */ 00133 class PinDetect { 00134 00135 protected: 00136 DigitalIn *_in; 00137 Ticker *_ticker; 00138 int _prevState; 00139 int _currentStateCounter; 00140 int _sampleTime; 00141 int _assertValue; 00142 int _samplesTillAssertReload; 00143 int _samplesTillAssert; 00144 int _samplesTillHeldReload; 00145 int _samplesTillHeld; 00146 FunctionPointer _callbackAsserted; 00147 FunctionPointer _callbackDeasserted; 00148 FunctionPointer _callbackAssertedHeld; 00149 FunctionPointer _callbackDeassertedHeld; 00150 00151 /** initialise class 00152 * 00153 * @param PinName p is a valid pin that supports DigitalIn 00154 * @param PinMode m The mode the DigitalIn should use. 00155 */ 00156 void init(PinName p, PinMode m) { 00157 _sampleTime = PINDETECT_SAMPLE_PERIOD; 00158 _samplesTillAssert = PINDETECT_ASSERT_COUNT; 00159 _samplesTillHeld = 0; 00160 _samplesTillAssertReload = PINDETECT_ASSERT_COUNT; 00161 _samplesTillHeldReload = PINDETECT_HOLD_COUNT; 00162 _assertValue = PINDETECT_PIN_ASSTERED; 00163 00164 _in = new DigitalIn( p ); 00165 _in->mode( m ); 00166 _prevState = _in->read(); 00167 _ticker = new Ticker; 00168 } 00169 00170 public: 00171 00172 friend class Ticker; 00173 00174 PinDetect() { error("You must supply a PinName"); } 00175 00176 /** PinDetect constructor 00177 * 00178 * By default the PinMode is set to PullDown. 00179 * 00180 * @see http://mbed.org/handbook/DigitalIn 00181 * @param p PinName is a valid pin that supports DigitalIn 00182 */ 00183 PinDetect(PinName p, PinMode m) { 00184 init( p, PullUp ); 00185 } 00186 00187 /** PinDetect constructor 00188 * 00189 * @see http://mbed.org/handbook/DigitalIn 00190 * @param PinName p is a valid pin that supports DigitalIn 00191 * @param PinMode m The mode the DigitalIn should use. 00192 */ 00193 PinDetect(PinName p) { 00194 init( p, PullUp ); 00195 } 00196 00197 /** PinDetect destructor 00198 */ 00199 ~PinDetect() { 00200 if ( _ticker ) delete( _ticker ); 00201 if ( _in ) delete( _in ); 00202 } 00203 00204 /** Set the sampling time in microseconds. 00205 * 00206 * @param int The time between pin samples in microseconds. 00207 */ 00208 void setSampleFrequency(int i = PINDETECT_SAMPLE_PERIOD) { 00209 _sampleTime = i; 00210 _prevState = _in->read(); 00211 _ticker->attach_us( this, &PinDetect::isr, _sampleTime ); 00212 } 00213 00214 /** Set the value used as assert. 00215 * 00216 * Defaults to 1 (ie if pin == 1 then pin asserted). 00217 * 00218 * @param int New assert value (1 or 0) 00219 */ 00220 void setAssertValue (int i = PINDETECT_PIN_ASSTERED) { _assertValue = i & 1; } 00221 00222 /** Set the number of continuous samples until assert assumed. 00223 * 00224 * Defaults to 1 (1 * sample frequency). 00225 * 00226 * @param int The number of continuous samples until assert assumed. 00227 */ 00228 void setSamplesTillAssert(int i) { _samplesTillAssertReload = i; } 00229 00230 /** Set the number of continuous samples until held assumed. 00231 * 00232 * Defaults to 50 * sample frequency. 00233 * 00234 * @param int The number of continuous samples until held assumed. 00235 */ 00236 void setSamplesTillHeld(int i) { _samplesTillHeldReload = i; } 00237 00238 /** Set the pin mode. 00239 * 00240 * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode 00241 * @param PinMode m The mode to pass on to the DigitalIn 00242 */ 00243 void mode(PinMode m) { _in->mode( m ); } 00244 00245 /** Attach a callback function 00246 * 00247 * @code 00248 * 00249 * DigitalOut led1( LED1 ); 00250 * PinDetect pin( p30 ); 00251 * 00252 * void myCallback( void ) { 00253 * led1 = 1; 00254 * }; 00255 * 00256 * main() { 00257 * pin.attach_asserted( &myCallback ); 00258 * } 00259 * 00260 * @endcode 00261 * 00262 * Call this function when a pin is asserted. 00263 * @param function A C function pointer 00264 */ 00265 void attach_asserted(void (*function)(void)) { 00266 _callbackAsserted.attach( function ); 00267 } 00268 00269 /** Attach a callback object/method 00270 * 00271 * @code 00272 * 00273 * class Bar { 00274 * public: 00275 * void myCallback( void ) { led1 = 1; } 00276 * }; 00277 * 00278 * DigitalOut led1( LED1 ); 00279 * PinDetect pin( p30 ); 00280 * Bar bar; 00281 * 00282 * main() { 00283 * pin.attach_asserted( &bar, &Bar::myCallback ); 00284 * } 00285 * 00286 * @endcode 00287 * 00288 * Call this function when a pin is asserted. 00289 * @param object An object that conatins the callback method. 00290 * @param method The method within the object to call. 00291 */ 00292 template<typename T> 00293 void attach_asserted(T *object, void (T::*member)(void)) { 00294 _callbackAsserted.attach( object, member ); 00295 } 00296 00297 /** Attach a callback function 00298 * 00299 * @code 00300 * 00301 * DigitalOut led1( LED1 ); 00302 * PinDetect pin( p30 ); 00303 * 00304 * void myCallback( void ) { 00305 * led1 = 0; 00306 * }; 00307 * 00308 * main() { 00309 * pin.attach_deasserted( &myCallback ); 00310 * } 00311 * 00312 * @endcode 00313 * 00314 * Call this function when a pin is deasserted. 00315 * @param function A C function pointer 00316 */ 00317 void attach_deasserted(void (*function)(void)) { 00318 _callbackDeasserted.attach( function ); 00319 } 00320 00321 /** Attach a callback object/method 00322 * 00323 * @code 00324 * 00325 * class Bar { 00326 * public: 00327 * void myCallback( void ) { led1 = 0; } 00328 * }; 00329 * 00330 * DigitalOut led1( LED1 ); 00331 * PinDetect pin( p30 ); 00332 * Bar bar; 00333 * 00334 * main() { 00335 * pin.attach_deasserted( &bar, &Bar::myCallback ); 00336 * } 00337 * 00338 * @endcode 00339 * 00340 * Call this function when a pin is deasserted. 00341 * @param object An object that conatins the callback method. 00342 * @param method The method within the object to call. 00343 */ 00344 template<typename T> 00345 void attach_deasserted(T *object, void (T::*member)(void)) { 00346 _callbackDeasserted.attach( object, member ); 00347 } 00348 00349 /** Attach a callback function 00350 * 00351 * @code 00352 * 00353 * DigitalOut led2( LED2 ); 00354 * PinDetect pin( p30 ); 00355 * 00356 * void myCallback( void ) { 00357 * led2 = 1; 00358 * }; 00359 * 00360 * main() { 00361 * pin.attach_asserted_held( &myCallback ); 00362 * } 00363 * 00364 * @endcode 00365 * 00366 * Call this function when a pin is asserted and held. 00367 * @param function A C function pointer 00368 */ 00369 void attach_asserted_held(void (*function)(void)) { 00370 _callbackAssertedHeld.attach( function ); 00371 } 00372 00373 /** Attach a callback object/method 00374 * 00375 * @code 00376 * 00377 * class Bar { 00378 * public: 00379 * void myCallback( void ) { led2 = 0; } 00380 * }; 00381 * 00382 * DigitalOut led2( LED2 ); 00383 * PinDetect pin( p30 ); 00384 * Bar bar; 00385 * 00386 * main() { 00387 * pin.attach_asserted_held( &bar, &Bar::myCallback ); 00388 * } 00389 * 00390 * @endcode 00391 * 00392 * Call this function when a pin is asserted and held. 00393 * @param object An object that conatins the callback method. 00394 * @param method The method within the object to call. 00395 */ 00396 template<typename T> 00397 void attach_asserted_held(T *object, void (T::*member)(void)) { 00398 _callbackAssertedHeld.attach( object, member ); 00399 } 00400 00401 /** Attach a callback function 00402 * 00403 * @code 00404 * 00405 * DigitalOut led3( LED3 ); 00406 * PinDetect pin( p30 ); 00407 * 00408 * void myCallback( void ) { 00409 * led3 = 1; 00410 * }; 00411 * 00412 * main() { 00413 * pin.attach_deasserted_held( &myCallback ); 00414 * } 00415 * 00416 * @endcode 00417 * 00418 * Call this function when a pin is deasserted and held. 00419 * @param function A C function pointer 00420 */ 00421 void attach_deasserted_held(void (*function)(void)) { 00422 _callbackDeassertedHeld.attach( function ); 00423 } 00424 00425 /** Attach a callback object/method 00426 * 00427 * @code 00428 * 00429 * class Bar { 00430 * public: 00431 * void myCallback( void ) { led3 = 0; } 00432 * }; 00433 * 00434 * DigitalOut led3( LED3 ); 00435 * PinDetect pin( p30 ); 00436 * Bar bar; 00437 * 00438 * main() { 00439 * pin.attach_deasserted_held( &bar, &Bar::myCallback ); 00440 * } 00441 * 00442 * @endcode 00443 * 00444 * Call this function when a pin is deasserted and held. 00445 * @param object An object that conatins the callback method. 00446 * @param method The method within the object to call. 00447 */ 00448 template<typename T> 00449 void attach_deasserted_held(T *object, void (T::*member)(void)) { 00450 _callbackDeassertedHeld.attach( object, member ); 00451 } 00452 00453 /** operator int() 00454 * 00455 * Read the value of the pin being sampled. 00456 */ 00457 operator int() { return _in->read(); } 00458 00459 protected: 00460 /** The Ticker periodic callback function 00461 */ 00462 void isr(void) { 00463 int currentState = _in->read(); 00464 00465 if ( currentState != _prevState ) { 00466 if ( _samplesTillAssert == 0 ) { 00467 _prevState = currentState; 00468 _samplesTillHeld = _samplesTillHeldReload; 00469 if ( currentState == _assertValue ) 00470 _callbackAsserted.call(); 00471 else 00472 _callbackDeasserted.call(); 00473 } 00474 else { 00475 _samplesTillAssert--; 00476 } 00477 } 00478 else { 00479 _samplesTillAssert = _samplesTillAssertReload; 00480 } 00481 00482 if ( _samplesTillHeld ) { 00483 if ( _prevState == currentState ) { 00484 _samplesTillHeld--; 00485 if ( _samplesTillHeld == 0 ) { 00486 if ( currentState == _assertValue ) 00487 _callbackAssertedHeld.call(); 00488 else 00489 _callbackDeassertedHeld.call(); 00490 } 00491 } 00492 else { 00493 _samplesTillHeld = 0; 00494 } 00495 } 00496 } 00497 00498 }; 00499 00500 }; // namespace AjK ends. 00501 00502 using namespace AjK; 00503 00504 #endif
Generated on Thu Jul 14 2022 14:06:13 by
1.7.2
