In this article let’s discuss designing of matrix keypads and the programming part to get the information regarding the pressed key. The Matrix keypads are used in systems/control panels where Human Machine Interface (HMI) is required in order to change the operating parameters of a system/machine. The Computer keyboard is also a matrix keypad.
The name itself infers that it has some keys arranged in rows and columns. Here arrangement of keys doesn’t mean the layout of the keys or physical placement on the circuit board, but the keys are identified in terms of elements of a matrix like M11, M12, and so on… up to M44 for a 4X4 Matrix Keypad.
The advantage of these matrix keypads is that all the switches of the matrix can be read using lesser number of I/O pins of a processor/microcontroller. For example, consider a 4X4 Matrix keypad, which contains 4*4=16 Keys. We need 16-Pins of the microcontroller in order to read the status of these 16 switches/push buttons individually. But, by using the Matrix type of configuration just 8-Pins are sufficient. In this case, the Pin count is halved.
Connecting the Push Buttons in a Matrix Keypad Format
Let’s take 4X4 Matrix Keypad as a reference and understand the connections. For a 4X4 keypad there are 4*4=16 push buttons. For easy understanding, let’s arrange these 16 push buttons as the elements of a 4X4 Matrix i.e, in four rows and four columns. These are electrically connected as shown below. As every button switch has two terminals, Terminal 1 of each switch in a row is connected to other switches. Similarly, switches in each column have one of their terminals connected to the remaining switches in the same column, thus giving out 4 pins representing four rows and 4 pins representing four columns.
Programming a Microcontroller to Read the Pressed Key
The pressed key is identified in terms of rows and columns. For this purpose, we will enable the columns one by one (by issuing logic HIGH) and then read the row which is enabled due to the pressed key for each of the columns. If there is no key in pressed state, then all the rows are read as LOW. The same procedure can be followed by interchanging the rows and columns.
Now, let’s put the logic into a C-Program. For 4X4 Matrix, in a microcontroller, we need 4-Pins as outputs for enabling the columns and 4-Pins as inputs for reading the rows. The variable named as ‘column’ contains the information regarding the enabled column. The same data is loaded into PORTC using a temporary variable. This temporary variable is initially loaded with value ‘1’ and is left shifted by multiplying it with ‘2’ each time when the loop is executed. ‘For loop’ is restarted with temp=1 and column=1. As every row contains 4 switches, the switches of row 1 can be valued as columns. When a switch from the second row is pressed, as there are 4 switches before row 2, it is valued as ’4+column’. Thus, our logic is converted into C-Program.
The identified key can be used according to the required application. In this example program, let’s show the number of the pressed key. For this purpose, a switch label with 16 cases for 16 keys is used to show the key value in Hexadecimal format.
The switches that are used in the matrix keypad can be of various types. The Mechanical parts of the push buttons do not change their states in a smooth fashion. They produce a transient output which might be understood by the microcontroller as if, the key is operated repeatedly. To avoid this wrong interpretation, a delay time can be included in the program after detecting the pressed key such that, the transient state is settled. This delay can be included in the program flow before or after the execution of the key function. The Instruction Pointer executes the Switch label and after identifying the key, the delay function is executed. This delay function is executed even if any of the keys are not pressed. If this is not desired, the delay function can be included in each case of the switch label.
If there are some other outputs in the system like, multiplexed segment displays or matrix displays etc.., which should be updated continuously, then instead of using delay function, it is better to execute one cycle of such updating. For example, if we have to show a 6-Digit value on a segment display, then instead of using a delay to eliminate bouncing effect of the key, the display can be refreshed 10 to 50 times.
Alternating the Key Function
A 4X4 Matrix contains 16 keys. This number can be either doubled to 32 Keys by using one button in addition to the matrix or increased to 30 Keys by using one of the matrix keys as a selector button similar to the ‘Shift key’ in the keyboard. This is entirely a software approach. If the user operates the selector button and releases the key, then the alternate function is activated and this continues until the user operates the selector button for the next time. It is like toggling action between the normal and the alternate functions of the keys. Below is the program for converting 16 Keys to 30 functions. This is useful to develop simple systems which do not require an alphanumeric display to show the Menu options.
Keypads in Proteus
There are inbuilt matrix keypads in the Proteus software. Their operation is as discussed till now. These keypads can be used while developing the simulation part of a prototype. Phone and calculator keypads are readily available in the software.
Using the Phone Keypad
The phone keypad in the Proteus software has three columns and four rows. So, the program has to be modified for correct identification of the key. The column variable must run from ‘1 to 3’ instead of ‘1’ to 4’ and as there are 3 switches above the 2nd row, the key is read as ‘3+column’ instead of ‘4+column’.
Interrupt Driven Key Identification
The program code shown above works well and serves the purpose. It is called as the Polling type of programming i.e., the CPU has to read the Rows continuously to find out the key. It is possible for systems which have to perform simple tasks like for example to show the pressed key as an alphabet or as a number or to switch a particular load etc..,. But if the processor has to run some other tasks in addition to the previously mentioned tasks, Interrupt driven programming is a better choice.
In this type of programming, the key identification part starts to function when a user operates any of the keys. The identification process can be started immediately with the first key press or it can be used as a wake-up signal in case there is a sleep mode involved in the system. The circuit connection needs to be modified for this purpose. The microcontroller must possess an external Interrupt source. The circuit connection to generate an Interrupt for every pressed key operation is shown below.
From the above image, it is clear that, on pressing any of the switches, the state of the interrupt pin i.e., INT0 changes from Low to High. Hence, this particular interrupt should be defined to generate Interrupt on Rising Edge transition. Whenever a key is pressed, an Interrupt is generated. The Key Identification function has to run i.e., the ‘for loop’ discussed previously. This is how we can reduce the load on the processor instead of refreshing the columns all the time. Below is the modified program code.
The Alpha-numeric keypad
The matrix keypad discussed up to now, can be used as an alpha numeric keypad by modifying the program. As there are 16 keys, we will use 12 keys for the alpha-numeric data similar to the mobile phone keypads. For this purpose, a timer counter is utilized to monitor the time gap between one key-press instant to the next key-press instant. If this time gap reaches the preset value, then the cursor shifts to next position and the data in the previous position remain the same as visible. The circuit diagram for the alpha-numeric matrix keypad example is shown below.
The program code presented below uses two new variables, one is ‘roll’ to indicate whether the time gap is reached and the cursor is shifted or not and the other is the ‘roll_out’ to count the time gap, whose value can be varied to vary the time gap to shift the cursor position. Whenever a key is pressed, the key value is verified whether it belongs to characters or the special functions. Depending on the result, the key functions are executed to store the character into the message variable. Below is the flow chart of the process.
In this example, the entered text is shown on the display after pressing the ‘Enter key’. The clear key is used as back space. Key=8 is the character type changing key, which shifts between Upper case, lower case, symbols, and numbers. When the ‘run key function’ is executed, the first character of that key is loaded into the character[ ] variable. If the same key is repeatedly pressed, then its index is incremented to get remaining characters of the key. For symbols and numbers, this index is not incremented as they are unique. However, in order to include more symbols, the program can be modified to increment index of the symbol type character also.