bclose

19 – Keypads

Objectives

 

 

    • Get to know a 4×4 Keypad.
    • Use another external library: KeyPad.
    • Review arrays, this time with two dimensions.
 

Bill of materials

Arduino Uno Arduino Uno or equivallent.

We can use any other Arduino board in this chapter.

BreadboardJumper wires A solderless Breadboard plus some jumper wires.
4x4 Keypad A 4×4 keypad

 

HOW DOES A KEYPAD WORK?

 

A keyboard is nothing more than a collection of buttons, each of which we assign a symbol or a particular function. But buttons in the end.

Reading buttons is something that has no secrets for us, but if we connect each key to a digital pin of our Arduino, we would be running out of pins.

The keyboard of your computer has usually around 106 keys, so the brute force method will get into trouble quickly. We need another solution.

And as the world it is full of clever people, they came up with an elegant solution, a key matrix or keypad.
Let’s see an example with a small keypad of 16 keys, as those used in mobile phones or cash dispensers.

Matrix 4x4 keypad schematic

Matrix keypad

 

For our Arduino to know which key is pressed, we simply apply voltage (5V – HIGH) on the rows sequentially and then read the columns to see which of them is HIGH. The keypads use a combination of rows and columns to know the status of the buttons.

Each key is a button connected to a row and a column. When one of the keys is pressed, a single connection between a row and a column is closed.

For example, we set HIGH the first row (wire 8 in the above diagram) and then we read the wires corresponding to the columns (wires 4, 3, 2.1). If none is HIGH, there isn’t any buttons pressed on the first row.

We turn to the second row (line 7) and set it HIGH. If when reading the wires 4, 3, 2 and 1, we find that the wire 1 is HIGH, it shows that key corresponding to “B” has been pressed.

Thus, to read a 4 × 4 keypad we need only 8 wires instead of 16, although it will give you a lot of trouble to program.

For a 106-key PC keyboard it will suffice an array of 10 × 11, that is, 21 wires instead of 106.

 

WIRING SCHEMATIC DIAGRAM

 

The most practical is to connect the keypad directly to Arduino, we can use jumper wires or a male pin header if we don’t want that any wire get released.

Chapter_19_wiring_diagram

 

This is one of those rare occasions when an circuit schematic diagram would make little sense, so we will move quickly to see program.

 
  • A quick note: For convenience in the diagram, and because the examples that come with Arduino use these same pin numbers, 0 through 7, we have maintained them. But we should know that Arduino uses pins 0 and 1 to communicate via USB, so it is not good to use them for something else if we want to use the serial port.
 

READING PROGRAM

 

As we said, the program must set HIGH the voltage consecutively on rows 8, 7, 6, 5 and then read the values on the columns to detect whether any key is pressed.

It is not a complicated program, but before panic seizes those who follow the session with growing fear we must comment that someone has had this problem before and have kindly put at our disposal a library called KeyPad, very useful to read this type of keypads.

 
  • Of course, you can write a program to read the keypad and detect the keystrokes without using the library. Cheer up, it is not difficult and practice is always good.
 

First, we have to download and install the library. This is the link:

keypad.zip

You can also download it from the Arduino site:

http://playground.arduino.cc/Code/Keypad#Download

Go to the section “Download, install and import” and you will find the link to keypad.zip.

Remember that in order to install the library in the Arduino IDE you have to go to Sketch\Include Library\Add .ZIP Library and then find and select the file Keypad.zip from the folder where you have previously downloaded it.

Import .ZIP library



Once it has been installed you only have to tell Arduino IDE you want to use it in your sketch. If you go to Sketch\Include Library\Keypad the following line will be included in your sketch:

#include <Keypad.h>

Let’s see how to use this library. First, we are going to define a couple of constants.

const byte Rows = 4;          //4 row KeyPad 
const byte Cols = 4;          //and 4 columns

And now a couple of arrays that will tell the library which Arduino pins correspond to the rows and columns of the keypad:

byte Row_Pins[] = {7, 6, 5, 4};     // Arduino pins for the rows 
byte Col_Pins[] = { 3, 2, 1, 0};    // Arduino pins for the columns.


Remember that an array is a collection of items written between braces and separated by commas. It is more comfortable than defining 8 variables.

Remember, as we saw in the chapter 9 when we defined an array by enumerating its elements, that we don’t need to write the number of items between brackets because C++ counts them itself.

We will have to further define which symbols correspond to each key position. A new opportunity to enjoy arrays, but this time using 2-dimensional arrays.

char Keys [ Rows ][ Cols ] =
    {
        {'1','2','3','A'},
        {'4','5','6','B'},
        {'7','8','9','C'},
        {'*','0','#','D'}
     };
 
  • We define the 4 × 4 array passing the size between brackets using the variables Rows and Cols. The array will have 4 rows, each one containing a 1-dimensional array of 4 elements. Finally we define the four 1-dimensional arrays of four items.
  • Pay attention to the fact that each array is enclosed between braces. The array items are separated by commas, but at the end of the outer brace there is a semicolon because the block is considered an assignment as a whole.
  • Arrays always seem complicated until you get used but they are not that bad and this is a good example to understand the idea of a 2-dimensional array.
 

One of the curiosities of reading a key matrix and then assign a character contained in an array is that we can redefine the value of the keys without changing the contents of the array.

 
  • If for whatever you had wrongly connected the keypad pins to Arduino, we could redefine the values of the array to match the keypad keys. It may be easier than reconnecting the wires.
  • In fact the ability to map the representation of a character to a position on a table, is what allows us to reconfigure the same keyboard in different languages, without changing the values in the array (and it will also help a lot to further change the symbols labeled on the keyboard).
 

Finally we have to create an instance of a Keypad object called KeyPad1.

     
Keypad KeyPad1 = Keypad(makeKeymap(Keys), Row_pins, Col_pins, Rows, Cols);

The previous line can scare a bit, but it is really a nonsense. The translation would be this: create an instance of the Keypad object called KeyPad1 and assign it the keys you have in the Keys array. Then we tell that we have connected the rows of the keypad to the pins indicated in the Row_Pins array and the columns to those in the Cols_Pins array.

 
  • MakeKeymap (Keys) is a function available in the library and allows us to assign an array of values to an array. It is done only once at the beginning unless we want to change it on the fly for whatever reason.
 

To read the keypad we call another function of the library, getKey():

char keyStroke = KeyPad1.getKey();

Finally we send the pressed key to the Serial Monitor console. This is the full version sketch:

Sketch 19.1
     
     #include <Keypad.h>           
     const byte Rows = 4;                // Four rows
     const byte Cols = 4;                // Four columns

     byte Row_pins[] = {7, 6, 5, 4};     // Arduino row pins
     byte Col_pins[] = { 3, 2, 1, 0};    // Arduino column pins
     char Keys [Rows][Cols] =
          {
              {'1','2','3','A'},
              {'4','5','6','B'},
              {'7','8','9','C'},
              {'*','0','#','D'}
          };
     Keypad KeyPad1 = Keypad(makeKeymap(Keys), Row_pins, Col_pins, Rows, Cols);
 
     void setup()
     {
         Serial.begin(9600);
     }

     void loop()
     {       
         char Keystroke = KeyPad1.getKey();
         if (Keystroke!= 0)               // if the value is 0
            Serial.println(Keystroke);   // no key is pressed
     }

By the way, in C ++ and other languages it is very common to write the statement:

if (Keystroke != 0)

… this other way (more elegant) and completely equivalent:

if (Keystroke)

The if condition should be evaluated to TRUE or FALSE, and for computers a 0 is FALSE without remission, but any value other than 0 is TRUE, including a character.

 

Summary

 

 

    • We have used our first hexadecimal keypad:
      • They are practical and very easy to use as you get accustomed to them.
      • They are available in multiple formats and types, here we have used one typical 4 × 4, but there are also 4 × 3 keypads in different materials and finishes.
      • We can disassemble an old broken mobile phone and use its keyboard, in addition to other things, in the described manner.
    • We have used keypads as an excuse to return on arrays. It’s worthwhile that you devote them some time as they help you to solve comfortably some programming problems, they don’t deserve their bad reputation.
    • We have known another external library, KeyPad. It will be very useful in your projects. I hope we can do some more sophisticated examples in further chapters using a keypad to open a lock, for example.
 

 

 

No Comments

Give a Reply