-
Notifications
You must be signed in to change notification settings - Fork 0
Membrane Keypad
Fritz Mahnke edited this page Apr 30, 2024
·
1 revision
The keypad can be read using a single analog single by wiring it with a voltage divider network:

Here's a working example. It's based on the above circuit, with a few modifications.
/*
# Circuit details
Resistor values (ohms):
Row 0: 0
Row 1: 820
Row 2: 1800
Row 3: 2700
Column 0: 0
Column 1: 220
Column 2: 470
Column 3: 680
To ground: 2700
Diodes: 1.7V LEDs
# Data
All values following were returned by the Arduino analogRead function.
These are the values as a matrix. Viewing it this way was useful for
determining the best resistor values.
680 / 0/820/1800/2700 : 0x21A, 0x1D3, 0x1A3, 0x186
470 / 0/820/1800/2700 : 0x237, 0x1E4, 0x1AD, 0x18D
220 / 0/820/1800/2700 : 0x25F, 0x1F8, 0x1B9, 0x195
0 / 0/820/1800/2700 : 0x287, 0x20D, 0x1C4, 0x19C
# Conversion to C char
Most examples use a series of if/else statements to convert the input value to
the corresponding character. The following example instead uses switch
statements, shifting away the bits we don't care about and then comparing the
result against the following table.
Whether or not this approach produces smaller code than the equivalent if/else
series is subject to a test.
Values (key, hex, binary, binary don't care, hex don't care):
1: 0x287 0b1010000111 0b1010xxxxxx 0x280
2: 0x25F 0b1001011111 0b1001xxxxxx 0x240
3: 0x237 0b1000110111 0b100011xxxx 0x230
A: 0x21A 0b1000011010 0b100001xxxx 0x210
4: 0x20D 0b1000001101 0b100000xxxx 0x200
5: 0x1F8 0b0111111000 0b011111xxxx 0x1F0
6: 0x1E4 0b0111100100 0b011110xxxx 0x1E0
B: 0x1D3 0b0111010011 0b011101xxxx 0x1D0
7: 0x1C4 0b0111000100 0b011100xxxx 0x1C0
8: 0x1B9 0b0110111001 0b011011xxxx 0x1B0
9: 0x1AD 0b0110101101 0b0110101xxx 0x1A8
C: 0x1A3 0b0110100011 0b0110100xxx 0x1A0
*: 0x19C 0b0110011100 0b0110011xxx 0x198
0: 0x195 0b0110010101 0b0110010xxx 0x190
#: 0x18D 0b0110001101 0b01100011xx 0x18C
D: 0x186 0b0110000110 0b01100001xx 0x184
No value: 0xF7 0b11110111
*/
#include <Arduino.h>
void setup() {
Serial.begin(115200);
}
void loop() {
int val = analogRead(A5);
char result = 0;
switch (val >> 2) {
case 0b1100011:
result = '#';
break;
case 0b1100001:
result = 'D';
break;
default:
switch (val >> 3) {
case 0b110010:
result = '0';
break;
case 0b110011:
result = '*';
break;
case 0b110100:
result = 'C';
break;
case 0b110101:
result = '9';
break;
default:
switch (val >> 4) {
case 0b11011:
result = '8';
break;
case 0b11100:
result = '7';
break;
case 0b11101:
result = 'B';
break;
case 0b11110:
result = '6';
break;
case 0b11111:
result = '5';
break;
case 0b100000:
result = '4';
break;
case 0b100001:
result = 'A';
break;
case 0b100011:
result = '3';
break;
default:
switch (val >> 6) {
case 0b1001:
result = '2';
break;
case 0b1010:
result = '1';
break;
default:
break;
}
}
}
}
bool have_input = (val & 0b1100000000) != 0;
if (have_input) {
Serial.print("input value: ");
Serial.print(val, 16);
Serial.print(", char: ");
if (!result) {
Serial.println("none");
} else {
Serial.println(result);
}
}
delay(200);
}