How to turn 4x4 keypad into one wire analog signal and how to make this design robust?

  Рет қаралды 4,075

insaneinvader

insaneinvader

Күн бұрын

I suppose you know the "TIP #7 4x4 Keyboard with 1 Input" described in the "Compiled Tips ‘N Tricks Guide" from Microchip ww1.microchip.c... But what are those "carefully selected resistor values"? This video shows how to select the resistor values. Moreover, I wrote a trial-and-error program that found the best resistors values:
best ratio; Rpu; Rr; Rc
0,017969; 4220; 1200; 316 "the best"
0,0179669; 4020; 1200; 316
0,017956; 3000; 910; 240 "the best of E24 series"
0,0179545; 2050; 560; 147
0,0179522; 2000; 560; 147
0,0179521; 3010; 910; 240
0,0179502; 1210; 330; 86,6
0,0179501; 1200; 330; 86,6
0,0179462; 1960; 560; 147
0,0179451; 1100; 300; 78,7
0,0179435; 2150; 560; 147
0,0179422; 5110; 1600; 422
0,0179402; 1150; 330; 86,6 "good enough"
I advise you to use the following resistors tolerances (or better): 0.1% Rpu, 1% Rr, 1% Rc. The ADC range assigned to a particular button depends on the selected resistors and the selected ADC resolution:
If the selected resistors are
Rpu: 4.22k, 0.1%
Rr: 1.2k, 1%
Rc: 316, 1%
Or
Rpu: 42.2k, 0.1%
Rr: 12k, 1%
Rc: 3.16k, 1%
Then the 10-bit ADC ranges are
541 522
522 503
503 482
482 462
462 441
441 415
415 386
386 358
358 328
328 290
290 249
249 207
207 161
161 102
102 36
36 -1
(...>=val) && (val>...)
If the selected resistors are
Rpu: 3k, 0.1%
Rr: 910, 1%
Rc: 240, 1%
Or
Rpu: 30k, 0.1%
Rr: 9.1k, 1%
Rc: 2.4k, 1%
Then the 10-bit ADC ranges are
559 539
539 519
519 499
499 479
479 457
457 431
431 402
402 374
374 342
342 304
304 261
261 218
218 170
170 109
109 38
38 -1
(...>=val) && (val>...)
Example source code for Arduino:
// *************************************
// ** (C) 2016 by insaneinvader **
// *************************************
char buf[128]; // text buffer
char keyChanged; // 1 if keypad state has changed
char keyPressed; // which key is pressed now
// the ADC threshold values works only with the following resistors:
// Rpu = 3 kOhm, 0.1%
// Rr = 910 Ohm, 1%
// Rc = 240 Ohm, 1%
// and only with 10-bit ADC
const int threshold[16+1] = {
559, 539, 519, 499, 479, 457, 431, 402, 374, 342, 304, 261, 218, 170, 109, 38, -1
};
void setup() {
analogReference(DEFAULT);
Serial.begin(115200);
Serial.println("Hello!");
}
void loop() {
int avg, reservep, reserven;
//
keyChanged = 0;
//
static unsigned long sum;
static unsigned int cnt;
sum += analogRead(0); // accumulate analog reads
cnt++;
if(cnt == 64) {
avg = sum / cnt; // calc average of many analog measurements
sum = 0;
cnt = 0;
//
keyPressed = 0;
int i;
for(i = 0; i < 16; i++) { // find which key is pressed
if((threshold[i+0] >= avg) && (avg > threshold[i+1])) {
reservep = threshold[i+0] - avg;
reserven = avg - threshold[i+1] - 1;
keyPressed = i + 1;
break;
}
}
//
static char keyOld;
static unsigned int keyConfirm;
if(keyOld == keyPressed) { // filter
if(keyConfirm) {
keyConfirm--;
} else {
//
static int keyPrev;
if(keyPrev != keyPressed) { // change detection
if(keyPrev) keyPressed = 0; // keep correct sequence
keyPrev = keyPressed;
keyChanged = 1;
}
}
} else {
keyConfirm = 3 -1; // how many times the same key needs to be confirmed
keyOld = keyPressed;
}
}
//
if(keyChanged) {
char keyLabel = ' ';
switch(keyPressed) {
case 1: keyLabel = '1'; break;
case 2: keyLabel = '2'; break;
case 3: keyLabel = '3'; break;
case 4: keyLabel = 'A'; break;
case 5: keyLabel = '4'; break;
case 6: keyLabel = '5'; break;
case 7: keyLabel = '6'; break;
case 8: keyLabel = 'B'; break;
case 9: keyLabel = '7'; break;
case 10: keyLabel = '8'; break;
case 11: keyLabel = '9'; break;
case 12: keyLabel = 'C'; break;
case 13: keyLabel = '*'; break;
case 14: keyLabel = '0'; break;
case 15: keyLabel = '#'; break;
case 16: keyLabel = 'D'; break;
}
if(keyPressed) sprintf(buf,
"key = '%c' #%i, avg = %i (+%i -%i)",
keyLabel, keyPressed, avg, reservep, reserven);
else sprintf(buf, ".
");
Serial.print(buf);
}
}

Пікірлер: 7
@KangJangkrik
@KangJangkrik 5 жыл бұрын
Well... That's more complicated than I thought :/
@franciscocasas2082
@franciscocasas2082 7 жыл бұрын
Have you ever thought to develop a library for arduino with your code?, it's better that another existing libraries, because it don't trow fake keys, Congrats again.
@franciscocasas2082
@franciscocasas2082 6 жыл бұрын
it's me again, with a doubt. I need to implement long press functions do you have any code to implement some like that? Regards
@InsaneInvader
@InsaneInvader 6 жыл бұрын
Hi! Unfortunately no code for that but I think it is something like that: while(1) // system main loop { delay(1); // wait 1ms if(key_state != key_state_old) // detect the change { if(key_state == 1) // detect the key is pressed { timeout = 100; // start the timeout counting } else // the key is released { timeout = 0; // stop time counting } } key_state_old = key_state; // remember it for future usage if(timeout) // timeout counting in progress { timeout--; // time goes down if(time == 0) // finished { on_key_held_down(); // the key was constantly pressed for 100 * 1ms } } } However it looks like a code for debouncing... Hope you come out with your own solution!
@franciscocasas2082
@franciscocasas2082 7 жыл бұрын
Congrats, good design, if I can try with a STM32 wich is 3.3v analog in, I'll need to do any modifications? or just with the built in analog reference is sufficient?
@InsaneInvader
@InsaneInvader 7 жыл бұрын
You can use any MCU running at any voltage. Just use the same voltage Vin for the keyboard and for the ADC's Vref (literaly the same, Vin connected to Vref) - it makes the reference voltage accuracy not important at all.
How to use 5x4 20 keys keypad  with Arduino detect String
10:05
Please Help This Poor Boy 🙏
00:40
Alan Chikin Chow
Рет қаралды 23 МЛН
Как мы играем в игры 😂
00:20
МЯТНАЯ ФАНТА
Рет қаралды 3,3 МЛН
Which One Is The Best - From Small To Giant #katebrush #shorts
00:17
Björk - I miss you (Live 1997)
3:59
insaneinvader
Рет қаралды 352 М.
Negative Time is Real, Physicists Confirm. Kind Of.
6:59
Sabine Hossenfelder
Рет қаралды 50 М.
Genuine & Fake  - Kingston 64GB Micro SD Cards
1:47
insaneinvader
Рет қаралды 106 М.
Single phase motor wiring with 2 capacity-reverse and forward
4:30
Please Help This Poor Boy 🙏
00:40
Alan Chikin Chow
Рет қаралды 23 МЛН