Keypad 4x4

Hello I am new to Arduino. I wrote this code to read a 4x4 keypad and it works. However, it needs improvement. I think the problem is with the delays. If you press the key for too long, it repeats on the screen. I would like to have the key only display one time no matter how long you hold the button down. Does anyone have any suggestions?

#include <Keypad.h>
int key(void);
void banner(void);
void compare(int hit);
int testColumn (void);
int debounce(int hit);
void setup() 
{
    Serial.begin(9600);//sets baud rate for serial communication
    banner();
    for (int a=6; a<=9; a++)//sets coulmn pins 6 through 9 as high inputs
    {
      pinMode(a, INPUT);//columns are inputs
      digitalWrite(a, HIGH);
    }//end for a
    for (int b=2; b<=5; b++)//sets row pins 2 through 5 as high outputs
    {
      pinMode(b, OUTPUT);//rows are outputs
      digitalWrite(b, HIGH);
    }//end for b
}//end setup
 
void loop() 
{
  int hit=0;//declares and initializes hit variable
  hit=key();//sets hit value to that returned by key function, calls key
  //Serial.print("hit = ");//used for debugging
  //Serial.println(hit);//used for debugging
  if (hit < 16)//if one of the 16 keys are hit, call compare function
  {
    debounce(hit);
    delay(100);
  }//end if
  //delay(20);
}//end loop
int debounce(int hit)//recalls key, creates new vaiable for comparison
{
  int hitd=0;//new variable for comparing
  hitd=key();//variable set equal to the value returned by key
  delay(100);
  if (hitd==hit)//checks validity
  {
    compare(hit);//send the value to be printed
    delay(100);
  }//end if
}//end debounce
int key(void)//tests for keypad entry
{
  int column=0;//declares and initializes column variable
  for(int c=2; c<=5; c++)//pulls each row low
  {
    digitalWrite(c, LOW);//pull row low
    column=testColumn();//sets column value to that returned from testColumn
    digitalWrite(c, HIGH);//resets row to high for next iteration
    if (column!=16)//testing for keypad hit
    {
      c-=2;//math determines value of row for the iteration
      //Serial.print("row=");//used for debugging
      //Serial.println(row);//used for debugging
      //Serial.println(c);//used for debugging
      //delay(500);//used for debugging
      return(column*4+c);//uses row to determine column, returns column number
    }//end if 
  }//end for c
  return 16;//return any number higher than 15--needs to be invalid
}//end key
int testColumn (void)//detects low column, returns column number for print
{
  for(int d=6; d<=9; d++)//if column is low, return column number
  {
    //Serial.print("d=");//used for debugging
    //Serial.println(d);//used for debugging
    if(digitalRead(d)==LOW)
    {
      return d-6;//math determines column number
    }//end if read for low
  }//end for d
 return 16;//return any number higher than 15--needs to be invalid
}//end testColumn

void compare (int hit)//prints key 
{
  switch (hit)//decodes hit value for keypad entry
  {
    case 0://0,0 from binary 1(count from low right, up)
      Serial.println("Keypad = D");break;
    case 1://0,1
       Serial.println("Keypad = #");break;
    case 2://0,2
      Serial.println("Keypad = 0");break;
    case 3://0,4
      Serial.println("Keypad = *");break;
    case 4://1,0
      Serial.println("Keypad = C");break;
    case 5://1,1
      Serial.println("Keypad = 9");break;
    case 6://1,2
      Serial.println("Keypad = 8");break;
    case 7://1,3
      Serial.println("Keypad = 7");break;
    case 8://2,0
      Serial.println("Keypad = B");break;
    case 9://2,1
      Serial.println("Keypad = 6");break;
    case 10://2,2
      Serial.println("Keypad = 5");break;
    case 11://2,3
      Serial.println("Keypad = 4");break;
    case 12://3,0
      Serial.println("Keypad = A");break;
    case 13://3,1
      Serial.println("Keypad = 3");break;
    case 14://3,2
      Serial.println("Keypad = 2");break;
    case 15://3,3
      Serial.println("Keypad = 1");break;
    default:
      fflush(stdin);
  }//end switch
}//end compare

void banner(void)
{
  Serial.println("sissieface");
  Serial.println("ET 240");
  Serial.println("10/23/14");
  Serial.println("Arduino Keypad");
}

Check for a key press, and save it in a holding variable called something like lastKey. Then read the keypad again and see if the new key press is different from lastKey. If the new keypress is different from the lastKey, print the key pressed otherwise dont.

Example:

void loop()
{
  myKey = myKeypad.getKey();
  
  if(myKey != lastKey)
  {
    if(myKey != NO_KEY)
    {
      Serial.println(myKey)
    }
    lastKey = myKey;
  }
}

Then read the keypad again and see if the new key press is different from lastKey.

Only acknowledge a key change when a valid key press is detected AND when and only when the key is released process the valid key change.

Looking at your code you seem to be making quite a meal of reading that keyboard. I've downloaded a copy of keypad.h and find there's quite a decent example in there.

Modifying it to fit in with your pins and keypad layout, style of reporting and attempting the non repeat idea you have, I've come up with this.

#include <Keypad.h>
const byte numRows= 4; //number of rows on the keypad
const byte numCols= 4; //number of columns on the keypad
//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols]=
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {2,3,4,5}; //Rows 0 to 3
byte colPins[numCols]=  {6,7,8,9}; //Columns 0 to 3

//initializes an instance of the Keypad class
Keypad ourKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup()
{
  Serial.begin(9600);
  Serial.begin(9600);//sets baud rate for serial communication
  banner();
}
char lastKey=0; 
void loop() 
{
  char key = ourKeypad.getKey();

  if ( (key!=0) && (key!=lastKey) )
  {
    Serial.print ("keypad = ");
    Serial.println(key);
    delay(400);//add a bit of debounce
  }
  lastKey=key;
}

void banner(void)
{
  Serial.println("sissieface");
  Serial.println("ET 240");
  Serial.println("10/23/14");
  Serial.println("Arduino Keypad");
}

I've never used this library before and have no way of testing it, but it's worth a shot.

Wow thank you so much, KenF, that worked really well! The keys don't repeat at all and it is so much cleaner now! I am going to modify this and keep adding to it!