Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was trying to interface my hex keypad with Arduino. I declared rows as input and columns as output. When I initialize three of the four columns as HIGH and one as LOW, and detect the button pressed as LOW in the corresponding row, it works fine. That is, it detects the button when its corresponding row and column is LOW. But, when I reverse the condition, i.e. when I try to detect the button pressed when its corresponding row and column is high while others are low, it does not work as expected.

I really want to know why is this happening?

The code that works:-

int row[]={6,7,8,9};
int col[]={10,11,12,13};
int i,j; 
int col_scan;
void setup()
{
   Serial.begin(9600);
   for(i=0;i<=3;i++)
   {
      pinMode(row[i],OUTPUT);
      pinMode(col[i],INPUT);
      digitalWrite(col[i],HIGH);
   } }
void loop()
{ 
   for(i=0; i<=3; i++)
   {
      digitalWrite(row[0],HIGH);
      digitalWrite(row[1],HIGH);
      digitalWrite(row[2],HIGH);
      digitalWrite(row[3],HIGH);
      digitalWrite(row[i],LOW);
      for(j=0; j<=3; j++)
      {
     col_scan=digitalRead(col[j]);
     if(col_scan==LOW)
     {
        keypress(i,j);
        delay(300);
     }}
   }}
void keypress(int i, int j)
{
   if(i==0&&j==0)
      Serial.println("1");
   if(i==0&&j==1)
      Serial.println("2");
   if(i==0&&j==2)
      Serial.println("3");
   if(i==0&&j==3)
      Serial.println("A");
   if(i==1&&j==0)
      Serial.println("4");
   if(i==1&&j==1)
      Serial.println("5");
   if(i==1&&j==2)
      Serial.println("6");
   if(i==1&&j==3)
      Serial.println("B");
   if(i==2&&j==0)
      Serial.println("7");
   if(i==2&&j==1)
      Serial.println("8");
   if(i==2&&j==2)
      Serial.println("9");
   if(i==2&&j==3)
      Serial.println("C");
   if(i==3&&j==0)
      Serial.println("*");
   if(i==3&&j==1)
      Serial.println("0");
   if(i==3&&j==2)
      Serial.println("#");
   if(i==3&&j==3)
      Serial.println("D");
}

the code that doesn't work:-

int row[]={6,7,8,9};
int col[]={10,11,12,13};
int i,j; 
int col_scan;
void setup()
{
   Serial.begin(9600);
   for(i=0;i<=3;i++)
   {
      pinMode(row[i],OUTPUT);
      pinMode(col[i],INPUT);
      digitalWrite(col[i],LOW);
   } }
void loop()
{ 
   for(i=0; i<=3; i++)
   {
      digitalWrite(row[0],LOW);
      digitalWrite(row[1],LOW);
      digitalWrite(row[2],LOW);
      digitalWrite(row[3],LOW);
      digitalWrite(row[i],HIGH);
      for(j=0; j<=3; j++)
      {
     col_scan=digitalRead(col[j]);
     if(col_scan==HIGH)
     {
        keypress(i,j);
        delay(300);
     }}
   }}
void keypress(int i, int j)
{
   if(i==0&&j==0)
      Serial.println("1");
   if(i==0&&j==1)
      Serial.println("2");
   if(i==0&&j==2)
      Serial.println("3");
   if(i==0&&j==3)
      Serial.println("A");
   if(i==1&&j==0)
      Serial.println("4");
   if(i==1&&j==1)
      Serial.println("5");
   if(i==1&&j==2)
      Serial.println("6");
   if(i==1&&j==3)
      Serial.println("B");
   if(i==2&&j==0)
      Serial.println("7");
   if(i==2&&j==1)
      Serial.println("8");
   if(i==2&&j==2)
      Serial.println("9");
   if(i==2&&j==3)
      Serial.println("C");
   if(i==3&&j==0)
      Serial.println("*");
   if(i==3&&j==1)
      Serial.println("0");
   if(i==3&&j==2)
      Serial.println("#");
   if(i==3&&j==3)
      Serial.println("D");
}
share|improve this question
    
There could be any number of reasons, but we'd need to see a schematic and some code, or at least the representative parts of each. There's not enough information here to be able to tell. – JRobert Jan 23 '15 at 21:18

To use unipolar switches as inputs, you need pulling resistors to give the input pin a defined value when the switch is open.

The ATmega has software configurable internal pullups. Even if these are not configured, implementation detail may (or may not) yield a very weak unreliable pullup effect.

There is no configurable pulldown on the ATmega. To operate in that direction (with a switch to high) you would need external pulldown resistors.

A few matrix keyboards include diodes, to combat some of the confusion which results when multiple keys are pressed in a simple matrix.

Also, you should add a tiny delay between driving and reading, in order to allow for capacitive delay.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.