In this blog post, we are going to write a C++ program to scan a keypad and display the character that is pressed on a seven segment display.
Hardware diagram
Figure 1 shows a diagram of the system that we are working with. There is a 4×4 keypad connected to a port of an Arduino and a seven segment display connected to another port of the Arduino. Our program will make the seven segment displays the current key being pressed on the keypad.
Keypad working principles
You might come across tutorials where a button or a switch is connected to an input/output (IO) pin of a microcontroller. That pin is configured as an input so that your microcontroller can monitor the status of the button and take some actions, for example pressing a button to toggle an LED light. In applications where a large number of buttons/keys is required (calculators/keyboards…), connecting every single key/button to an IO line may not be feasible because of the limited numbers of the IO line provided by your microcontroller. Even if it’s possible, it’s a big waste of resources and the interface will contain a lot of wires (For example: a keypad of 16 keys will eat up 16 IO pins of the microcontroller).
To avoid the trouble, there is a very clever technique, called multiplex matrix keypad. In this technique, the keys in the keypad are connected in a multiplexed matrix form to help reducing the number of IO pins required. For example, a 4×4 keypad with 16 keys would require 16 IO lines should they be connected to the microcontroller in the traditional way (i.e. 1 key 1 IO pin). Using this clever technique, the number of IO pins required is only 8. Here is how: the keys are arranged in a matrix form and there are 4 rows and 4 columns as shown in Figure 2.
Figure 2 shows the internal interconnect of the keypad. Each key is a push button which has one end connected to one row, and the other end connected to one column. There are 4 rows: row 0, row 1, row 2 and row 3. There are 4 columns: column 0, column 1, column 2 and column 3. There are 16 buttons which are indexed from 0 to 15 as shown in the Figure 2. Assuming row 0 is connected to PIN_0 of the microcontroller, row 1 is connected to PIN_1, row 2 is connected to PIN_2, row 3 is connected to PIN_3. Similarly, assuming column 0 is connected to PIN_4, column 1 is connected to PIN_5, column 2 is connected to PIN_6 and column 3 is connected to PIN_7.
With the above diagram, we can scan for which button is pressed by the following algorithm:
- Set all columns as input ports with internal pull up resistor
- Loop over each row
- Pull the current row low
- Pull all other rows high
- Read the status of each column
- If the current column is low, it means the button at position (row, column) is pressed. In other words, button indexed (row * 4 + column) is pressed.
Program skeleton
Now with the background of working principles of keypad, let’s dive into coding our program.
There are two entities in our circuits: a keypad and a seven segment display. We might want to create two classes: KeyPad and SevenSegment to control the respective peripherals. Let’s create the KeyPad class.
We have declared two member functions: init() and get_pressed_button(). init() function is to initialise the port and get_pressed_button() is to determine which button is pressed. get_pressed_button() returns a number representing which button is pressed. This function implements the algorithm as we discussed above.
Implementation with Arduino
This section shows how to implement the code if using an Arduino Mega2560 board as the microcontroller. We will need to create two classes representing the KeyPad and SevenSegment.
KeyPad class
In this project, the keypad is connected to PORTC of the Arduino (pin 30 to pin 37). With that connections, the KeyPad class can be implemented as follow:
Seven Segment Controller class
Next, to control a 7-segment, we can create an object called SevenSegment. This object has two methods:
- init() to initialise the port being used to drive the seven segment as output port
- display() to display a given number from 0 to 9, or any other characters
If we connect the seven segment to PORTL of Arduino Mega 2560, we can write Seven Segment class as follow. The init() method is to initialise PORTL as output port, and the display() method decodes the given number and light up necessary LEDs in the seven segment to display output character.
Main program
Now with the KeyPad and SevenSegment class ready, we can write our main program. In our main program, we create two objects kp and seg7 to control keypad and seven segment, respectively. After calling initialisation methods, we repeatedly call get_pressed_button() method of the keypad object to determine which button is pressed and show it on the seven segment.
After compiling and flashing the code, you should see the seven segment display the number being pressed on the keypad as expected.
Wrapping Up
In this article, you have learnt how to write a C++ class to control a KeyPad using Arduino. That’s all for today’s post. Thanks for reading.