Created
March 10, 2025 06:43
-
-
Save nickgammon/d9c0919ae961ef509cc38ffb3ef93c2d to your computer and use it in GitHub Desktop.
Keypad2 library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
|| | |
|| @file Keypad.h | |
|| @version 1.8 | |
|| @author Mark Stanley, Alexander Brevig | |
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com | |
|| | |
|| @description | |
|| | This library provides a simple interface for using matrix | |
|| | keypads. It supports the use of multiple keypads with the | |
|| | same or different sets of keys. It also supports user | |
|| | selectable pins and definable keymaps. | |
|| # | |
|| | |
|| @license | |
|| | This library is free software; you can redistribute it and/or | |
|| | modify it under the terms of the GNU Lesser General Public | |
|| | License as published by the Free Software Foundation; version | |
|| | 2.1 of the License. | |
|| | | |
|| | This library is distributed in the hope that it will be useful, | |
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
|| | Lesser General Public License for more details. | |
|| | | |
|| | You should have received a copy of the GNU Lesser General Public | |
|| | License along with this library; if not, write to the Free Software | |
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
|| # | |
|| | |
*/ | |
#include "Keypad2.h" | |
// <<constructor>> Allows custom keymap. pin configuration and keypad size | |
Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte rows, byte cols) | |
{ | |
rowPins = row; | |
columnPins = col; | |
size.rows = rows; | |
size.columns = cols; | |
begin(userKeymap); | |
lastUpdate = 0; | |
debounceTime = 50; | |
holdTime = 1000; | |
keypadEventListener = 0; | |
currentKey = NO_KEY; | |
state = IDLE; | |
initializePins(); | |
} | |
// Let the user define a keymap - assume the same row- / columncount as defined in constructor | |
void Keypad::begin( char *userKeymap){ | |
keymap = userKeymap; | |
} | |
// Returns the keykode of the pressed key, or NO_KEY if no key is pressed | |
char Keypad::getKey(){ | |
char key = NO_KEY; // Assume that no key is pressed, this is the default return for getKey() | |
for (byte c=0; c<size.columns; c++){ | |
digitalWrite(columnPins[c],LOW); // Activate the current column. | |
for (byte r=0; r<size.rows; r++){ // Scan all the rows for a key press. | |
// The user pressed a button for more then debounceTime microseconds. | |
if (currentKey == keymap[c+(r*size.columns)]){ | |
// Button hold | |
if (((millis()-lastUpdate) >= holdTime) && digitalRead(rowPins[r]) == LOW){ | |
transitionTo(HOLD); | |
} | |
// Button release | |
if (((millis()-lastUpdate) >= debounceTime) && digitalRead(rowPins[r]) == HIGH){ | |
transitionTo(RELEASED); | |
currentKey = NO_KEY; | |
} | |
} | |
// Button pressed event. The user pressed a button. | |
else if (((millis()-lastUpdate) >= debounceTime) && digitalRead(rowPins[r]) == LOW){ | |
digitalWrite(columnPins[c],HIGH); // De-activate the current column. | |
key = keymap[c+(r*size.columns)]; | |
lastUpdate = millis(); | |
goto EVALUATE_KEY; // Save resources and do not attempt to parse to keys at a time | |
} | |
} | |
digitalWrite(columnPins[c],HIGH); // De-activate the current column. | |
} | |
EVALUATE_KEY: | |
if (key != NO_KEY && key != currentKey){ | |
currentKey = key; | |
transitionTo(PRESSED); | |
return currentKey; | |
} | |
else{ | |
return NO_KEY; | |
} | |
} | |
KeypadState Keypad::getState(){ | |
return state; | |
} | |
void Keypad::setDebounceTime(unsigned int debounce){ | |
debounceTime = debounce; | |
} | |
void Keypad::setHoldTime(unsigned int hold){ | |
holdTime = hold; | |
} | |
void Keypad::addEventListener(void (*listener)(char)){ | |
keypadEventListener = listener; | |
} | |
//private | |
void Keypad::transitionTo(KeypadState newState){ | |
if (state!=newState){ | |
state = newState; | |
if (keypadEventListener!=NULL){ | |
keypadEventListener(currentKey); | |
} | |
} | |
} | |
void Keypad::initializePins(){ | |
for (byte r=0; r<size.rows; r++){ | |
for (byte c=0; c<size.columns; c++){ | |
pinMode(columnPins[c],OUTPUT); | |
digitalWrite(columnPins[c],HIGH); | |
} | |
//configure row pin modes and states | |
pinMode(rowPins[r],INPUT); | |
digitalWrite(rowPins[r],HIGH); | |
} | |
} | |
/* | |
|| @changelog | |
|| | 2009-07-08 - Alexander Brevig : Library does not use 2d arrays | |
|| | 2009-06-15 - Alexander Brevig : Added transitionTo | |
|| | 2009-06-15 - Alexander Brevig : Added getState() | |
|| | 2009-06-13 - Mark Stanley : Fixed bug in getKey() that returns the wrong key if debounceTime is too short. | |
|| | 2009-06-13 - Mark Stanley : Minor bug fix: Added 'currentKey = NO_KEY' to constructors. | |
|| | 2009-05-19 - Alexander Brevig : Added setHoldTime() | |
|| | 2009-05-15 - Alexander Brevig : Changed begin() amd getKey(), this Library should be operational. | |
|| | 2009-05-09 - Alexander Brevig : Changed getKey() | |
|| | 2009-04-28 - Alexander Brevig : Modified API, and made variables private | |
|| | 2007-XX-XX - Mark Stanley : Initial Release | |
|| # | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
|| | |
|| @file Keypad.h | |
|| @version 1.8 | |
|| @author Mark Stanley, Alexander Brevig | |
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com | |
|| | |
|| @description | |
|| | This library provides a simple interface for using matrix | |
|| | keypads. It supports the use of multiple keypads with the | |
|| | same or different sets of keys. It also supports user | |
|| | selectable pins and definable keymaps. | |
|| # | |
|| | |
|| @license | |
|| | This library is free software; you can redistribute it and/or | |
|| | modify it under the terms of the GNU Lesser General Public | |
|| | License as published by the Free Software Foundation; version | |
|| | 2.1 of the License. | |
|| | | |
|| | This library is distributed in the hope that it will be useful, | |
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
|| | Lesser General Public License for more details. | |
|| | | |
|| | You should have received a copy of the GNU Lesser General Public | |
|| | License along with this library; if not, write to the Free Software | |
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
|| # | |
|| | |
*/ | |
#ifndef KEYPAD_H | |
#define KEYPAD_H | |
#if ARDUINO >= 100 | |
#include "Arduino.h" | |
#else | |
#include "WProgram.h" | |
#endif | |
#define makeKeymap(x) ((char*)x) | |
typedef char KeypadEvent; | |
typedef enum { | |
IDLE=0, | |
PRESSED, | |
RELEASED, | |
HOLD | |
} KeypadState; | |
typedef struct { | |
byte rows; | |
byte columns; | |
} KeypadSize; | |
const char NO_KEY = '\0'; | |
#define KEY_RELEASED NO_KEY | |
class Keypad { | |
public: | |
/* | |
Keypad(); | |
Keypad(byte row[], byte col[], byte rows, byte cols); | |
*/ | |
Keypad(char *userKeymap, byte *row, byte *col, byte rows, byte cols); | |
//void begin(); //DEPRECATED! | |
void begin(char *userKeymap); | |
char getKey(); | |
KeypadState getState(); | |
void setDebounceTime(unsigned int debounce); | |
void setHoldTime(unsigned int hold); | |
void addEventListener(void (*listener)(char)); | |
private: | |
void transitionTo(KeypadState newState); | |
void initializePins(); | |
char *keymap; | |
byte *rowPins; | |
byte *columnPins; | |
KeypadSize size; | |
KeypadState state; | |
char currentKey; | |
unsigned long lastUpdate; | |
unsigned int debounceTime; | |
unsigned int holdTime; | |
void (*keypadEventListener)(char); | |
}; | |
#endif | |
/* | |
|| @changelog | |
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays | |
|| | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine | |
|| | every time a state changes the keypadEventListener will trigger, if set | |
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime | |
|| | setHoldTime specifies the amount of microseconds before a HOLD state triggers | |
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo | |
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable | |
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime() | |
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener | |
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing | |
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey() | |
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private | |
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release | |
|| # | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment