Reading a 4x4 matrix keypad with a single pin on arduino

Hello,
I was wondering if anyone is familiar with this 4X4 keypad tutorial ---> Reading a 4x4 matrix keypad with a single pin without ranging on arduino - YouTube. It's a really neat project and I managed to get it working great to view on the serial monitor whenever a key is pressed. But would anyone here know how to address the individual keys of the keypad in the code to make something happen when say key 9 or key 2 is pressed or any key for that matter? I just can't figure that part out. I've included the code below. Any help from anyone will be much appreciated...
Thanks
jessey

/*
Here’s the video for this 4x4 keypad below:
https://www.youtube.com/watch?v=URO042VrCKU
Schematic here ----> http://imgur.com/fpBat
Code here ----> http://pastebin.com/7aqbptxp
Another one wire example here ----> http://playground.arduino.cc/Code/OneWireKeyPad
*/


String keys="123A456B789C*0#D";
int key;
boolean key_lockout=false;

int a = 0;

/*
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
*/ 

void setup(){
   Serial.begin(9600);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);   
}

/*
|---------------------------------------------------------------------------------------|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|---------void loop---------void loop---------void loop---------void loop---------void loop|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|---------void loop---------void loop---------void loop---------void loop---------void loop|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|---------------------------------------------------------------------------------------|
*/ 

void loop(){
  key=getKeypad();
  if(key!=-1)
      Serial.println(keys[key]);
   delay(10);

// blink an led here...  
  a = a +1;	
  if (a==100) {digitalWrite(LED_BUILTIN, HIGH);} 
  if (a==200) {digitalWrite(LED_BUILTIN, LOW); a = 0;} 
   
}
/*

======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
*/
 
int getKeypad(){
  int ret=-1;
  boolean reset_lockout=false;
  if(analogRead(A0)==0)
    key_lockout=false;
  else if(!key_lockout){
    delay(20);
    ret=15-(log((analogRead(A0)-183.9)/58.24)/0.1623)+0.5;
    key_lockout=true;
  }
  return ret;
}

The schematic creates a table of 16 resistance values that are measured by the analog read

Resistances _______________________Resistance adding in the 1.5K on schematic
........0.......220...480...680
0......0.......220...480....680_______1500__1720__1980__2180
1000..1000..1220..1480.1680______2500__2720__2980__3180
2200..2200..3420..3680.3880______3700__4920__5180__5380
3300..3300..6720..6980.7180______4800__8220__8480__8680

By learning which key produces which values, well the analogread voltages, not the resistances above, you can determine which key is which. (allow a bit of margin for resistor drift and tolerances)

Ignore those values above, I mad a mistake in Excel...
0 220 480 680 1500 1720 1980 2180
1000 1220 1480 1680 2500 2720 2980 3180
2200 2420 2680 2880 3700 3920 4180 4380
3300 3520 3780 3980 4800 5020 5280 5480

A little experimentation with OpenOffice Calc (or Microsoft Excel) reveals that the uncommented function getKeypad() could return a result from 32 down to 8. This is potentially 25 values from a 16 key keypad so you will have to tell us what really happens. I don’t feel like doing the math to calculate what those resistive dividers actually do.

Some of those values are produced only in an extremely narrow range.

You could use a switch/case statement or a series of if/else statements to make use of the result from getKeypad().

The line

if(analogRead(A0)==0)

should probably be

if(analogRead(A0)<184)

but there is no guarantee that the following analogRead(A0) is not going to violate this anyway. I would code getKeypad() differently.

The line

  boolean reset_lockout=false;

does not seem to do anything. I hope that it is eliminated by the compiler.

Using the delay(…) function (delay(10) and delay(20) are present) wastes some of the power of your Arduino.

Thanks MarshaJ847 & vaj4088,

MarshaJ847:
By learning which key produces which values, well the analogread voltages, not the resistances above, you can determine which key is which. (allow a bit of margin for resistor drift and tolerances)

So if I understand this, the code is reading a voltage which changes due to the different resistors values that are being introduced by the various key presses. So the 1.5 Kohm resistor going to ground is forming a voltage divider circuit when connected to the different resistor values introduced by a press of a key switch which delivers a unique voltage for each key?

OK, so what I should do (when I get home tonight) is to check and record with a voltmeter the voltages that are produced for each button press.
Can you give me an example of an if statement to read the analog input voltage that would be suitable for what I need here?
I could probably refine and use a statement like this one below to do what you suggested to “allow a bit of margin for resistor drift and tolerances”
if(analogRead(A0) >= 10 && analogRead(A0) <= 20){} // true if a is between 10 and 20

I guess I could use a LCD to display the voltage value for each key press and use that value in my if statement and have one for each key to check if it’s being pressed. Do you know how I could use the serial display to calculate and display the voltage value for each key press? That would be a big help if I could see how to do that.

Any additional help will be greatly appreciated.
Thanks
jessey

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 5, 4, 3, 2);

void setup()
{
pinMode(8, INPUT_PULLUP);//controll specific pin from here
pinMode(9, INPUT_PULLUP);
}
void loop()
{
int push = digitalRead(8);
int push1 = digitalRead(9);

if (push == LOW)

{
//output area i used lcd to display
lcd.clear();
lcd.begin(16, 0);
lcd.print(“MENU”);
}

if (push1 == LOW)

{
//output area i used lcd to display
lcd.clear();
lcd.begin(16, 0);
lcd.print(“SANDEEP”);//YOU CAN USE AS LED OUTPUT
}}

Well I managed to find an example on how to print to the serial monitor here ----> https://www.arduino.cc/en/Tutorial/AnalogReadSerial and managed to get it up and running, it was just a copy and paste and I didn’t have to change anything. I changed the two delays in the program and it seems to be working good.

I don’t understand why I don’t get an email alert when someone replies to this thread? The check box is clicked that says “Notify me of replies.”

Thanks for your help
jessey

/*
this programs on a Mega using COM8 on PC running 64 bit
Here’s the video for this 4x4 keypad below:
https://www.youtube.com/watch?v=URO042VrCKU
Schematic here ----> http://imgur.com/fpBat
Code here ----> http://pastebin.com/7aqbptxp
another one wire to try sometime ----> http://playground.arduino.cc/Code/OneWireKeyPad
*/


String keys="123A456B789C*0#D";
int key;
boolean key_lockout=false;

//flash led using for loop and delay(1)
int a = 0;
int led_on_time = 100;
int led_off_time = 200;
/*
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
|----------void setup----------void setup----------void setup----------void setup----------|
|void setup----------void setup----------void setup----------void setup----------void setup|
*/ 
void setup(){
   Serial.begin(9600);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);   
}
/*
|------------------------------------------------------------------------------------------|
|---------void loop---------void loop---------void loop---------void loop---------void loop|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|---------void loop---------void loop---------void loop---------void loop---------void loop|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|---------void loop---------void loop---------void loop---------void loop---------void loop|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|---------void loop---------void loop---------void loop---------void loop---------void loop|
|void loop---------void loop---------void loop---------void loop---------void loop---------|
|------------------------------------------------------------------------------------------|
*/ 
void loop(){
	
   for (int i=0; i <= 2000; i++){// check for button press every 10 milliseconds
   if (i==5)
  {
  	key=getKeypad(); i==0;                                       
    if(key!=-1)
    Serial.println(keys[key]);
  }   
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage); // 

  if (voltage >= 4.14 && voltage <= 4.34){led_on_time = 300; 
                     led_off_time = 500; Serial.print("Key # 1 Volts = "); a = 0;} // key 1 = 4.24 volts
  if (voltage >= 3.60 && voltage <= 3.80){led_on_time = 100; 
                     led_off_time = 200; Serial.print("Key # 2 Volts = "); a = 0;} // key 2 = 3.70 volts
  if (voltage >= 3.14 && voltage <= 3.34){ Serial.print("Key # 3 Volts = ");} // key 3 = 3.24 volts
  if (voltage >= 2.82 && voltage <= 3.02){ Serial.print("Key # A Volts = ");} // key A = 2.92 volts  
  if (voltage >= 2.45 && voltage <= 2.65){ Serial.print("Key # 4 Volts = ");} // key 4 = 2.55 volts
  if (voltage >= 2.25 && voltage <= 2.45){ Serial.print("Key # 5 Volts = ");} // key 5 = 2.35 volts
  if (voltage >= 2.05 && voltage <= 2.25){ Serial.print("Key # 6 Volts = ");} // key 6 = 2.15 volts
  if (voltage >= 1.90 && voltage <= 2.10){ Serial.print("Key # B Volts = ");} // key B = 2.00 volts
  if (voltage >= 1.68 && voltage <= 1.83){ Serial.print("Key # 7 Volts = ");} // key 7 = 1.73 volts
  if (voltage >= 1.60 && voltage <= 1.69){ Serial.print("Key # 8 Volts = ");} // key 8 = 1.64 volts
  if (voltage >= 1.50 && voltage <= 1.58){ Serial.print("Key # 9 Volts = ");} // key 9 = 1.54 volts
  if (voltage >= 1.42 && voltage <= 1.50){ Serial.print("Key # C Volts = ");} // key C = 1.46 volts
  if (voltage >= 1.28 && voltage <= 1.38){ Serial.print("Key # * Volts = ");} // key * = 1.33 volts
  if (voltage >= 1.25 && voltage <= 1.31){ Serial.print("Key # 0 Volts = ");} // key 0 = 1.28 volts
  if (voltage >= 1.19 && voltage <= 1.25){ Serial.print("Key # # Volts = ");} // key # = 1.22 volts
  if (voltage >= 1.14 && voltage <= 1.20){ Serial.print("Key # D Volts = ");} // key D = 1.17  volts

  a = a +1;	
  if (a==led_on_time) {digitalWrite(LED_BUILTIN, HIGH);} 
  if (a==led_off_time) {digitalWrite(LED_BUILTIN, LOW); a = 0;}
  delay(1);
  } 
}
/*
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======
*/ 
int getKeypad(){
  int ret=-1;
  boolean reset_lockout=false;
  if(analogRead(A0)==0)
    key_lockout=false;
  else if(!key_lockout){
    delay(1); // this was 20
    ret=15-(log((analogRead(A0)-183.9)/58.24)/0.1623)+0.5;
    key_lockout=true;
  }
  return ret;
}

I forgot to include a wiring diagram for the 4X4 keypad. I made this one myself in powerpoint to make it easier for me to wire mine. Anyway if someone wants to reproduce this then they can either go with the link I provided in the other post or use this one I’m providing here…

Thanks
jessey

check and record with a voltmeter the voltages that are produced for each button press.

You don't care what the actual voltage is. What you need to know is what is returned by analogRead()

Instead of

if(analogRead(A0) >= 10 && analogRead(A0) <= 20){} // true if a is between 10 and 20

I would think that you would want something more like

int keypadValue = analogRead(A0) ;
if(keypadValue  >= 10 && keypadValue <= 20){} // true if the voltage read from the keypad
                                                                  // is between 10 and 20

or even (untested)

int keypadValue = analogRead(A0) ;
int epsilon = 5 ;
if(inRange(15, keypadValue, epsilon)){} // true if the voltage read from the keypad
                                                                  // is between 10 and 20

where

bool inRange(int center, int incoming, int allowed) { return (abs(center-incoming)<=allowed) ; }

This avoids multiple (and possible inconsistent) reads of the keypad, and simplifies the “if” statements.

Hi,
Thanks for getting back to me but did you guys even read my last 2 posts?

UKheliBob - I didn't use a volt meter to get the voltages for the code, have a look at the code I posted. I used the serial monitor to get the voltages. Have a look at what I posted when you get the time...

Vaj4088, Like I said to Bob you have to read what was posted. I'm not using the if statement your commenting about. Please take the time and read the code I'm using...

It looks like you guys are in too much of a hurry

Thanks
Jessey

I didn't use a volt meter to get the voltages for the code, have a look at the code I posted. I used the serial monitor to get the voltages

As I said, you don't need to know the voltage, just the value returned by analogRead().

   ret=15-(log((analogRead(A0)-183.9)/58.24)/0.1623)+0.5;

Lots of time consuming code and magic numbers, but why bother ? The value of ret is based purely on analogRead(A0) so why not use it directly ?

Thanks UKhelibob,
Sorry for the assumption that you didn't read my code but how do I use that line of code. You can see how I'm addressing the keys so how would you do it? Could you give me an example on how to use it? That line of code your using there looks like the line of code that's in the subroutine.
Thanks
Jessey

Posted by jessey - Sep 08, 2016, 01:55 am (in part):

Can you give me an example of an if statement to read the analog input voltage that would be suitable for what I need here?
I could probably refine and use a statement like this one below to do what you suggested to “allow a bit of margin for resistor drift and tolerances”
if(analogRead(A0) >= 10 && analogRead(A0) <= 20){} // true if a is between 10 and 20

My reply was intended to address this question. The replies by UKHeliBob addressed this and more.

Posted by jessey - Sep 08, 2016, 06:57 pm (in part):

It looks like you guys are in too much of a hurry

If ONE person is asking questions and TWO people seem to be in too much of a hurry with their answers,
maybe it is the way that the ONE person asks the questions without attempting to make use of the answers.

We try to lead you into solving your own problems here. If you want a ready-made solution, try the section called “Gigs and Collaborations” and bring your wallet.

how do I use that line of code.

You are already using that line of code in the getKeypad() function.

What I am suggesting is that you simply use
keypadValue = analogRead(A0);then test the value of the keypadValue variable rather than the calculated voltage.

Thanks UKhelibob,
Sorry for the assumption that you didn’t read my code but how do I use that line of code. You can see how I’m addressing the keys so how would you do it? Could you give me an example on how to use it? That line of code your using there looks like the line of code that’s in the subroutine.
Thanks
Jessey

Thanks Bob,
I did finally figure out how to use your example from re-reading the previous posts. Looks like I did have the right way of getting the values I needed (as you suggested in your last post) but I just didn’t know it was the correct way of doing it and that’s why I was asking how to do it and not like vaj4088 suggested, that I was looking for a ready-made solution that possibly needed me to produce my wallet. I’m not a student looking for a quick cheat to get an assignment completed on time, I’m a senior that has a hobby and I thought that is one of the things that arduino was about, having a hobby.

Anyway, I’m sorry if I offended anyone and for that I apologize.
I’m including the code and schematics for anyone that’s interested and wants to reproduce it. I wrote the code to display to a serial LCD and the serial monitor, it also changes the flash rate of an led using Keys 1 and 2 to show it’s working.

Thanks for your help as it was appreciated.
jessey

/*
https://www.arduino.cc/en/Tutorial/ReadAnalogVoltage
this programs on a Mega using COM8 on my home PC running 64 bit
Here’s the video for this 4x4 keypad below:
https://www.youtube.com/watch?v=URO042VrCKU
Schematic here ----> http://imgur.com/fpBat
Code here ----> http://pastebin.com/7aqbptxp
another one wire to try sometime ----> http://playground.arduino.cc/Code/OneWireKeyPad
*/


String keys="123A456B789C*0#D";
int key;
boolean key_lockout=false;

//flash led using for loop and delay(1)
int a = 0;
int led_on_time = 100;
int led_off_time = 200;

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 
#define I2C_ADDR 0x27 // <<- Add your address here.
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define BACKLIGHT_PIN 3
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

/*
|void setup----------void setup----------void setup----------void setup----------void setup|
*/ 
void setup(){
   Serial.begin(9600);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT); 
  
  // LCD Backlight ON in void setup
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);  
  
   lcd.begin(16, 2);//-----------//    
   lcd.setCursor(0, 0);//--------// 
   lcd.print("This Program Is ");// 
   lcd.setCursor(0, 1);//--------//
   lcd.print(" Called MSC.ino ");//  
   delay(4500);//----------------//
   lcd.clear();//----------------//  
}
/*
|---------void loop---------void loop---------void loop---------void loop---------void loop|
*/ 
void loop(){
	
   for (int i=0; i <= 2000; i++){// check for button press every 10 milliseconds
   if (i==1)
  {
  	key=getKeypad(); i==0;                                       
    if(key!=-1)
    Serial.println(keys[key]);
  }   

  int keypadValue = analogRead(A0);
   lcd.setCursor(0, 0);//-------------//keypadValue  
   lcd.print(keypadValue);
   lcd.setCursor(3, 0);
   lcd.print(" Anolog pinA0");//---//  
   lcd.setCursor(0, 1);//-------------//   

///*
// am using key 1 and 2 to change the rate that the led flashes...
  Serial.println(keypadValue);
  if (keypadValue >= 858 && keypadValue <= 878){led_on_time = 300; 
      led_off_time = 500; lcd.print("  Button Pin 1  "); a = 0;}//pin 1 = 868
  if (keypadValue >= 749 && keypadValue <= 769){led_on_time = 100; 
      led_off_time = 200; lcd.print("  Button Pin 2  "); a = 0;}//pin 2 =759
  if (keypadValue >= 653 && keypadValue <= 673){ 
  	                        lcd.print("  Button Pin 3  ");}// 3 = 663  
  if (keypadValue >= 588 && keypadValue <= 608){ 
  	                        lcd.print("  Button Pin A  ");}// A = 598  
  if (keypadValue >= 512 && keypadValue <= 532){ 
  	                        lcd.print("  Button Pin 4  ");}// 4 = 522 
  if (keypadValue >= 470 && keypadValue <= 490){ 
  	                        lcd.print("  Button Pin 5  ");}// 5 = 480 
  if (keypadValue >= 430 && keypadValue <= 450){ 
  	                        lcd.print("  Button Pin 6  ");}// 6 = 440 
  if (keypadValue >= 400 && keypadValue <= 420){ 
  	                        lcd.print("  Button Pin B  ");}// B = 410
  if (keypadValue >= 346 && keypadValue <= 365){ 
  	                        lcd.print("  Button Pin 7  ");}// 7 = 355
  if (keypadValue >= 325 && keypadValue <= 345){ 
  	                        lcd.print("  Button Pin 8  ");}// 8 = 335
  if (keypadValue >= 305 && keypadValue <= 324){ 
  	                        lcd.print("  Button Pin 9  ");}// 9 = 315
  if (keypadValue >= 289 && keypadValue <= 304){ 
  	                        lcd.print("  Button Pin C  ");}// C = 299 
  if (keypadValue >= 267 && keypadValue <= 279){ 
  	                        lcd.print("  Button Pin *  ");}// * = 273 
  if (keypadValue >= 255 && keypadValue <= 266){ 
  	                        lcd.print("  Button Pin 0  ");}// 0 = 261 
  if (keypadValue >= 244 && keypadValue <= 254){ 
  	                        lcd.print("  Button Pin #  ");}// # = 249 
  if (keypadValue >= 233 && keypadValue <= 243){ 
  	                        lcd.print("  Button Pin D  ");}// D = 239
//*/

///*
// I'm printing to the serial monitor here just to show it works...
// also am using key 1 and 2 to change the rate that the led flashes...
  if (keypadValue >= 858 && keypadValue <= 878){led_on_time = 300; 
      led_off_time = 500; Serial.print("Key # 1 keypadValue = "); a = 0;}//pin 1 = 868
  if (keypadValue >= 749 && keypadValue <= 769){led_on_time = 100; 
      led_off_time = 200; Serial.print("Key # 2 keypadValue = "); a = 0;}//pin 2 =759
  if (keypadValue >= 653 && keypadValue <= 673){ 
  	                        Serial.print("Key # 3 keypadValue = ");}// 3 = 663  
  if (keypadValue >= 588 && keypadValue <= 608){ 
  	                        Serial.print("Key # A keypadValue = ");}// A = 598  
  if (keypadValue >= 512 && keypadValue <= 532){ 
  	                        Serial.print("Key # 4 keypadValue = ");}// 4 = 522 
  if (keypadValue >= 470 && keypadValue <= 490){ 
  	                        Serial.print("Key # 5 keypadValue = ");}// 5 = 480 
  if (keypadValue >= 430 && keypadValue <= 450){ 
  	                        Serial.print("Key # 6 keypadValue = ");}// 6 = 440 
  if (keypadValue >= 400 && keypadValue <= 420){ 
  	                        Serial.print("Key # B keypadValue = ");}// B = 410
  if (keypadValue >= 346 && keypadValue <= 365){ 
  	                        Serial.print("Key # 7 keypadValue = ");}// 7 = 355
  if (keypadValue >= 325 && keypadValue <= 345){ 
  	                        Serial.print("Key # 8 keypadValue = ");}// 8 = 335
  if (keypadValue >= 305 && keypadValue <= 324){ 
  	                        Serial.print("Key # 9 keypadValue = ");}// 9 = 315
  if (keypadValue >= 289 && keypadValue <= 304){ 
  	                        Serial.print("Key # C keypadValue = ");}// C = 299 
  if (keypadValue >= 267 && keypadValue <= 279){ 
  	                        Serial.print("Key # * keypadValue = ");}// * = 273 
  if (keypadValue >= 255 && keypadValue <= 266){ 
  	                        Serial.print("Key # 0 keypadValue = ");}// 0 = 261 
  if (keypadValue >= 244 && keypadValue <= 254){ 
  	                        Serial.print("Key # # keypadValue = ");}// # = 249 
  if (keypadValue >= 233 && keypadValue <= 243){ 
  	                        Serial.print("Key # D keypadValue = ");}// D = 239
//*/
  a = a +1;	
  if (a==led_on_time) {digitalWrite(LED_BUILTIN, HIGH);} 
  if (a==led_off_time) {digitalWrite(LED_BUILTIN, LOW); a = 0;}
  delay(1);
  } 
}
/*
======= Subroutine Area ======= Subroutine Area ======= Subroutine Area =======

*/ 
int getKeypad(){
  int ret=-1;
  boolean reset_lockout=false;
  if(analogRead(A0)==0)
    key_lockout=false;
  else if(!key_lockout){
    delay(1); // this was 20
    ret=15-(log((analogRead(A0)-183.9)/58.24)/0.1623)+0.5;
    key_lockout=true;
  }
  return ret;
}

4X4 Keypad wiring.jpg

One Wire Keypad.

http://playground.arduino.cc/Code/OneWireKeyPad#.UyozdvldWSo

Late to the party, but would like to jump in and ask a few questions. For background, I've been anxious to use recently acquired Arduino NANO boards for a variety of projects, but first need to decide on user I/O, AND I didn't want to use up a lot of arduino pins for that I/O! So after some initial grief I've begun to get an I2C based LCD to work for user display output, and am now looking for various keypad panels for input. I certainly didn't want to waste more wires than necessary and thought of looking for maybe a cheap keypad with a built in serial output. But when i saw this 0ne-wire analog method, it really made me smile. Kudos to the folks who came up with this. The principal seems fairly easy to understand and code for.

My big question however is how difficult it is to recognize and ignore "fat finger" errors, as would happen if a user hit two or 3 keys on a pad at once. I suppose the problem could be somewhat simplified if you consider that there is a limit to the number of multiple key combinations that could occur, and a further limit to the number of errant combinations that could produce an input that could mistakenly by seen as valid. What experience has everyone had with this?

PeterPan321:
My big question however is how difficult it is to recognize and ignore "fat finger" errors, as would happen if a user hit two or 3 keys on a pad at once. I suppose the problem could be somewhat simplified if you consider that there is a limit to the number of multiple key combinations that could occur, and a further limit to the number of errant combinations that could produce an input that could mistakenly by seen as valid. What experience has everyone had with this?

That all depends on the context. You need to give the fat fingered person immediate feedback on what they entered. Your project should have some display showing the key and accept only valid keys. If they meant to press "5" and your program thinks they entered "8", the 8 should show immediately, so they know of the error.

Paul

Paul_KD7HB:
That all depends on the context. You need to give the fat fingered person immediate feedback on what they entered. Your project should have some display showing the key and accept only valid keys. If they meant to press "5" and your program thinks they entered "8", the 8 should show immediately, so they know of the error.

Paul

Oh yes, of course I'd do that. I just wondered how innately immune the circuit is to double key hits. I guess I'll find that out when I build one, but I was curious what others have found. And if it is subject to some errors, whether certain variations of resistors, maybe some filtering mods (like adding a capacitor to the A/D input) or tightening of the "valid" ranges would help.

PeterPan321:
Oh yes, of course I'd do that. I just wondered how innately immune the circuit is to double key hits. I guess I'll find that out when I build one, but I was curious what others have found. And if it is subject to some errors, whether certain variations of resistors, maybe some filtering mods (like adding a capacitor to the A/D input) or tightening of the "valid" ranges would help.

I used the code in an example that selects each key based on a small range of values. There are no values that don't relate to a key. So makes no difference how many keys are pressed, only one key will be returned and like you did, it is displayed. If not what was intended, they can press "reset" and start over.

Paul