/* Elegant Keypad extendable to Keyboard
Details at:
https://www.instructables.com/An-Elegant-Keypad-Extendable-to-Keyboard/
Github repository:
https://github.com/QuteNZ/An-Elegant-Keypad-extendable-to-Keyboard.git
and Demo Video:
https://youtu.be/oLSrkSVk7Mg
===============================================
A typical keypad uses matrix configuration for microcontroller.
C1 C2 C3
| | |
R1 ---1, 2, 3
R2 ---4, 5, 6
R3 ---7, 8, 9
R4 ---*, 0, #
in which, total IOs taken are number of Rows plus number of Columes.
For a 4X3 matrix keypad, number of IOs can be reduced with 4 diodes as configured below:
C1 C2 C3 C4
| | | |
R1 --- 1/ | 2/ | 3/ | --cDa-- |
R2 --- 4/ | 5/ | --cDa-- | 6/ |
R3 --- 7/ | --cDa-- | 8/ | 9/ |
R4 ---cDa--| star/ | 0/ | #/ |
Then the 4x3 matrix was transformed to 4x4 one with diodes between Row & Column.
The software can recongnise a key press by appling a voltage to each row in turn
while observing the state of the remainning port pin, which are configured as inputs.
*/
//#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//PCF8574 I2C chip,use I2C_Scanner if address is unkown, 0x27 for mine
LiquidCrystal_I2C lcd(0x27, 16, 2); //0x3F for Simulation
const int debounceTime = 160;
const int rowPins[4] = {4, 5, 6, 7}; // Shared row/column pins by diode
char key;
const char keymap[4][4] = { //D for 1N4048 Diode
{'1', '2', '3', 'D'} ,
{'4', '5', 'D', '6'} ,
{'7', 'D', '8', '9'} ,
{'D', '*', '0', '#'}
};
void setup() {
//Serial.begin(9600);
lcd.init(); //TinkerCad use init()
//lcd.begin();
lcd.print(" Elegant Keypad");
lcd.setCursor(0,1);
// Initialize all pins as inputs with pull-ups
for (int i = 0; i < 4; i++) {
pinMode(rowPins[i], INPUT_PULLUP);
}
//Serial.println("ready!");
}
void loop() {
for (int active = 0; active < 4; active++) {
// Set one pin as OUTPUT HIGH
pinMode(rowPins[active], OUTPUT);
digitalWrite(rowPins[active], LOW);
// Check other pins for HIGH signal
for (int i = 0; i < 4; i++) {
if (i == active) continue; //Skip the output itself
pinMode(rowPins[i], INPUT_PULLUP);
if (digitalRead(rowPins[i]) == LOW) {
delay(debounceTime);
while (digitalRead(rowPins[i]) == LOW)
; //Waiting for key release
key = keymap[i][3-active];
lcd.print(key);
//Serial.print("Key Pressed: ");
//Serial.print(key);
delay(debounceTime); // debounce
}
}
pinMode(rowPins[active], INPUT_PULLUP); // Reset active pin to input
}
}