Go Down

Topic: Troubleshooting a 4x4 16 keys keypad [solved] (Read 2446 times) previous topic - next topic

Jan 31, 2013, 02:22 pm Last Edit: Feb 01, 2013, 12:33 pm by tavovalencia Reason: 1
Hello community, I come here because I'm not quite sure if I'm doing something wrong or if there is something wrong with my hardware. Here's the deal:

1. I have connected as directed per tutorial a 4x4 keypad to an arduino leonardo using the following code:
Code: [Select]
#include <Keypad.h>

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
// Define the Keymap
char keys[ROWS][COLS] = {
 {'1','2','3','A'},
 {'4','5','6','B'},
 {'7','8','9','C'},
 {'*','0','#','D'},
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 6, 8, 7, 9 };
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 2, 5, 4, 3 };

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
 Serial.begin(9600);
}

void loop()
{
 char key = kpd.getKey();
 if(key)  // Check for a valid key.
 {
   Serial.println(key);
   }
}


It works quite ok, but some keys are not read by the Arduino when the're hit.

  • Keys that don't work: 2, 3, A & 4, 7, *.

  • All rest work and show accordingly

  • All col OR row have at least 1 key working OK



What am i missing here?

CrossRoads

#1
Jan 31, 2013, 04:03 pm Last Edit: Feb 01, 2013, 05:08 pm by CrossRoads Reason: 1
Sounds like a bdy [edit: bad] keypad.
If you use a jumper wire and connect the two pins that make up any keypress, can you see all the characters?

For example, put a jumper wire on 6, and touch it to 2,5,4,3, then 7 and 2,5,4,3, then 8 and 2,5,4,3, then 9 and 2,5,4,3.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Hey CrossRoads,

what's a bdy ? a typo or abbreviation for...

If I jump pin 6 with the other pins, I get all the keys that are missing on ROW0 (2,3,A) without pressing the keypad.
Also if I jump 2 with the rest, I get all the missing keys in COL0 (4,7,*) without pressing the keypad.

What should I do?

After all it wasn't a hardware problem, I believe that with my keypad there's a need to include some pull-up resistors. I actually figure this out after changing my scope. As I wouldn't be able to use as many I/O pins anyways, I connected the keypad via I2C with a PCF8574AN (As instructed) with the http://playground.arduino.cc/Main/I2CPortExpanderAndKeypads library and the modifications suggested by PaulS here: http://arduino.cc/forum/index.php/topic,102018.0.html (5th post).

superdmp1978

I was able to connect a pad directly to the digital pins on my mega. Below is the code I used.

Happy coding :)

Code: [Select]
int row[4] = {36,34,32,30};  // from left to right, the first four connections
int col[4] = {28,26,24,22};  // from left to right, the next four connections
int results[4][4] = {{1,2,3,-2},{4,5,6,-3},{7,8,9,-4},{-6,0,-7,-5}};  // This is the array to match up the keystroke with the associated value
                                                                      // I use the special keys as function keys, so I want to capture those strokes.

void setup()
{
  for (int x=0;x<4;x++)  {
  pinMode(row[x],OUTPUT);          //  I assign the rows as output
  pinMode(col[x],INPUT_PULLUP);    //  I assign the columns as inputs and use the internal pullup (probably not necessary, but I did it anyway)
  digitalWrite(row[x],HIGH);       //  I cycle through and set up the entire row index as high.
  }
  Serial.begin(38400);             //  This is used just to debug. Make sure you test all the keys, as it is easy to plug things into the wrong pin.
}

int keyboard_read() {              //  This is the meaty function to scan the keypad
 int value = -1;                   //  I set -1 as my null value, as I want to be able to receive back a zero key-stroke
  for (int x=0;x<4;x++)  {
    digitalWrite(row[x],LOW);      //  I set the active row as low
    delay(5);                      //  I put the delay in, because I want to be sure the full row is pulled low, again probably not necessary
    for (int y=0;y<4;y++)  {
       if (digitalRead(col[y]) == LOW) {  //  As I cycle through, the key pressed will be the one that returns a low signal
         delay(250);                      //  I know I'm cheating, but I just put a delay in after a key-stroke to make sure there is time to let the key up before the next read
         value=results[x][y];      //  After reading which row and column was pressed, I pull the associated value from the key array.
       }
  }
  digitalWrite(row[x],HIGH);       //  Don't forget to set the row back to high, so the next row read is correct.
 }
return(value);                     //  The function then returns the value read, or the default -1 if no key was pressed
}


void loop()
{
  int key_stroke;                 
  key_stroke=keyboard_read();
if (key_stroke != -1)  {              //  Yes, I could have read the function straight in, but because of where I put the delay on a key-press
 Serial.println(String(key_stroke));  //  I would often have the if statement trigger, only to read the board again and return the no-key -1 value
}
}
Just another electron addict

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy