Keyboard matrix behaves differently based on choice of row pins

Status
Not open for further replies.

kdharbert

Well-known member
I have a keyboard matrix that is 4 columns and 6 rows. On first test, I had two columns where pressing keys activated two different keys on the column. I couldn't find any wiring issues, so I changed what pin the malfunctioning column uses...and got different behavior. I found a pin where one of the broken columns works properly, but trial and error hasn't yielded a pin where the final column behaves properly. The behavior is reproducible, so either I have a broken unit or there are differences in the pins...?

I'm using keypad.h. I know there are pin-dependent aspects of timer usage detailed here:
https://www.pjrc.com/teensy/td_pulse.html

...but I can't see anything that would explain what I'm seeing. Any ideas?
 
You've not really given enough information, if you post your code and a schematic someone might be able to help. I'm also not entirely sure of the error you're seeing, are you finding that the key presses trigger a different output than the one you expect?
 
Here's code and more data:

The problem is with row 1:

Using pin 4,27,26,24:*
'4' comes through ok.
3 does 3 and four
2 does 1 and two.
1 does 2 and 3.

Using pin 25,
3 and 4 behave properly.
2 does 1 and two.
1 does 2 and 3.

Using pin 12.
4 behaves properly.
3 does 3 and four
2 gives 1*
1 does 2 and 3.



#include <Keypad.h>

const byte ROWS = 6;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','4'},
{'5','6','7','8'},
{'a','b','c','d'},
{'e','f','g','h'},
{'i','j','k','l'},
{'m','n','o','p'}
};
//byte rowPins[ROWS] = {6,7,8,9}; //connect to the row pinouts of the kpd
//byte colPins[COLS] = {0,1,2,3,4,5}; //connect to the column pinouts of the kpd

byte colPins[COLS] = {7,8,0,1}; //connect to the row pinouts of the kpd
byte rowPins[ROWS] = {12,11,28,29,30,31}; //connect to the column pinouts of the kpd


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

unsigned long loopCount;
unsigned long startTime;
String msg;


void setup() {
* * Serial.begin(9600);
* * loopCount = 0;
* * startTime = millis();
* * msg = "";


* * for(int i=0;i<COLS;i++){
* ** *pinMode(colPins,OUTPUT);
* ** *digitalWriteFast(colPins,HIGH);
* * }
* * for(int i=0;i<ROWS;i++){
* ** *pinMode(rowPins,INPUT_PULLUP);
* * }
* * //test
* * //digitalWriteFast(colPins[0],LOW);
* *
}

void loop() {
* * loopCount++;
* * if ( (millis()-startTime)>5000 ) {
* ** ** Serial.print("Average loops per second = ");
* ** ** Serial.println(loopCount/5);
* ** ** startTime = millis();
* ** ** loopCount = 0;
* * }

* * // Fills kpd.key[ ] array with up-to 10 active keys.
* * // Returns true if there are ANY active keys.
* * if (kpd.getKeys())
* * {
* ** ** for (int i=0; i<LIST_MAX; i++)* *// Scan the whole key list.
* ** ** {
* ** ** ** *if ( kpd.key.stateChanged )* *// Only find keys that have changed state.
* ** ** ** *{
* ** ** ** ** * switch (kpd.key.kstate) {* // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
* ** ** ** ** ** ** case PRESSED:
* ** ** ** ** ** ** msg = " PRESSED.";
* ** ** ** ** * break;
* ** ** ** ** ** ** case HOLD:
* ** ** ** ** ** ** msg = " HOLD.";
* ** ** ** ** * break;
* ** ** ** ** ** ** case RELEASED:
* ** ** ** ** ** ** msg = " RELEASED.";
* ** ** ** ** * break;
* ** ** ** ** ** ** case IDLE:
* ** ** ** ** ** ** msg = " IDLE.";
* ** ** ** ** * }
* ** ** ** ** * Serial.print("Key ");
* ** ** ** ** * Serial.print(kpd.key.kchar);
* ** ** ** ** * Serial.println(msg);
* ** ** ** *}
* ** ** }
* * }
}
 
Can you fix the malformed code and use code tags please - no easy way to copy/paste that....
 
Code:
#include <Keypad.h>

const byte ROWS = 6;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','4'},
{'5','6','7','8'},
{'a','b','c','d'},
{'e','f','g','h'},
{'i','j','k','l'},
{'m','n','o','p'}
};
//byte rowPins[ROWS] = {6,7,8,9}; //connect to the row pinouts of the kpd
//byte colPins[COLS] = {0,1,2,3,4,5}; //connect to the column pinouts of the kpd

byte colPins[COLS] = {7,8,0,1}; //connect to the row pinouts of the kpd
byte rowPins[ROWS] = {12,11,28,29,30,31}; //connect to the column pinouts of the kpd


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

unsigned long loopCount;
unsigned long startTime;
String msg;


void setup() {

      Serial.begin(9600);
      loopCount = 0;
      startTime = millis();
      msg = "";


      for(int i=0;i<COLS;i++){
          pinMode(colPins[i],OUTPUT);
          digitalWriteFast(colPins[i],HIGH);
      }
      for(int i=0;i<ROWS;i++){
           pinMode(rowPins[i],INPUT_PULLUP);
      }
      //test
      //digitalWriteFast(colPins[0],LOW);

}

void loop() {
      loopCount++;
      if ( (millis()-startTime)>5000 ) {
           Serial.print("Average loops per second = ");
           Serial.println(loopCount/5);
           startTime = millis();
           loopCount = 0;
      }

      // Fills kpd.key[ ] array with up-to 10 active keys.
      // Returns true if there are ANY active keys.
      if (kpd.getKeys())
      {
           for (int i=0; i<LIST_MAX; i++)       // Scan the whole key list.
          {
               if ( kpd.key[i].stateChanged )     // Only find keys that have changed state.
              {
                  switch (kpd.key[i].kstate) {    // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
                       case PRESSED:
                            msg = " PRESSED.";
                            break;
                        case HOLD:
                             msg = " HOLD.";
                             break;
                        case RELEASED:
                             msg = " RELEASED.";
                             break;
                        case IDLE:
                             msg = " IDLE.";
                  }
                  Serial.print("Key ");
                  Serial.print(kpd.key[i].kchar);
                 Serial.println(msg);
          }
      }
   }
}
Just done it for him
 
Last edited:
it looks like you've derived your code from the example file multikey, which is fine, but I don't understand the use of lines 35-41 where you define the columns as outputs and the rows as input pullups. I would think that this is probably being undone by the internal code to keypad.h which would redefine these as it needs, but I'd still get rid of these lines as they might cause issues.

Beyond that, I would suspect a hardware fault. It would seem most likely to me that the pins are getting shorted somewhere producing the extra keys
 
I removed the pin config lines and it doesn't change behavior. I'm running out of diagnostics looking for the short...
 
Ok, so it just got weirder. I swapped the pins IN CODE for rows 1 and 2. The physical row that failed before now works, and the physical row for the previously working row 2, now fails the same way row one did. Unless, I'm mistaken, there need not be any physical\code ordering of the rows and columns...is there more in the scanning code that I'm not taking into account.
 
It appears that the multikey press code is causing the funny behavior. I used the customkeypad example and it didn't mess up the way multikey did.

I didn't put the rows or column pins in any order with respect to the wiring. Is there any chance the multi key press code is scanning in some order to enable that?
 
Status
Not open for further replies.
Back
Top