A matrix keypad is the kind of keypad you see on microwave ovens, gas pumps, and calculators. A matrix keypad you can connect to a breadboard is also great for prototypes and inventions where things like codes, times, or other values have to be entered.
Parts
- (1) 4x4 Matrix Membrane Keypad
- (4) Resistors - 1 kΩ (brown-black-red)
- (4) Jumper Wires
Circuit
Note: Be careful when making your 4x4 Keypad connections. The FLiP and ABWX diagrams below use the same pins, but the orientation of your circuit and keypad differs depending on which board you use.
Test Code
The test program updates the Terminal showing whichever single key is pressed, every 1.5 s. If you're not pressing a key when it checks, the program will display -1. So, for best results, press and hold the key you want to try. Keep in mind, this is just test code. The Try This and Your Turn examples will demonstrate how to make it responsive as you type in numbers, how to do simple mathematic functions, and more.
Before running the program, let's add the matrix keypad examples and library to your Learn folder.
- Download Matrix Keypad Library and Examples 1_1_6.zipside
- In SimpleIDE, click Tools and select Update Workspace.
- Click Browse, and then find/select Matrix Keypad Library and Examples 1_1_6.zipside.
- Click Open and wait for SimpleIDE to update the workspace.
Now, you're ready to try the first example program
- Click SimpleIDE's Open Project button, and open Keypad 4x4 Read Keys.side from ...Documents/SimpleIDE/Learn/Examples/Devices/Interface/.
- Make sure your board has power, and the COM port is correctly set.
- Use SimpleIDE's Run with Terminal button.
- When the SimpleIDE terminal appears and starts displaying "Key = -1", try pressing and holding various buttons and verify that the program detects and displays the button you press.
How it Works
This 4x4 matrix keypad has 16 built-in pushbutton contacts connected to row and column lines. A microcontroller can scan these lines for a button-pressed state. In the keypad library, the Propeller sets all the column lines to input, and all the row lines to input. Then, it picks a row and sets it high. After that, it checks the column lines one at a time. If the column connection stays low, the button on the row has not been pressed. If it goes high, the microcontroller knows which row (the one it set high), and which column, (the one that was detected high when checked). See the schematic in the "Circuit" section, above, for a visual reference of the keypad layout.
The keypad library supports pretty much any number of rows and columns. So, the program has to tell it our keypad is has 4 rows and 4 columns, which I/O pins the lines are connected to, and what value each button represents. The rows, cols, and values arrays store that information. The rows array will be used to tell the keypad library that the top row is connected to P7, the second row to P6 and so on. Likewise, the cols array lists the leftmost column as connected to P3, the next over connected to P2 and so on. The values array stores the value we want the program to give us for each button press. For example, if the top-left button is pressed, we want the number 1, and if the next one over is pressed, we want the number two. If the top right button is pressed, we want the ASCII code for the 'A' character, which is 65.
Inside the main function, keypad_setup gets the number of rows (4), the number of columns (also 4), the rows array, the cols array, and the values array. After that, key = keypad_read() will return -1 if no buttons are pressed. If a button is pressed, it will return the value from the array that corresponds to that button. For example, if you press a button on the 3rd row, second column, the keypad_read function will return the number 8, which will get stored in the key variable. To display it correctly, an if statement checks for values less than or equal to 9, and displays them with %d, decimal-integer formatting flag . The ASCII codes for '*', '#', 'A', 'B', 'C', and 'D' are 35, 42, 65, 66, 67, and 68, all of which are above 9, and get displayed with the print statement that uses the %c character formatting flag.
/* Keypad 4x4 Read Keys.c Demonstrates how to read individual key presses with the keypad library. */ #include "simpletools.h" // Libraries simpletools & keypad #include "keypad.h" int rows[4] = {7, 6, 5, 4}; // Row I/O pins (top to bottom) int cols[4] = {3, 2, 1, 0}; // Column I/O pins (left to right) int values[16] = { 1, 2, 3, 'A', // Values for each key in the 4x4 4, 5, 6, 'B', 7, 8, 9, 'C', '*', 0, '#', 'D' }; int key; // Variable stores keypad key int main() // Main function { keypad_setup(4, 4, rows, cols, values); // Setup dimensions, keypad arrays while(1) // Main loop { key = keypad_read(); // Get pressed key (or -1 for none) if(key <= 9) // Display key value print("key = %d\r", key); // If <= 9, dispaly as decimal else print("key = %c\r", key); // Otherwise, display as character pause(1500); // Wait 1.5 s before repeat } }
Did You Know?
If you want the Propeller to rememeber a value 123 when after you press the 1, 2, and 3 buttons, here's how it works:
- When the 1 is pressed add it to a variable (we'll use the number variable).
- Wait for the 1 button to be released.
- When 2 is pressed, muliply number by 10, then add 2.
- Wait for the 2 button to be released.
- When 3 is pressed, muliply number (which holds 12) by 10, and add 3.
- Wait for the 3 button to be released.
- If the button is pressed that signals you're done typing digits, save or display the value.
Try This
This example program allows you to press/release digits to build numbers. For example, if you press and release 1, then 2, then 3, then #, the program will display "You entered 123". Keep in mind that it's not just rememebering the digits 1, 2, and 3, it's creating the number 123 by multiplying what's already in the number variable by 10, and then adding the most recently pressed digit. Once the Propeller has this value, it could be used as a count-down timer in an oven, or the first value used in a calculator operation.
/* Keypad 4x4 Digits to Numbers.c Demonstrates how to build numbers with multiple key presses. */ #include "simpletools.h" // Libraries simpletools & keypad #include "keypad.h" int rows[4] = {7, 6, 5, 4}; // Row I/O pins (top to bottom) int cols[4] = {3, 2, 1, 0}; // Column I/O pins (left to right) int values[16] = { 1, 2, 3, 'A', // Values for each key in the 4x4 4, 5, 6, 'B', 7, 8, 9, 'C', '*', 0, '#', 'D' }; int number = 0; // Stores number result int main() // Main function { keypad_setup(4, 4, rows, cols, values); // Setup dimensions, keypad arrays print("Type a number, then press #\r"); // User prompt while(1) // Main loop { number = keypad_getNumber(); // Get number entered on keypad print("\r"); // Next line print("You entered %d\r", number); // Display result } }
Your Turn
- The ...Documents/SimpleIDE/Learn/Examples/Devices/Interface/ folder also has a calculator example that uses the A button to add two numbers, and the B button to subtract. Try modifying this program for multiply with C and divide with D.
Advanced Topic
- Try opening the 4x4 Keypad Read Simultaneous Keys example.
- Try pressing any two keys, they should both display.
However, when you start pressing 3 keys at a time, a keypad like the 4x4 Matrix Membrane, which is designed for individual key presess will sometimes display as if a key was pressed that was not actually pressed.
Many combinations work fine, like 1, 5, 9, and D will all display correctly, as will 1, 4, 7, and *. But, try pressing 1, 2, and 7. The program will tell you that detected 1, 2, 7, and 8. This phenomenon is called ghosting, with the number 8 being the ghost number. Ghosting happens when you press 2 buttons on the same row, and one button on the same column. For example, 1 and 2 are on the same row, and 7 is on the same column as 1. The 7 press travels up to 1, across to 2, and then down the 8 column and is detected there. Some keypads that are designed for multiple, simultaneous key presses have built-in diodes that can prevent this.
Another problem with keypads that are designed for indivdual key presses is called masking. Masking just means that if your program is waiting for a single key press, and you then press and release a second key after the first, the second key is not detected. The change is "masked out" by the keypad circuit.