Adafruit Keypad: a matrix keypad as a queue of events
Adafruit_Keypad reads the same membrane 4x4 and 3x4 keypads as the classic Keypad library, with a different model. Each call to tick() scans the matrix once and, for every key that changed since the last scan, adds an event to a queue: KEY_JUST_PRESSED or KEY_JUST_RELEASED, with the key’s character and its row and column. loop() then empties the queue with available() and read().
Built in on Mokxi: #include <Adafruit_Keypad.h> and it builds, with nothing to install. Free, and no account needed.
What Adafruit Keypad does
Because releases are events too, you can see exactly when each key went up and down, and two keys held together are reported as two presses. That makes it a good fit for chords, for a piano, or for anything that needs press-and-hold. The queue holds sixteen events, so a sketch that is busy for a while does not lose keys, as long as it reads them eventually.
There is no debouncing beyond the scan rate, so call tick() about every 10 ms, as the runnable example does with delay(10). The keymap is a two-dimensional char array wrapped in makeKeymap(), with the row pins and the column pins listed in the same order as the keypad’s connector.
| Library Manager name | Adafruit Keypad |
|---|---|
| Author | Adafruit |
| Include | #include <Adafruit_Keypad.h> |
| Boards | every board Mokxi compiles for |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | Keypad, 4x4, Keypad, 4x3 telephone |
Install it
It builds on every board Mokxi compiles for.
In Mokxi it is built in: #include <Adafruit_Keypad.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Adafruit Keypad" by Adafruit from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add Adafruit Keypad to lib_deps in PlatformIO. Mokxi follows the calls of release 1.3.2, so a sketch written here builds there too.
- ESP32-C3
- Arduino Uno
- Arduino Nano
- Arduino Mega 2560
- Arduino Leonardo
- SparkFun Pro Micro
- Arduino Micro
- ESP32-C6
- WCH CH32V003
- ATtiny85
- Raspberry Pi Pico
- Raspberry Pi Pico W
- Seeed XIAO SAMD21
- STM32
- STM32 Nucleo-F411RE
- STM32 Blue Pill
- micro:bit V2
- Arduino Uno R4
- ESP32 DevKit
- ESP32-S3-DevKitC-1
- ESP8266 NodeMCU
- Arduino Pro Mini 3.3 V
- Seeed XIAO ESP32-C3
- ESP32-C3 SuperMini
- Seeed XIAO ESP32-C6
- ESP32-DevKitC V4
- LOLIN32 Lite
- Wemos D1 R32
- Cheap Yellow Display
- TTGO T-Display
- Seeed XIAO ESP32-S3
- Arduino Nano ESP32
- Arduino Nano RP2040 Connect
- Seeed XIAO RP2040
- Waveshare RP2040-Zero
- Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
Adafruit_Keypad customKeypad = Adafruit_Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS)
Makes the keypad from a char keys[ROWS][COLS] map and two byte arrays of pins.
customKeypad.begin()
Sets the row pins as inputs with pull-ups and the column pins ready to scan.
customKeypad.tick()
Scans every key once and queues an event for each change. Call it every 10 ms or so.
customKeypad.available()
How many events are waiting in the queue, up to sixteen.
keypadEvent e = customKeypad.read()
Takes the oldest event. e.bit.KEY is the character, e.bit.EVENT says pressed or released, and e.bit.ROW and e.bit.COL say where.
while (customKeypad.available()) {
keypadEvent e = customKeypad.read();
if (e.bit.EVENT == KEY_JUST_PRESSED) Serial.println((char)e.bit.KEY);
}customKeypad.isPressed('5')
Whether one key is down right now, without going through the queue.
customKeypad.justPressed('#')
Whether a key went down on the last tick(). justReleased() is the opposite.
Example: Key presses and releases as events with Adafruit_Keypad
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include "Adafruit_Keypad.h"
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Adafruit_Keypad customKeypad = Adafruit_Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup() {
Serial.begin(9600);
customKeypad.begin();
Serial.println("Keypad ready");
}
void loop() {
customKeypad.tick();
while (customKeypad.available()) {
keypadEvent e = customKeypad.read();
Serial.print((char)e.bit.KEY);
if (e.bit.EVENT == KEY_JUST_PRESSED) Serial.println(" pressed");
else if (e.bit.EVENT == KEY_JUST_RELEASED) Serial.println(" released");
}
delay(10);
}Wiring
- Arduino Uno R3 9 to Keypad, 4x4 R1
- Arduino Uno R3 8 to Keypad, 4x4 R2
- Arduino Uno R3 7 to Keypad, 4x4 R3
- Arduino Uno R3 6 to Keypad, 4x4 R4
- Arduino Uno R3 5 to Keypad, 4x4 C1
- Arduino Uno R3 4 to Keypad, 4x4 C2
- Arduino Uno R3 3 to Keypad, 4x4 C3
- Arduino Uno R3 2 to Keypad, 4x4 C4
Common errors and how to fix them
The wrong characters come out, or keys in one row read as another row
The row and column pins are listed in a different order from the wiring. Check the keypad’s pinout (rows usually come first on the connector) and reorder rowPins and colPins to match.
Serial prints a number like 49 instead of the key
e.bit.KEY is a number holding the character code. Cast it, (char)e.bit.KEY, when printing, as the example does.
Some presses are missed when loop() is busy
tick() only sees what is down at the moment it scans. Keep loop() fast so tick() runs every 10 ms or so; the queue will hold the events until you read them.
Questions and answers
Should I use Adafruit_Keypad or the Keypad library?
Keypad returns one key at a time from getKey() and is the common choice for a code lock. Adafruit_Keypad gives every press and release as an event, which suits several keys at once.
Keep going
Try Adafruit Keypad without installing anything
Open the example, change the sketch, and keep your version in a free account.