Go Down

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

tavovalencia

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.

tavovalencia

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?

tavovalencia

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