-
Notifications
You must be signed in to change notification settings - Fork 932
Add Example Code for 4x4 Keypad with Raspberry Pi Pico #542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jcarranz97
wants to merge
9
commits into
raspberrypi:develop
Choose a base branch
from
jcarranz97:add-keypad-example
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
79b986c
Include keypad folder from blink example
jcarranz97 8a653c7
Include keypad example in README.md
jcarranz97 b30685b
Move keypad example under gpio
jcarranz97 f787419
Remove PICO_CYW43 as this example does not have any CYW43 functionallity
jcarranz97 139d981
Fix typo 'it can by used' -> 'it can be used'
jcarranz97 b80d96d
Include space between ) and {
jcarranz97 52a7f7b
Fix typo 'lectures' -> 'reads'
jcarranz97 c56503e
Implemented the enhanced keypad changes and README.adoc (#3)
jcarranz97 7324b2a
Fix pinout and update image
jcarranz97 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
add_subdirectory_exclude_platforms(dht_sensor host) | ||
add_subdirectory_exclude_platforms(hello_7segment host) | ||
add_subdirectory_exclude_platforms(hello_gpio_irq host) | ||
add_subdirectory_exclude_platforms(keypad host) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
set(TARGET_NAME keypad) | ||
add_executable(${TARGET_NAME} | ||
keypad.c | ||
) | ||
|
||
# pull in common dependencies | ||
target_link_libraries(keypad pico_stdlib) | ||
|
||
# Enable printing via USB serial | ||
pico_enable_stdio_usb(${TARGET_NAME} 1) | ||
pico_enable_stdio_uart(${TARGET_NAME} 0) | ||
|
||
# create map/bin/hex file etc. | ||
pico_add_extra_outputs(${TARGET_NAME}) | ||
|
||
# add url via pico_set_program_url | ||
example_auto_set_url(${TARGET_NAME}) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
= Keypad Example for Raspberry Pi Pico | ||
|
||
This document provides details about the 4x4 keypad example included in the larger repository of examples for Raspberry Pi Pico. This example demonstrates how to interface a 4x4 matrix keypad with the Pico and includes both simple and enhanced key detection modes. | ||
|
||
== Introduction | ||
|
||
This example shows how to use a 4x4 matrix keypad with the Raspberry Pi Pico. It has been enhanced to support detecting multiple key presses simultaneously, alongside the original single key press functionality. | ||
|
||
== Features | ||
|
||
* Simple key detection (one key press at a time) | ||
* Enhanced key detection (multiple keys pressed simultaneously) | ||
* Configurable maximum number of simultaneous key presses | ||
* Mode switching via macro definition | ||
|
||
== Hardware Requirements | ||
|
||
* Raspberry Pi Pico | ||
* 4x4 matrix keypad | ||
* Connecting wires | ||
|
||
== Wiring Instructions | ||
|
||
Follow these wiring instructions to connect the 4x4 matrix keypad to the Raspberry Pi Pico: | ||
|
||
[image2] | ||
image::pico_keypad_connection.png[Keypad Connection Diagram] | ||
|
||
=== Wiring Table | ||
|
||
The following table shows the GPIO pins used for the rows and columns of the keypad: | ||
|
||
[width="50%",cols="1,1,1",options="header"] | ||
|=== | ||
| Keypad Row/Column | GPIO Pin | Pin Number | ||
|
||
| Row 0 | GP9 | 9 | ||
| Row 1 | GP8 | 8 | ||
| Row 2 | GP7 | 7 | ||
| Row 3 | GP6 | 6 | ||
|
||
| Column 0 | GP5 | 5 | ||
| Column 1 | GP4 | 4 | ||
| Column 2 | GP2 | 2 | ||
| Column 3 | GP1 | 1 | ||
|=== | ||
|
||
Ensure that the keypad rows and columns are connected to the GPIO pins on the Pico as indicated in the table. | ||
|
||
== Usage | ||
|
||
This example can be compiled and run to interact with the keypad. | ||
|
||
=== Simple Mode | ||
|
||
In simple mode, the `get_keypad_value` function returns a single character corresponding to the pressed key. If no key is pressed, it returns a constant value indicating no key press. | ||
|
||
[source,c] | ||
---- | ||
char get_keypad_value(); | ||
---- | ||
|
||
=== Enhanced Mode | ||
|
||
In enhanced mode, the `get_keypad_result` function returns a `KeypadResult` structure containing the count of pressed keys and a list of those keys. | ||
|
||
[source,c] | ||
---- | ||
KeypadResult get_keypad_result(); | ||
---- | ||
|
||
The `KeypadResult` structure is defined as follows: | ||
|
||
[source,c] | ||
---- | ||
typedef struct { | ||
int count; // Number of pressed keys | ||
char keys[MAX_MULTI_KEYS]; // Pressed keys | ||
} KeypadResult; | ||
---- | ||
|
||
== Example Output | ||
|
||
=== Simple Mode | ||
|
||
If a key is pressed, the output will be: | ||
|
||
[source, plain] | ||
---- | ||
Key 'A' pressed | ||
---- | ||
|
||
If no key is pressed, the output will be: | ||
|
||
[source, plain] | ||
---- | ||
No key pressed | ||
---- | ||
|
||
=== Enhanced Mode | ||
|
||
If multiple keys are pressed, the output will be: | ||
|
||
[source, plain] | ||
---- | ||
Bang!!! '2' key(s) are pressed. Keys: A, B | ||
---- | ||
|
||
If no keys are pressed, the output will be: | ||
|
||
[source, plain] | ||
---- | ||
No key pressed | ||
---- | ||
|
||
== Additional Information | ||
|
||
For contributing to the repository, refer to the link:../../CONTRIBUTING.md[CONTRIBUTING.md] file. | ||
|
||
For licensing information, see the link:../../LICENSE.TXT[LICENSE.TXT] file. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
/** | ||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include "pico/stdlib.h" | ||
|
||
|
||
#define KEYPAD_NUM_ROWS 4 | ||
#define KEYPAD_NUM_COLUMNS 4 | ||
#define NO_KEY_PRESSED '\0' // Just a character that unlikely be | ||
// present in keyboards, so it can be used | ||
// to determine if no key is pressed. | ||
#define READ_MS_DELAY 10 // Delay between read to avoid noise | ||
|
||
// Enable enhanced mode to allow reading multiple keys simultaneously. | ||
#define ENHANCED_KEYPAD | ||
|
||
|
||
#ifdef ENHANCED_KEYPAD | ||
/* | ||
* When using the Enhanced Keypad mode, the get_keypad_value function | ||
* returns a KeypadResult structure instead of a single character. | ||
* | ||
* KeypadResult includes: | ||
* - count: The number of keys pressed (up to MAX_MULTI_KEYS). | ||
* - keys: An array containing the pressed keys (up to MAX_MULTI_KEYS). | ||
*/ | ||
#define MAX_MULTI_KEYS 6 // Maximum number of keys that can be pressed simultaneously. | ||
|
||
typedef struct { | ||
int count; // Number of keys pressed. | ||
char keys[MAX_MULTI_KEYS]; // Array of pressed keys. | ||
} KeypadResult; | ||
#endif // ENHANCED_KEYPAD | ||
|
||
|
||
const uint8_t keypad_rows_pins[KEYPAD_NUM_ROWS] = { | ||
9, // GP9 | ||
8, // GP8 | ||
7, // GP7 | ||
6, // GP6 | ||
}; | ||
|
||
|
||
const uint8_t keypad_columns_pins[KEYPAD_NUM_COLUMNS] = { | ||
5, // GP5 | ||
4, // GP4 | ||
3, // GP2 | ||
2, // GP1 | ||
}; | ||
|
||
|
||
const char keypad_keys[KEYPAD_NUM_ROWS][KEYPAD_NUM_COLUMNS] = { | ||
{'1', '2', '3', 'A'}, | ||
{'4', '5', '6', 'B'}, | ||
{'7', '8', '9', 'C'}, | ||
{'*', '0', '#', 'D'}, | ||
}; | ||
|
||
|
||
void pico_keypad_init(void) { | ||
// Initialize GPIOs | ||
//Initialize row pins as GPIO_OUT | ||
for (int i=0; i < KEYPAD_NUM_ROWS; i++) { | ||
uint8_t pin_number = keypad_rows_pins[i]; | ||
gpio_init(pin_number); | ||
gpio_set_dir(pin_number, GPIO_OUT); | ||
gpio_put(pin_number, 0); // Make sure GPIO_OUT is LOW | ||
} | ||
//Initialize column pins as GPIO_IN | ||
for (int i=0; i < KEYPAD_NUM_COLUMNS; i++) { | ||
uint8_t pin_number = keypad_columns_pins[i]; | ||
gpio_init(pin_number); | ||
gpio_set_dir(pin_number, GPIO_IN); | ||
} | ||
} | ||
|
||
|
||
#ifdef ENHANCED_KEYPAD | ||
KeypadResult get_keypad_result(void) { | ||
KeypadResult result; // Define the result structure. | ||
result.count = 0; // Initialize count to 0. | ||
|
||
// Iterate over key and rows to identify which key(s) are pressed. | ||
for (int row=0; row < KEYPAD_NUM_ROWS; row++) { | ||
gpio_put(keypad_rows_pins[row], 1); | ||
for (int column=0; column < KEYPAD_NUM_COLUMNS; column++) { | ||
sleep_ms(READ_MS_DELAY); | ||
if(gpio_get(keypad_columns_pins[column])) { | ||
// If the column pin is HIGH, a key is pressed. | ||
// Save the key in the KeypadResult structure and increase | ||
// count. | ||
result.keys[result.count] = keypad_keys[row][column]; | ||
result.count++; | ||
} | ||
} | ||
gpio_put(keypad_rows_pins[row], 0); | ||
} | ||
|
||
// Return the structure containing all pressed keys. | ||
return result; | ||
} | ||
#else | ||
char get_keypad_result(void) { | ||
// Iterate over key and rows to identify which key is pressed. | ||
// When iterating rows, the GPIO_OUT associated to the row needs to be set | ||
// to HIGH, and then iterate the columns to determine the GPIO_IN. | ||
for (int row=0; row < KEYPAD_NUM_ROWS; row++) { | ||
gpio_put(keypad_rows_pins[row], 1); | ||
for (int column=0; column < KEYPAD_NUM_COLUMNS; column++) { | ||
sleep_ms(READ_MS_DELAY); | ||
if(gpio_get(keypad_columns_pins[column])) { | ||
// If the column pin is HIGH, a key is pressed. | ||
// Put the row pin to low and return the pressed key. | ||
gpio_put(keypad_rows_pins[row], 0); | ||
return keypad_keys[row][column]; | ||
} | ||
} | ||
gpio_put(keypad_rows_pins[row], 0); | ||
} | ||
|
||
// Return a constant indicating no key was pressed | ||
return NO_KEY_PRESSED; | ||
} | ||
#endif //ENHANCED_KEYPAD | ||
|
||
|
||
int main() { | ||
stdio_init_all(); | ||
pico_keypad_init(); | ||
while (true) { | ||
#ifdef ENHANCED_KEYPAD | ||
// Call the enhanced function to get the result structure | ||
// containing the number of keys pressed and the keys themselves. | ||
KeypadResult result = get_keypad_result(); | ||
|
||
// Check if no keys are pressed. | ||
if (result.count == 0) { | ||
// Inform the user that no keys are pressed. | ||
printf("No key pressed\n"); | ||
} | ||
else{ | ||
// If one or more keys are pressed, print the number of pressed keys. | ||
printf("Bang!!! '%d' key(s) are pressed. Keys: ", result.count); | ||
|
||
// Iterate through the pressed keys and print them. | ||
for (int i = 0; i < result.count; i++) { | ||
printf("%c", result.keys[i]); | ||
|
||
// If it's not the last key, print a comma separator. | ||
if (i != (result.count - 1)) { | ||
printf(", "); | ||
} else { | ||
// If it's the last key, move to the next line. | ||
printf("\n"); | ||
} | ||
} | ||
} | ||
#else | ||
// Call the simple function to get a single pressed key. | ||
char key = get_keypad_result(); | ||
|
||
// Check if no key is pressed. | ||
if (key == NO_KEY_PRESSED) { | ||
// Inform the user that no keys are pressed. | ||
printf("No key pressed\n"); | ||
} | ||
else{ | ||
// If a key is pressed, print the key. | ||
printf("Key '%c' pressed\n", key); | ||
} | ||
#endif | ||
sleep_ms(500); | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.