Рет қаралды 4,075
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);
}
}