Sense keypresses from a 4x4 keypad A derivative ot he Hotboard_keypad library

Dependents:   26_Hotboards_MultiKey 26_Hotboards_EventKeypad

Fork of Hotboards_keypad by Hotboards MX

Committer:
icserny
Date:
Mon May 30 09:30:12 2016 +0000
Revision:
3:c88c922efd74
Parent:
2:e870110f753b
Changes in v1.2:; 1. i < LIST_MAX in for cycle instead of i <= LIST_MAX; 2. Adaptation for KL25z; 3. Use internal pullup in the library;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Hotboards 0:4ca112f96484 1 /*
Hotboards 0:4ca112f96484 2 ||
Hotboards 0:4ca112f96484 3 || @file Hotboards_Keypad.h
Hotboards 0:4ca112f96484 4 || @version 3.2
Hotboards 0:4ca112f96484 5 || @ported by Diego (Hotboards)
Hotboards 0:4ca112f96484 6 || This Keypad fork library allow to work with keyboard that
Hotboards 0:4ca112f96484 7 || has physical pull-ups on columns (rather than rows)
Hotboards 0:4ca112f96484 8 ||
Hotboards 0:4ca112f96484 9 || Keypad library originaly develop by:
Hotboards 0:4ca112f96484 10 || @author Mark Stanley, Alexander Brevig
Hotboards 0:4ca112f96484 11 || @contact mstanley@technologist.com, alexanderbrevig@gmail.com
Hotboards 0:4ca112f96484 12 ||
Hotboards 0:4ca112f96484 13 || @description
Hotboards 0:4ca112f96484 14 || | This library provides a simple interface for using matrix
Hotboards 0:4ca112f96484 15 || | keypads. It supports multiple keypresses while maintaining
Hotboards 0:4ca112f96484 16 || | backwards compatibility with the old single key library.
Hotboards 0:4ca112f96484 17 || | It also supports user selectable pins and definable keymaps.
Hotboards 0:4ca112f96484 18 || #
Hotboards 0:4ca112f96484 19 ||
Hotboards 0:4ca112f96484 20 || @license
Hotboards 0:4ca112f96484 21 || | This library is free software; you can redistribute it and/or
Hotboards 0:4ca112f96484 22 || | modify it under the terms of the GNU Lesser General Public
Hotboards 0:4ca112f96484 23 || | License as published by the Free Software Foundation; version
Hotboards 0:4ca112f96484 24 || | 2.1 of the License.
Hotboards 0:4ca112f96484 25 || |
Hotboards 0:4ca112f96484 26 || | This library is distributed in the hope that it will be useful,
Hotboards 0:4ca112f96484 27 || | but WITHOUT ANY WARRANTY; without even the implied warranty of
Hotboards 0:4ca112f96484 28 || | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Hotboards 0:4ca112f96484 29 || | Lesser General Public License for more details.
Hotboards 0:4ca112f96484 30 || |
Hotboards 0:4ca112f96484 31 || | You should have received a copy of the GNU Lesser General Public
Hotboards 0:4ca112f96484 32 || | License along with this library; if not, write to the Free Software
Hotboards 0:4ca112f96484 33 || | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Hotboards 0:4ca112f96484 34 || #
Hotboards 0:4ca112f96484 35 ||
Hotboards 0:4ca112f96484 36 */
Hotboards 0:4ca112f96484 37
Hotboards 0:4ca112f96484 38 #ifndef KEYPAD_H
Hotboards 0:4ca112f96484 39 #define KEYPAD_H
Hotboards 0:4ca112f96484 40
Hotboards 0:4ca112f96484 41 #include "Key.h"
Hotboards 0:4ca112f96484 42
Hotboards 0:4ca112f96484 43
Hotboards 0:4ca112f96484 44 #define OPEN 0
Hotboards 0:4ca112f96484 45 #define CLOSED 1
Hotboards 0:4ca112f96484 46
Hotboards 0:4ca112f96484 47 typedef char KeypadEvent;
Hotboards 0:4ca112f96484 48 typedef unsigned int uint;
Hotboards 0:4ca112f96484 49 typedef unsigned long ulong;
Hotboards 0:4ca112f96484 50
Hotboards 0:4ca112f96484 51 // Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0
Hotboards 0:4ca112f96484 52 // by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :)
Hotboards 0:4ca112f96484 53 typedef struct {
Hotboards 0:4ca112f96484 54 uint8_t rows;
Hotboards 0:4ca112f96484 55 uint8_t columns;
Hotboards 0:4ca112f96484 56 } KeypadSize;
Hotboards 0:4ca112f96484 57
Hotboards 0:4ca112f96484 58 #define LIST_MAX 10 // Max number of keys on the active list.
Hotboards 0:4ca112f96484 59 #define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns)
Hotboards 0:4ca112f96484 60 #define makeKeymap(x) ((char*)x)
Hotboards 0:4ca112f96484 61
Hotboards 0:4ca112f96484 62
Hotboards 2:e870110f753b 63 /** Hotboards_keypad class.
Hotboards 2:e870110f753b 64 * Used to control general purpose leds
Hotboards 2:e870110f753b 65 *
Hotboards 2:e870110f753b 66 * Example:
Hotboards 2:e870110f753b 67 * @code
Hotboards 2:e870110f753b 68 * #include "mbed.h"
Hotboards 2:e870110f753b 69 * #include "Hotboards_keypad.h"
Hotboards 2:e870110f753b 70 *
Hotboards 2:e870110f753b 71 * char keys[ 4 ][ 4 ] =
Hotboards 2:e870110f753b 72 * {
Hotboards 2:e870110f753b 73 * {'1','2','3','A'},
Hotboards 2:e870110f753b 74 * {'4','5','6','B'},
Hotboards 2:e870110f753b 75 * {'7','8','9','C'},
Hotboards 2:e870110f753b 76 * {'*','0','#','D'}
Hotboards 2:e870110f753b 77 * };
Hotboards 2:e870110f753b 78 * DigitalInOut rowPins[ 4 ] = {PC_0, PC_1, PC_2, PC_3};
Hotboards 2:e870110f753b 79 * DigitalInOut colPins[ 4 ] = {PB_2, PB_1, PB_15, PB_14};
Hotboards 2:e870110f753b 80
Hotboards 2:e870110f753b 81 * Keypad kpd( makeKeymap( keys ), rowPins, colPins, 4, 4 );
Hotboards 2:e870110f753b 82
Hotboards 2:e870110f753b 83 * int main( void )
Hotboards 2:e870110f753b 84 * {
Hotboards 2:e870110f753b 85 * while(1){
Hotboards 2:e870110f753b 86 * char key = keypad.getKey( );
Hotboards 2:e870110f753b 87 * if( key ){
Hotboards 2:e870110f753b 88 * // do something with key
Hotboards 2:e870110f753b 89 * }
Hotboards 2:e870110f753b 90 * }
Hotboards 2:e870110f753b 91 * }
Hotboards 2:e870110f753b 92 * @endcode
Hotboards 2:e870110f753b 93 */
Hotboards 0:4ca112f96484 94 class Keypad : public Key {
Hotboards 2:e870110f753b 95 public:
Hotboards 0:4ca112f96484 96
Hotboards 2:e870110f753b 97 /** Allows custom keymap, pin configuration, and keypad sizes
Hotboards 2:e870110f753b 98 * @param userKeymap pointer to bidimentional array with key definitions
Hotboards 2:e870110f753b 99 * @param row pointer to array with pins conected to rows
Hotboards 2:e870110f753b 100 * @param col pointer to array with pins conected to columns
Hotboards 2:e870110f753b 101 * @param numRows number of rows in use
Hotboards 2:e870110f753b 102 * @param numCols number of columns in use
Hotboards 2:e870110f753b 103 *
Hotboards 2:e870110f753b 104 * Example:
Hotboards 2:e870110f753b 105 * @code
Hotboards 2:e870110f753b 106 * char keys[ 4 ][ 4 ] =
Hotboards 2:e870110f753b 107 * {
Hotboards 2:e870110f753b 108 * {'1','2','3','A'},
Hotboards 2:e870110f753b 109 * {'4','5','6','B'},
Hotboards 2:e870110f753b 110 * {'7','8','9','C'},
Hotboards 2:e870110f753b 111 * {'*','0','#','D'}
Hotboards 2:e870110f753b 112 * };
Hotboards 2:e870110f753b 113 * DigitalInOut rowPins[ 4 ] = {PC_0, PC_1, PC_2, PC_3};
Hotboards 2:e870110f753b 114 * DigitalInOut colPins[ 4 ] = {PB_2, PB_1, PB_15, PB_14};
Hotboards 2:e870110f753b 115 * Keypad kpd( makeKeymap( keys ), rowPins, colPins, 4, 4 );
Hotboards 2:e870110f753b 116 * @endcode
Hotboards 2:e870110f753b 117 */
Hotboards 0:4ca112f96484 118 Keypad(char *userKeymap, DigitalInOut *row, DigitalInOut *col, uint8_t numRows, uint8_t numCols);
Hotboards 0:4ca112f96484 119
Hotboards 2:e870110f753b 120 /** Returns a single key only. Retained for backwards compatibility.
Hotboards 2:e870110f753b 121 * @return key pressed (user defined key)
Hotboards 2:e870110f753b 122 *
Hotboards 2:e870110f753b 123 * Example:
Hotboards 2:e870110f753b 124 * @code
Hotboards 2:e870110f753b 125 * char key = keypad.getKey( );
Hotboards 2:e870110f753b 126 * if( key ){
Hotboards 2:e870110f753b 127 * // do something with key
Hotboards 2:e870110f753b 128 * }
Hotboards 2:e870110f753b 129 * @endcode
Hotboards 2:e870110f753b 130 */
Hotboards 2:e870110f753b 131 char getKey(void);
Hotboards 2:e870110f753b 132
Hotboards 2:e870110f753b 133 /** Populate the key list (check public key array).
Hotboards 2:e870110f753b 134 * @return true if user pressed any key(s)
Hotboards 2:e870110f753b 135 *
Hotboards 2:e870110f753b 136 * Example:
Hotboards 2:e870110f753b 137 * @code
Hotboards 2:e870110f753b 138 * if( kpd.getKeys( ) ){
Hotboards 2:e870110f753b 139 * // you need to poll the array kpd.key[]
Hotboards 2:e870110f753b 140 * for( int i=0 ; i<LIST_MAX ; i++ ){
Hotboards 2:e870110f753b 141 * if( kpd.key[ i ].stateChanged ){
Hotboards 2:e870110f753b 142 * chat = kpd.key[ i ].kchar;
Hotboards 2:e870110f753b 143 * }
Hotboards 2:e870110f753b 144 * }
Hotboards 2:e870110f753b 145 * @endcode
Hotboards 2:e870110f753b 146 */
Hotboards 2:e870110f753b 147 bool getKeys(void);
Hotboards 2:e870110f753b 148
Hotboards 2:e870110f753b 149 /** Get the state of the first key on the list of active keys
Hotboards 2:e870110f753b 150 * @return key[0].kstate
Hotboards 2:e870110f753b 151 *
Hotboards 2:e870110f753b 152 * Example:
Hotboards 2:e870110f753b 153 * @code
Hotboards 2:e870110f753b 154 * if(kpd.getState() == PRESSED ){
Hotboards 2:e870110f753b 155 * // do something
Hotboards 2:e870110f753b 156 * }
Hotboards 2:e870110f753b 157 * @endcode
Hotboards 2:e870110f753b 158 */
Hotboards 2:e870110f753b 159 KeyState getState(void);
Hotboards 2:e870110f753b 160
Hotboards 2:e870110f753b 161 /** Let the user define a keymap - assume the same row/column
Hotboards 2:e870110f753b 162 * count as defined in constructor
Hotboards 2:e870110f753b 163 * @param userKeymap pointer to user keymap
Hotboards 2:e870110f753b 164 *
Hotboards 2:e870110f753b 165 * Example:
Hotboards 2:e870110f753b 166 * @code
Hotboards 2:e870110f753b 167 * // lets assume user wnats to change the keymap
Hotboards 2:e870110f753b 168 * kpd.begin( makeKeymap( NewKeys )),
Hotboards 2:e870110f753b 169 * @endcode
Hotboards 2:e870110f753b 170 */
Hotboards 2:e870110f753b 171 void begin(char *userKeymap);
Hotboards 2:e870110f753b 172
Hotboards 2:e870110f753b 173 /** Return a true if the selected key is pressed. Is neccesary
Hotboards 2:e870110f753b 174 * to call getKeys function first
Hotboards 2:e870110f753b 175 * @return key pressed (user defined key)
Hotboards 2:e870110f753b 176 *
Hotboards 2:e870110f753b 177 * Example:
Hotboards 2:e870110f753b 178 * @code
Hotboards 2:e870110f753b 179 * if( kpd.getKeys( ) ){
Hotboards 2:e870110f753b 180 * if( kpd.isPressed( '2' ) ){
Hotboards 2:e870110f753b 181 * // key '2' have been press
Hotboards 2:e870110f753b 182 * }
Hotboards 2:e870110f753b 183 * }
Hotboards 2:e870110f753b 184 * @endcode
Hotboards 2:e870110f753b 185 */
Hotboards 2:e870110f753b 186 bool isPressed(char keyChar);
Hotboards 2:e870110f753b 187
Hotboards 2:e870110f753b 188 /** Set a new debounce time (1ms is the minimum value)
Hotboards 2:e870110f753b 189 * @param debounce time in milliseconds
Hotboards 2:e870110f753b 190 *
Hotboards 2:e870110f753b 191 * Example:
Hotboards 2:e870110f753b 192 * @code
Hotboards 2:e870110f753b 193 * // change default 10ms debounce time to 20ms
Hotboards 2:e870110f753b 194 * kpd.setDebounceTime( 20 );
Hotboards 2:e870110f753b 195 * @endcode
Hotboards 2:e870110f753b 196 */
Hotboards 2:e870110f753b 197 void setDebounceTime(uint);
Hotboards 2:e870110f753b 198
Hotboards 2:e870110f753b 199 /** Set a new time to considered a key is in hold state
Hotboards 2:e870110f753b 200 * @param hold hold time in milliseconds
Hotboards 2:e870110f753b 201 *
Hotboards 2:e870110f753b 202 * Example:
Hotboards 2:e870110f753b 203 * @code
Hotboards 2:e870110f753b 204 * // change default 500ms hold time to 250ms
Hotboards 2:e870110f753b 205 * kpd.setHoldTime( 250 );
Hotboards 2:e870110f753b 206 * @endcode
Hotboards 2:e870110f753b 207 */
Hotboards 2:e870110f753b 208 void setHoldTime(uint);
Hotboards 2:e870110f753b 209
Hotboards 2:e870110f753b 210 /** Set a callback function to be called everytime an key change its status
Hotboards 2:e870110f753b 211 * @param listener function to be called
Hotboards 2:e870110f753b 212 *
Hotboards 2:e870110f753b 213 * Example:
Hotboards 2:e870110f753b 214 * @code
Hotboards 2:e870110f753b 215 * kpd.addEventListener( keypadEvent );
Hotboards 2:e870110f753b 216 * @endcode
Hotboards 2:e870110f753b 217 */
Hotboards 2:e870110f753b 218 void addEventListener(void (*listener)(char));
Hotboards 2:e870110f753b 219
Hotboards 2:e870110f753b 220 /** Search by character for a key in the list of active keys.
Hotboards 2:e870110f753b 221 * @return Returns -1 if not found or the index into the list of active keys.
Hotboards 2:e870110f753b 222 *
Hotboards 2:e870110f753b 223 * Example:
Hotboards 2:e870110f753b 224 * @code
Hotboards 2:e870110f753b 225 * // kpd.getKeys function needs to be called first
Hotboards 2:e870110f753b 226 * int index = findInList( '7' );
Hotboards 2:e870110f753b 227 * if( kpd.key[ index ].stateChanged ){
Hotboards 2:e870110f753b 228 * // the key change, so do something =)
Hotboards 2:e870110f753b 229 * }
Hotboards 2:e870110f753b 230 * @endcode
Hotboards 2:e870110f753b 231 */
Hotboards 2:e870110f753b 232 int findInList(char keyChar);
Hotboards 2:e870110f753b 233
Hotboards 2:e870110f753b 234 /** Search by code for a key in the list of active keys.
Hotboards 2:e870110f753b 235 * @return Returns -1 if not found or the index into the list of active keys.
Hotboards 2:e870110f753b 236 *
Hotboards 2:e870110f753b 237 * Example:
Hotboards 2:e870110f753b 238 * @code
Hotboards 2:e870110f753b 239 * // kpd.getKeys function needs to be called first
Hotboards 2:e870110f753b 240 * int index = findInList( 10 );
Hotboards 2:e870110f753b 241 * if( kpd.key[ index ].stateChanged ){
Hotboards 2:e870110f753b 242 * // the key change, so do something =)
Hotboards 2:e870110f753b 243 * }
Hotboards 2:e870110f753b 244 * @endcode
Hotboards 2:e870110f753b 245 */
Hotboards 2:e870110f753b 246 int findInList(int keyCode);
Hotboards 2:e870110f753b 247
Hotboards 2:e870110f753b 248 /** lock everything while waiting for a keypress.
Hotboards 2:e870110f753b 249 * @return key pressed
Hotboards 2:e870110f753b 250 *
Hotboards 2:e870110f753b 251 * Example:
Hotboards 2:e870110f753b 252 * @code
Hotboards 2:e870110f753b 253 * char key = kpd.waitForKey();
Hotboards 2:e870110f753b 254 * @endcode
Hotboards 2:e870110f753b 255 */
Hotboards 2:e870110f753b 256 char waitForKey(void);
Hotboards 2:e870110f753b 257
Hotboards 2:e870110f753b 258 /** Return stateChanged element of the first key from the active list
Hotboards 2:e870110f753b 259 * @return key[0].stateChanged
Hotboards 2:e870110f753b 260 *
Hotboards 2:e870110f753b 261 * Example:
Hotboards 2:e870110f753b 262 * @code
Hotboards 2:e870110f753b 263 * if( kpd.keyStateChanged() ){
Hotboards 2:e870110f753b 264 * // do something
Hotboards 2:e870110f753b 265 * }
Hotboards 2:e870110f753b 266 * @endcode
Hotboards 2:e870110f753b 267 */
Hotboards 2:e870110f753b 268 bool keyStateChanged(void);
Hotboards 2:e870110f753b 269
Hotboards 2:e870110f753b 270 /** The number of keys on the key list, key[LIST_MAX]
Hotboards 2:e870110f753b 271 * @return number of keys
Hotboards 2:e870110f753b 272 *
Hotboards 2:e870110f753b 273 * Example:
Hotboards 2:e870110f753b 274 * @code
Hotboards 2:e870110f753b 275 * int keyNum = numKeys();
Hotboards 2:e870110f753b 276 * @endcode
Hotboards 2:e870110f753b 277 */
Hotboards 2:e870110f753b 278 uint8_t numKeys(void);
Hotboards 2:e870110f753b 279
Hotboards 0:4ca112f96484 280 uint bitMap[MAPSIZE]; // 10 row x 16 column array of bits. Except Due which has 32 columns.
Hotboards 0:4ca112f96484 281 Key key[LIST_MAX];
Hotboards 0:4ca112f96484 282 unsigned long holdTimer;
Hotboards 0:4ca112f96484 283
Hotboards 0:4ca112f96484 284 private:
Hotboards 0:4ca112f96484 285 unsigned long startTime;
Hotboards 0:4ca112f96484 286 char *keymap;
Hotboards 0:4ca112f96484 287 DigitalInOut *rowPins;
Hotboards 0:4ca112f96484 288 DigitalInOut *columnPins;
Hotboards 0:4ca112f96484 289 KeypadSize sizeKpd;
Hotboards 0:4ca112f96484 290 uint debounceTime;
Hotboards 0:4ca112f96484 291 uint holdTime;
Hotboards 0:4ca112f96484 292 bool single_key;
Hotboards 0:4ca112f96484 293 Timer debounce;
Hotboards 0:4ca112f96484 294
Hotboards 0:4ca112f96484 295 void scanKeys();
Hotboards 0:4ca112f96484 296 bool updateList();
Hotboards 0:4ca112f96484 297 void nextKeyState(uint8_t n, bool button);
Hotboards 0:4ca112f96484 298 void transitionTo(uint8_t n, KeyState nextState);
Hotboards 0:4ca112f96484 299 void (*keypadEventListener)(char);
Hotboards 0:4ca112f96484 300 };
Hotboards 0:4ca112f96484 301
Hotboards 0:4ca112f96484 302 #endif
Hotboards 0:4ca112f96484 303
Hotboards 0:4ca112f96484 304 /*
Hotboards 0:4ca112f96484 305 || @changelog
Hotboards 0:4ca112f96484 306 || | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
Hotboards 0:4ca112f96484 307 || | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
Hotboards 0:4ca112f96484 308 || | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
Hotboards 0:4ca112f96484 309 || | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
Hotboards 0:4ca112f96484 310 || | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
Hotboards 0:4ca112f96484 311 || | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
Hotboards 0:4ca112f96484 312 || | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
Hotboards 0:4ca112f96484 313 || | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
Hotboards 0:4ca112f96484 314 || | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
Hotboards 0:4ca112f96484 315 || | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
Hotboards 0:4ca112f96484 316 || | 1.8 2011-11-21 - Mark Stanley : Added test to determine which header file to compile,
Hotboards 0:4ca112f96484 317 || | WProgram.h or Arduino.h.
Hotboards 0:4ca112f96484 318 || | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
Hotboards 0:4ca112f96484 319 || | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes
Hotboards 0:4ca112f96484 320 || | the keypadEventListener will trigger, if set
Hotboards 0:4ca112f96484 321 || | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of
Hotboards 0:4ca112f96484 322 || | microseconds before a HOLD state triggers
Hotboards 0:4ca112f96484 323 || | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
Hotboards 0:4ca112f96484 324 || | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
Hotboards 0:4ca112f96484 325 || | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
Hotboards 0:4ca112f96484 326 || | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
Hotboards 0:4ca112f96484 327 || | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
Hotboards 0:4ca112f96484 328 || | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
Hotboards 0:4ca112f96484 329 || | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
Hotboards 0:4ca112f96484 330 || | 1.0 2007-XX-XX - Mark Stanley : Initial Release
Hotboards 0:4ca112f96484 331 || #
Hotboards 0:4ca112f96484 332 */