Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: Keyboard matrix behaves differently based on choice of row pins

  1. #1
    Senior Member
    Join Date
    Oct 2019
    Posts
    178

    Keyboard matrix behaves differently based on choice of row pins

    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?

  2. #2
    Senior Member
    Join Date
    Dec 2016
    Location
    Wales
    Posts
    122
    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?

  3. #3
    Senior Member
    Join Date
    Oct 2019
    Posts
    178
    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[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);
    * ** ** ** *}
    * ** ** }
    * * }
    }

  4. #4
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Can you fix the malformed code and use code tags please - no easy way to copy/paste that....

  5. #5
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    416
    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 by BriComp; 07-27-2021 at 11:55 AM.

  6. #6
    Senior Member
    Join Date
    Dec 2016
    Location
    Wales
    Posts
    122
    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

  7. #7
    Senior Member
    Join Date
    Oct 2019
    Posts
    178
    I removed the pin config lines and it doesn't change behavior. I'm running out of diagnostics looking for the short...

  8. #8
    Senior Member
    Join Date
    Oct 2019
    Posts
    178
    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.

  9. #9
    Senior Member
    Join Date
    Oct 2019
    Posts
    178
    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?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •