A 4×4 keypad is a really useful Arduino project component, particularly for security access projects or projects requiring code inputs. One of the problems with using the keypad however, is that you’re going to be using up 8 of your Arduino inputs just to read all of the buttons. This is obviously more efficient than connecting the 16 buttons individually but it’s still using up the majority of your Arduino’s IO. If you’re using one of the smaller Arduino boards such as the Uno or Nano, you’re not going to be able to connect something like an LCD display, TFT display or Ethernet shield to it as well, making it difficult to display the code which has been input and really limiting the functionality you could bring to your project. So, in this guide we’rd going to be looking at a way in which you can connect your entire 4×4 keypad to a single Arduino input and still read each button individually.
This project assumes that you know the basics of Arduino programming, otherwise follow our guide on getting started with Arduino.
What You’ll Need For This Project
- Arduino (Uno Used Here) – Buy Here
- 4×4 Keypad – Buy Here
- LCD Display – Buy Here
- Resistor Set (10 Different Value Resistors Required) – Buy Here
- LCD Contrast Potentiometer – Buy Here
- Breadboard – Buy Here
- Jumper Wires – Buy Here
How To Connect Your 4×4 Keypad To A Single Arduino Input
When working on Arduino projects, people often overlook the 6 analogue inputs and start working with the digital IO, especially if they’re not using “measurement” sensors in their project. The analogue inputs can actually be quite powerful and versatile and although they require a bit more code, they can be effectively used to free up some of your digital IO.
This project draws upon a concept used in a previous project, connecting multiple push buttons to a single Arduino input, it is however a little more complex due to the way the keypad is internally wired. There isn’t a common ground and 16 outputs, one connected to each button. Instead, the buttons are wired into a grid matrix in rows and columns and you’re given a connection to each row and each column in order to identify which button is being pressed.
The overall concept is to connect a different set of resistors to each button so that you generate a different voltage on the analogue input for each button, thereby enabling your Arduino to identify which button is being pressed without actually having to connect each button individually to your Arduino and clog up your IO.
Connecting Your 4×4 Keypad
We’re going to ignore the LCD connections in this project and assume that you know how to connect an LCD display to your Arduino, if you don’t, follow the link and we’ll show you how. The LCD display in this project is just used to display which button is pressed and demonstrate than it is possible to connect a keypad and LCD display to your Arduino and still have 8 free digital IO pins!
What we are going to be doing is turning the keypad into a selectable voltage divider circuit, with each button selecting a different divider configuration, resulting in a different voltage being measured by your Arduino, enabling it to identify which button is being pushed.
The voltage divider circuit consists of two resistors in series, with the Arduino’s analogue input measuring the voltage at the mid-point. We have a fixed resistor in the top half of the divider, which is the 5.1K resistor shown by itself on the top right in this example, and then a selectable group of resistors which are activated in different combinations by the keypad in the bottom half of the divider.
You can use any combination of resistors you’d like to, the actual resistance isn’t that important. What is important is that each resistor is a different resistance so that the ratios between the resistors create enough of a difference in voltage for your Arduino to detect each button combination.
Lets look at the circuit:
We can see that each row and each column of the keypad has a resistor connected to it, and the whole keypad and resistor circuit is connected as the “bottom” or second resistor in our voltage divider circuit. When we push a button, a connection is made between one of the resistors in the left group of four and one of the resistors in the right group of four (one row and one column) to create an overall resistance, which is unique to each button.
You’ll notice that all 8 of these resistors are different and it’s important that no combinations can produce the same resultant resistance. For example, an 8K and 4K resistor together in series would have the same resultant resistance as a 7K and a 5K resistor in series.
We then have a single resistor on the top right which forms the “top”or second resistor in our voltage divider circuit.
Lastly, the centre point of our voltage divider circuit is connected to one of our Arduino’s analogue inputs.
I used an LCD shield for my test setup so I don’t require the additional connections to the LCD display.
That’s the circuit complete, we can now have a look at how to code your Arduino to identify each button from the single Arduino analogue input.
Let’s now have a look at how to get your Arduino to recognise which button is being pressed in the code.
Here is the code:
//The DIY Life
//15 November 2019
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Assign LCD screen pins, as per LCD shield requirements
lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
int num = analogRead(A0);
char button = ' ';
button = '1';
button = '2';
button = '3';
button = '4';
button = '5';
button = '6';
button = '7';
button = '8';
button = '9';
button = '*';
button = '0';
button = '#';
button = 'A';
button = 'B';
button = 'C';
button = 'D';
The initial functions outside of the main loop are all related to the LCD display, you can read up on these in our guide to connecting an LCD display to an Arduino.
In the loop of the code, we first clear the display and then display the label text “Button: “.
We then read in the voltage on the analogue input to a variable called num. This will store a an integer between 0 and 1023 which is proportional to the voltage measured by the input between 0 and 5V.
Now we create a character variable called “button” in order to store the pressed character.
Finally, we use a switch statement to look at the value stored in the variable num and identify which button corresponds to that value. We set the variable “button”equal to the corresponding character, break from the switch statement and then display the character on the LCD before running a short delay to make the code more stable.
The only challenging part of this code is determining what value is measured for each button pressed on your keypad. In order to do this you can either use the Arduino IDE serial monitor or you can simply display the measured value directly onto your LCD (Use the line lcd.print(num) right after you read your analogue input) and make a note of each value displayed for each button pressed. You’ll then need to go through the code and change all of the values to correspond with your actual measured values for each character.
Once you’ve found and set your button values, upload the final code to your Arduino and try it out, your LCD should display the character corresponding to each button you press.
Problems With Fluctuating Input Values
There may be some instances where these measured values do not stay constant, if you have an unstable power supply, a bad quality Arduino or resistors, or resistors which are particularly susceptible to temperature variation. If this is the case then you’ll need to define a small range for each input and change your switch statement to an if statement which has a lower and upper limit for each button.
int num = analogRead(A0);
char button = ' ';
if (num >= 720 && num <= 730)
button = '1';
else if (num >= 700 && num <= 715)
button = '2';
Now you’ll be able to create better keypad based Arduino projects with more available IO!
Have you used this method or a similar method to connect your 4×4 keypad to your Arduino more efficiently? Let us know in the comments section below.
Share This Guide:
If you found this tutorial useful, please share it to help others out as well.