rapkeeper:
I am confused. I just read the Keypad(makeKeymap(userKeymap), row[], col[], rows, cols) command. I don't understand the syntax of this command. Would someone be nice enough to explain me what the words mean?
Let us see if we can acquire some better understanding of what you have wanted (the meaning of this highly abstracted structure: Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);) with the help of the following Keypad.
Figure-1: 4x4 keypad interfacing with Arduino UNO
A: Detecting that a Key(Switch/Button) has been closed.
1. Row Lines (R1 - R3) are terminated to LH by enabling the internal pull-up resistors.
2. Column Lines (C1 - C4) are activated to Logic-LOW (LL) one after another. This means that when C1 is made LOW, all other column lines (C2 - C4) are kept at Logic-HIGH (LH) state.
3. Let us assert 0111 on C1C2C3C4 and close K11 button. The result is this:
(1) R1 line will get shorted with C1 line; as a consequence, Logic-level of DPin-11 will LOW.
(2) We will observe this bit pattern (known as Scan Code) on C1 C2 C3 C4 and R1 R2 R3 R4 Lines: 0111 0111 (0x77).
(3) Similarly when we close K21 button, we will get this Scan Code: 0111 1011 (0x7B) = C1 C2 C3 C4 R1 R2 R3 R4.
4. Now we can make the following Table to contain all possible (16) scan codes for the keys of the 4x4 Keypad of Fig-1. we will observe that the scan codes are all different from each other. Therefore, a closed key can uniquely be identified by looking at its scan code.
Logic of C1C2C3C4 Key Closed Label of Key Scan Code (C1C2C3 R1R2R3R4) ASCII Code of Label
0111 K11 1 0111 0111 (0x77) 0x31
0111 K21 4 0111 1011 (0x7B) 0x34
0111 K31 7 0111 1101 (0x7D) 0x37
0111 K41 * 0111 1110 (0x7E) 0x2A
//---------------------------------------------------------------------------------------------------
1011 K12 2 1011 0111 (0xB7) 0x32
1011 K22 5 1011 1011 (0xBB) 0x35
1011 K32 8 1011 1101 (0xBD) 0x38
1011 K42 0 1011 1110 (0xBE) 0x30
//---------------------------------------------------------------------------------------------------
1101 K13 3 1101 0111 (0xD7) 0x33
1101 K23 6 1101 1011 (0xDB) 0x36
1101 K33 9 1101 1101 (0xDD) 0x39
1101 K43 # 1101 1110 (0xDE) 0x23
//---------------------------------------------------------------------------------------------------
1110 K14 A 1110 0111 (0xE7) 0x41
1110 K24 B 1110 1011 (0xEB) 0x42
1110 K34 C 1110 1101 (0xED) 0x43
1110 K45 D 1110 1110 (0xEE) 0x44
//---------------------------------------------------------------------------------------------------
5. Let us execute the following sketch. This sketch will generate scan codes only for the keys of Column-0 (C1). The scan codes will be displayed on Serial Monitor.
void setup()
{
Serial.begin(9600);
for (int i = 4; i < 8; i++)
{
pinMode(i, OUTPUT);
}
for (int i = 8; i < 12; i++) //PB0 - PB3
{
pinMode(i, INPUT_PULLUP);
}
}
void loop()
{
//------------------------------
digitalWrite(7, LOW); //PD7 C1
digitalWrite(6, HIGH); //PD6 C2
digitalWrite(5, HIGH); //PD5 C3
digitalWrite(4, HIGH); //PD4 C4
byte x = (PINB & 0x0F); //R1 R2 R3 R4 PB3 PB2 PB1 PB0
x = (PIND & 0xF0) | x;
//---------------------------------
switch (x)
{
case 0x77:
Serial.println("K11 is closed -- Scan Code: 0x77");
break;
case 0x7B:
Serial.println("K21 is closed -- Scan Code: 0x7B");
break;
case 0x7D:
Serial.println("K31 is closed -- Scan Code: 0x7D");
break;
case 0x7E:
Serial.println("K41 is closed -- Scan Code: 0x7E");
default:
;
break;
}
delay(1000);
}
6. The sketch of Step-5 can be cascaded (expanded) to accommodate the mechanisms of activating the remaining column lines (C2, C3, and C4). The scan codes (and the ASCII codes) of the pressed down keys (and the label of the keys) can be acquired, saved, and displayed. Now, we have a final sketch of tens of lines at a very messy C level.
7. If we are good students of C++/OOP, we can proceed to offer some kind of high level structure to the messy codes of Step-7. I am not very sure about myself who is pre-dominantly a hardware enthusiast (with a little bit of C/C++ Programming Language). What's about you?
8. There is a group of programmers working with Arduino Development Team, who has nicely given fantastic high level abstraction of these messy C codes. We may systematically study their works with reference to the codes of Step-5. Before we do so, we may bring some kinds of modular level functionalities to the codes of Step-5.
(1) Column Scanning
Column lines are activated with LL one at a time. This means that a 0 is walking around the column lines at certain speed. This is known walking 0's keyboard. We activate the column lines; press the key; read the row lines; build the scan code and map it to ASCII code. we can make the following declarations/definitions:
byte ROWS = 4; //4 row lines in the keypad
(a) byte COLS = 4; //4 column lines in the keypad
(b) byte rowPins[] = {11, 10, 9, 8}; //Digital pins of UNO with which row lines (R1R2R3R4) are connected
(c) byte colPins[] = {7, 6, 5, 4}; //Digital pins of UNO with which the col lines (C1C2C3C4) are connected
(d) char hexaKeys[ROWS][COLS] = { //2-dimensional array containing ASCII codes for the labels of keys
{'1', '2', '3', 'A'}'
{'4', '5', '6', 'B'}'
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
(e) The array named hexaKeys can also be declared as 1-dimensional array like this:
char hexaKeys[]= {'0', '1', '2', '3', '4', '5, '6, '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#'};
OR
char hexaKeys[] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x2A, 0x23}; //null-byte (0x00) is automatically inserted by the compiler.
(2) Mapping (transformation) Scan Codes of the pressed down keys into ASCII Codes
When we press a key, the information that we receive is the scan code of that key. For example: after pressing K11, we will receive the scan code 0x77. The artificial label that we have put over K11 is 1; so, what we want is this -- if K11/1 is pressed down, the character/image 1 should appear on Serial Monitor/LCD which are ASCII devices. In order to achieve this goal, the scan code 0x77 must be mapped/transformed into its corresponding ASCII code which is 0x31. This mapping can be done in many ways -- one of the methods is of the use of Lookup Table which says that:
if (scancode == 0x77)
{
ASCII Code is 0x31 and collect it from the Lookup Table -- the char hehaKeys[] = {0x30, ..., 0x23};
}
and etc.
The makeKeymap(hexaKeys) function performs this mapping job.
9. Now, let us study this cryptic/bureaucratic structure: Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
More will be added and finally, we will try to come up to the understanding of the meaning of the following highly abstracted structure:
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);