/* Code Lock with Elegant Keypad
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.
ATtiny85, 8MHz
PB5 =|1 U 8|= VCC
PB3 =|2 7|=2--> SCL
PB4 =|3 6|= PB1
GND =|4 5|=0--> SDA
*/
//#include "Servo8bit.h" // Or use Relay code
//Servo8Bit myServo;
char password[] = "1234"; // Define your password here
char enteredCode[5];
byte index = 0;
const int green = PB0; // Relay or Servo control pin
const int red = PB2;
const int debounceTime = 160;
const int rowPins[4] = {PB1, PB3, PB4, PB5}; // 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() {
//myServo.attach(lock);
pinMode(green, OUTPUT);
digitalWrite(green, LOW); // Locked
pinMode(red, OUTPUT);
digitalWrite(red, HIGH); // Locked
// Initialize all pins as inputs with pull-ups
for (int i = 0; i < 4; i++) {
pinMode(rowPins[i], INPUT_PULLUP);
}
delay(1000);
}
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];
if (key) {
enteredCode[index] = key;
index++;
//Serial.print(key);
}
if (index == 4) {
if (strcmp(enteredCode, password) == 0) {
//Serial.println(" - Correct");
digitalWrite(green, HIGH); // Unlock
digitalWrite(red, LOW);
delay(5000); // Wait 5 seconds
digitalWrite(green, LOW); // Lock
digitalWrite(red, HIGH);
} else {
for (int i = 0; i < 10; i++) {
digitalWrite(red, LOW);
delay(500);
digitalWrite(red, HIGH);
delay(500);
}
}
index = 0;
memset(enteredCode, 0, sizeof(enteredCode)); // Clear entry
}
delay(debounceTime); // debounce
}
}
pinMode(rowPins[active], INPUT_PULLUP); // Reset active pin to input
}
}