A common problem raised in the forum is how to use a keypad to enter a number to be used in a sketch. The examples with the Keypad library show the principles but there is little or no explanation of how they work or how they can be changed
The aim of this thread is to explain the principles of keypad entry, explain how and why some things work or don't work and to provide a way forward for more complicated use of the Keypad library
Let's start with "How do I enter a number using the keypad ?"
Try this small sketch
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] =
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte colPins[COLS] = {10, 11, 12, A4}; //column pins
byte rowPins[ROWS] = {2, 4, 7, 8}; //row pins
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
Serial.begin(115200);
}
void loop()
{
char key = keypad.getKey();
if (key)
{
Serial.print("key : ");
Serial.println(key);
}
}
Change the pin numbers in the arrays and the baud rate to suit your system and upload the code and run it. Pressing a key on the keypad should print its value as defined in the keys array
Congratulations. You can now enter a number and print it.
Actually I am lying, as you can enter and print any value in the keys array even if they are not numbers. Let's improve that. Try this loop() function instead
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] =
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte colPins[COLS] = {10, 11, 12, A4}; //column pins
byte rowPins[ROWS] = {2, 4, 7, 8}; //row pins
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
Serial.begin(115200);
}
void loop()
{
char key = keypad.getKey();
if (key >= '0' && key <= '9') //only act on numeric keys
{
Serial.print("key : ");
Serial.println(key);
}
}
Now the program only accepts numbers and prints them
Actually, I lied again. It is reading and printing a character that represents a number rather than an actual number. Try doing something with the "number" like this
void loop()
{
char key = keypad.getKey();
if (key >= '0' && key <= '9') //only act on numeric keys
{
Serial.print("key : ");
Serial.println(key);
Serial.print("key * 10 : ");
Serial.println(key * 10);
Serial.println();
}
}
You will see that key * 10 is not what you want. What you are seeing is 10 * the value of the character not 10 times the number. So, how to fix it ? If you look carefully at the value printed by key * 10 you should spot a pattern. This revised loop() function takes advantage of that pattern by subtracting 48 from the value of the character the result of which is a single digit containing the actual number which you can use in the program
void loop()
{
char key = keypad.getKey();
if (key >= '0' && key <= '9') //only act on numeric keys
{
Serial.print("key : ");
Serial.println(key);
Serial.print("key * 10 : ");
Serial.println(key * 10);
byte keyAsANumber = key - 48;
Serial.print("keyAsANumber : ");
Serial.println(keyAsANumber);
Serial.print("keyAsANumber * 10 : ");
Serial.println(keyAsANumber * 10);
Serial.println();
}
}
If you are wondering where this "magic" number of 48 comes from then search Google for ASCII and all will be revealed. Incidentally, if it helps understand why it works you could also do
byte keyAsANumber = key - '0';
instead
Future instalments will deal with how to input a multi digit number