Istvan Cserny / Hotboards_keypad

Dependents:   26_Hotboards_MultiKey 26_Hotboards_EventKeypad

Fork of Hotboards_keypad by Hotboards MX

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Hotboards_keypad.h Source File

Hotboards_keypad.h

00001 /*
00002 ||
00003 || @file Hotboards_Keypad.h
00004 || @version 3.2
00005 || @ported by Diego (Hotboards)
00006 || This Keypad fork library allow to work with keyboard that
00007 || has physical pull-ups on columns (rather than rows)
00008 ||
00009 || Keypad library originaly develop by:
00010 || @author Mark Stanley, Alexander Brevig
00011 || @contact mstanley@technologist.com, alexanderbrevig@gmail.com
00012 ||
00013 || @description
00014 || | This library provides a simple interface for using matrix
00015 || | keypads. It supports multiple keypresses while maintaining
00016 || | backwards compatibility with the old single key library.
00017 || | It also supports user selectable pins and definable keymaps.
00018 || #
00019 ||
00020 || @license
00021 || | This library is free software; you can redistribute it and/or
00022 || | modify it under the terms of the GNU Lesser General Public
00023 || | License as published by the Free Software Foundation; version
00024 || | 2.1 of the License.
00025 || |
00026 || | This library is distributed in the hope that it will be useful,
00027 || | but WITHOUT ANY WARRANTY; without even the implied warranty of
00028 || | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00029 || | Lesser General Public License for more details.
00030 || |
00031 || | You should have received a copy of the GNU Lesser General Public
00032 || | License along with this library; if not, write to the Free Software
00033 || | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00034 || #
00035 ||
00036 */
00037 
00038 #ifndef KEYPAD_H
00039 #define KEYPAD_H
00040 
00041 #include "Key.h"
00042 
00043 
00044 #define OPEN 0
00045 #define CLOSED 1
00046 
00047 typedef char KeypadEvent;
00048 typedef unsigned int uint;
00049 typedef unsigned long ulong;
00050 
00051 // Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0
00052 // by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :)
00053 typedef struct {
00054     uint8_t rows;
00055     uint8_t columns;
00056 } KeypadSize;
00057 
00058 #define LIST_MAX 10     // Max number of keys on the active list.
00059 #define MAPSIZE 10      // MAPSIZE is the number of rows (times 16 columns)
00060 #define makeKeymap(x) ((char*)x)
00061 
00062 
00063 /** Hotboards_keypad class.
00064  *  Used to control general purpose leds
00065  *
00066  * Example:
00067  * @code
00068  * #include "mbed.h"
00069  * #include "Hotboards_keypad.h"
00070  *
00071  * char keys[ 4 ][ 4 ] =
00072  * {
00073  *    {'1','2','3','A'},
00074  *    {'4','5','6','B'},
00075  *    {'7','8','9','C'},
00076  *    {'*','0','#','D'}
00077  * };
00078  * DigitalInOut rowPins[ 4 ] = {PC_0, PC_1, PC_2, PC_3}; 
00079  * DigitalInOut colPins[ 4 ] = {PB_2, PB_1, PB_15, PB_14};
00080 
00081  * Keypad kpd( makeKeymap( keys ), rowPins, colPins, 4, 4 );
00082 
00083  * int main( void ) 
00084  * {
00085  *    while(1){
00086  *       char key = keypad.getKey( );
00087  *       if( key ){
00088  *           // do something with key
00089  *       }
00090  *    }
00091  * }
00092  * @endcode
00093  */
00094 class Keypad : public Key {
00095   public:
00096 
00097     /** Allows custom keymap, pin configuration, and keypad sizes
00098       * @param userKeymap pointer to bidimentional array with key definitions
00099       * @param row pointer to array with pins conected to rows
00100       * @param col pointer to array with pins conected to columns
00101       * @param numRows number of rows in use
00102       * @param numCols number of columns in use
00103       * 
00104       * Example:
00105       * @code
00106       *   char keys[ 4 ][ 4 ] =
00107       *   {
00108       *     {'1','2','3','A'},
00109       *     {'4','5','6','B'},
00110       *     {'7','8','9','C'},
00111       *     {'*','0','#','D'}
00112       *   };
00113       *   DigitalInOut rowPins[ 4 ] = {PC_0, PC_1, PC_2, PC_3}; 
00114       *   DigitalInOut colPins[ 4 ] = {PB_2, PB_1, PB_15, PB_14};
00115       *   Keypad kpd( makeKeymap( keys ), rowPins, colPins, 4, 4 );
00116       * @endcode
00117       */
00118     Keypad(char *userKeymap, DigitalInOut *row, DigitalInOut *col, uint8_t numRows, uint8_t numCols);
00119 
00120     /** Returns a single key only. Retained for backwards compatibility.
00121       * @return key pressed (user defined key)
00122       * 
00123       * Example:
00124       * @code
00125       *   char key = keypad.getKey( );
00126       *   if( key ){
00127       *     // do something with key
00128       *   }
00129       * @endcode
00130       */
00131     char getKey(void);
00132     
00133     /** Populate the key list (check public key array).
00134       * @return true if user pressed any key(s)
00135       * 
00136       * Example:
00137       * @code
00138       * if( kpd.getKeys( ) ){
00139       *   // you need to poll the array kpd.key[]
00140       *   for( int i=0 ; i<LIST_MAX ; i++ ){
00141       *     if( kpd.key[ i ].stateChanged ){ 
00142       *       chat = kpd.key[ i ].kchar;
00143       *     }
00144       * }
00145       * @endcode
00146       */
00147     bool getKeys(void);
00148     
00149     /** Get the state of the first key on the list of active keys
00150       * @return key[0].kstate
00151       * 
00152       * Example:
00153       * @code
00154       *   if(kpd.getState() == PRESSED ){
00155       *     // do something
00156       *   }
00157       * @endcode
00158       */
00159     KeyState getState(void);
00160     
00161     /** Let the user define a keymap - assume the same row/column 
00162       * count as defined in constructor
00163       * @param userKeymap pointer to user keymap
00164       * 
00165       * Example:
00166       * @code
00167       *   // lets assume user wnats to change the keymap
00168       *   kpd.begin( makeKeymap( NewKeys )),
00169       * @endcode
00170       */
00171     void begin(char *userKeymap);
00172     
00173     /** Return a true if the selected key is pressed. Is neccesary 
00174       * to call getKeys function first
00175       * @return key pressed (user defined key)
00176       * 
00177       * Example:
00178       * @code
00179       *  if( kpd.getKeys( ) ){
00180       *    if( kpd.isPressed( '2' ) ){
00181       *      // key '2' have been press
00182       *    }
00183       *  } 
00184       * @endcode
00185       */
00186     bool isPressed(char keyChar);
00187     
00188     /** Set a new debounce time (1ms is the minimum value)
00189       * @param debounce time in milliseconds
00190       * 
00191       * Example:
00192       * @code
00193       *  // change default 10ms debounce time to 20ms
00194       *  kpd.setDebounceTime( 20 );
00195       * @endcode
00196       */
00197     void setDebounceTime(uint);
00198     
00199     /** Set a new time to considered a key is in hold state
00200       * @param hold hold time in milliseconds
00201       * 
00202       * Example:
00203       * @code
00204       *  // change default 500ms hold time to 250ms
00205       *  kpd.setHoldTime( 250 );
00206       * @endcode
00207       */
00208     void setHoldTime(uint);
00209     
00210     /** Set a callback function to be called everytime an key change its status 
00211       * @param listener function to be called
00212       * 
00213       * Example:
00214       * @code
00215       *   kpd.addEventListener( keypadEvent );
00216       * @endcode
00217       */
00218     void addEventListener(void (*listener)(char));
00219     
00220     /** Search by character for a key in the list of active keys.
00221       * @return Returns -1 if not found or the index into the list of active keys.
00222       * 
00223       * Example:
00224       * @code
00225       *   // kpd.getKeys function needs to be called first
00226       *   int index = findInList( '7' );
00227       *   if( kpd.key[ index ].stateChanged ){
00228       *     // the key change, so do something =)
00229       *   }
00230       * @endcode
00231       */
00232     int findInList(char keyChar);
00233     
00234     /** Search by code for a key in the list of active keys.
00235       * @return Returns -1 if not found or the index into the list of active keys.
00236       * 
00237       * Example:
00238       * @code
00239       *   // kpd.getKeys function needs to be called first
00240       *   int index = findInList( 10 );
00241       *   if( kpd.key[ index ].stateChanged ){
00242       *     // the key change, so do something =)
00243       *   }
00244       * @endcode
00245       */
00246     int findInList(int keyCode);
00247     
00248     /** lock everything while waiting for a keypress.
00249       * @return key pressed 
00250       * 
00251       * Example:
00252       * @code
00253       *   char key = kpd.waitForKey();
00254       * @endcode
00255       */
00256     char waitForKey(void);
00257     
00258     /** Return stateChanged element of the first key from the active list
00259       * @return key[0].stateChanged
00260       * 
00261       * Example:
00262       * @code
00263       *   if( kpd.keyStateChanged() ){
00264       *     // do something
00265       *   }
00266       * @endcode
00267       */
00268     bool keyStateChanged(void);
00269     
00270     /** The number of keys on the key list, key[LIST_MAX]
00271       * @return number of keys
00272       * 
00273       * Example:
00274       * @code
00275       *   int keyNum = numKeys(); 
00276       * @endcode
00277       */
00278     uint8_t numKeys(void);
00279     
00280     uint bitMap[MAPSIZE];   // 10 row x 16 column array of bits. Except Due which has 32 columns.
00281     Key key[LIST_MAX];
00282     unsigned long holdTimer;
00283 
00284 private:
00285     unsigned long startTime;
00286     char *keymap;
00287     DigitalInOut *rowPins;
00288     DigitalInOut *columnPins;
00289     KeypadSize sizeKpd;
00290     uint debounceTime;
00291     uint holdTime;
00292     bool single_key;
00293     Timer debounce;
00294 
00295     void scanKeys();
00296     bool updateList();
00297     void nextKeyState(uint8_t n, bool button);
00298     void transitionTo(uint8_t n, KeyState nextState);
00299     void (*keypadEventListener)(char);
00300 };
00301 
00302 #endif
00303 
00304 /*
00305 || @changelog
00306 || | 3.1 2013-01-15 - Mark Stanley     : Fixed missing RELEASED & IDLE status when using a single key.
00307 || | 3.0 2012-07-12 - Mark Stanley     : Made library multi-keypress by default. (Backwards compatible)
00308 || | 3.0 2012-07-12 - Mark Stanley     : Modified pin functions to support Keypad_I2C
00309 || | 3.0 2012-07-12 - Stanley & Young  : Removed static variables. Fix for multiple keypad objects.
00310 || | 3.0 2012-07-12 - Mark Stanley     : Fixed bug that caused shorted pins when pressing multiple keys.
00311 || | 2.0 2011-12-29 - Mark Stanley     : Added waitForKey().
00312 || | 2.0 2011-12-23 - Mark Stanley     : Added the public function keyStateChanged().
00313 || | 2.0 2011-12-23 - Mark Stanley     : Added the private function scanKeys().
00314 || | 2.0 2011-12-23 - Mark Stanley     : Moved the Finite State Machine into the function getKeyState().
00315 || | 2.0 2011-12-23 - Mark Stanley     : Removed the member variable lastUdate. Not needed after rewrite.
00316 || | 1.8 2011-11-21 - Mark Stanley     : Added test to determine which header file to compile,
00317 || |                                          WProgram.h or Arduino.h.
00318 || | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
00319 || | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes
00320 || |                                          the keypadEventListener will trigger, if set
00321 || | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of
00322 || |                                          microseconds before a HOLD state triggers
00323 || | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
00324 || | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
00325 || | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
00326 || | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
00327 || | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
00328 || | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
00329 || | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
00330 || | 1.0 2007-XX-XX - Mark Stanley : Initial Release
00331 || #
00332 */