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

Thread: Keypad library more than 10 rows

  1. #1
    Junior Member
    Join Date
    Feb 2019
    Posts
    4

    Keypad library more than 10 rows

    I'm trying to make the keypad library to work with more than 11 rows, and it doesn't seem to work.

    Everything works fine if I configure only 10 rows.

    As soon as I put 11 rows, it starts acting weird, multiple key pressed when I push only one and the last row keypress are never registered.

    Can someone help me finding out what's going on?

  2. #2
    No one is telepathic and can't guess you problem. souce code is a MUST if you want help.

  3. #3
    Junior Member
    Join Date
    Feb 2019
    Posts
    4
    Sorry, you're right.

    I'm trying to make a firmware for a split mechanical keyboard using Teensyduino. I'm using the keypad https://github.com/Chris--A/Keypad library (available as a library with Arduino).


    Here's the code that has an issue with the number of rows (it's the right side):

    Code:
    #include <Keypad.h>
    #include <Wire.h>
    
    const byte ROWS = 11;
    const byte COLS = 6;
    const byte I2C_ADDRESS = 8;
    
    char keys[ROWS][COLS] = {
      {'A', 'B', 'C', 'D', 'E', 'F'},
      {'G', 'H', 'I', 'J', 'K', 'L'},
      {'M', 'N', 'O', 'P', 'Q', 'R'},
      {'S', 'T', 'U', 'V', 'W', 'X'},
      {'Y', 'Z', 'a', 'b', 'c', 'd'},
      {'e', 'f', 'g', 'h', 'i', 'j'},
      {'k', 'l', 'm', 'n', 'o', 'p'},
      {'q', 'r', 's', 't', 'u', 'v'},
      {'w', 'x', 'y', 'z', '+', '"'},
      {'*', '[', '%', '&', '/', '('},
      {'A', 'B', 'C', 'D', 'E', 'F'},
    };
    byte colPins[COLS] = {21, 20, 19, 18, 17, 16};
    byte rowPins[ROWS] = { 0, 1, 4, 3, 9, 10, 22, 12, 13, 14, 15};
    
    Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
    
    unsigned long loopCount;
    unsigned long startTime;
    String msg;
    byte keyOr;
    
    void setup() {
      Serial.begin(9600);
        
      Wire.begin();
        
      loopCount = 0;
      startTime = millis();
      msg = "";
    }
    
    void loop() {
      loopCount++;
      if ( (millis()-startTime)>5000 ) {
        Serial.print("Average loops per second = ");
        Serial.println(loopCount/5);
        startTime = millis();
        loopCount = 0;
      }
    
      if (kpd.getKeys())
        {
            for (int i=0; i<LIST_MAX; i++)   // Scan the whole key list.
            {
                char keyPressed = kpd.key[i].kchar;
                int keyCode = kpd.key[i].kcode;
                
                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:
                        Wire.beginTransmission(I2C_ADDRESS);
                        Wire.write(keyCode);
                        Wire.endTransmission();
                        msg = " PRESSED.";
                    break;
                        case HOLD:
                        msg = " HOLD.";
                    break;
                        case RELEASED:
                        Wire.beginTransmission(I2C_ADDRESS);
                        keyOr = keyCode | 0x80;
                        Wire.write(keyOr);
                        Wire.endTransmission();
                        msg = " RELEASED.";
                    break;
                        case IDLE:
                        msg = " IDLE.";
                    }
                    Serial.print("Key ");
                    Serial.print(keyPressed);
                    Serial.println(msg);
                }
            }
        }
    }
    and for completeness, here's the left side:

    Code:
    #include <Keypad.h>
    #include <Wire.h>
    
    //#define KEY_NON_US_BS  (100 | 0xF000)
    //#define KEY_MENU       (101 | 0xF000)
    //#define KEY_FN 1
    
    const byte LEFT_COLS = 7;
    const byte LEFT_ROWS = 6;
    const byte RIGHT_COLS = 11;
    const byte RIGHT_ROWS = 6;
    const int LAYOUT_NBR = 2;
    const byte I2C_ADDRESS = 8;
    
    uint16_t layoutsRight[LAYOUT_NBR][RIGHT_COLS*RIGHT_ROWS]{
      {
        KEY_ESC, KEY_TILDE, KEY_TAB, KEY_CAPS_LOCK, MODIFIERKEY_SHIFT, MODIFIERKEY_CTRL,
        NO_KEY,  KEY_1,     KEY_Q,   KEY_A,         KEY_NON_US_BS,     MODIFIERKEY_GUI,
        KEY_F1,  KEY_2,     KEY_W,   KEY_S,         KEY_Z,             NO_KEY,
        KEY_F2,  KEY_3,     KEY_E,   KEY_D,         KEY_X,             MODIFIERKEY_ALT,
        KEY_F3,  KEY_4,     NO_KEY,  NO_KEY,        KEY_C,             KEY_SPACE,
        KEY_F4,  KEY_5,     KEY_R,   KEY_F,         KEY_V,             NO_KEY,
        NO_KEY,  KEY_6,     KEY_T,   KEY_G,         KEY_B,             NO_KEY
      },
      {
        KEY_ESC, KEY_TILDE, KEY_TAB, KEY_CAPS_LOCK, MODIFIERKEY_SHIFT, MODIFIERKEY_CTRL,
        NO_KEY,  KEY_1,     KEY_Q,   KEY_A,         KEY_NON_US_BS,     MODIFIERKEY_GUI,
        KEY_F1,  KEY_2,     KEY_W,   KEY_S,         KEY_Z,             NO_KEY,
        KEY_F2,  KEY_3,     KEY_E,   KEY_D,         KEY_X,             MODIFIERKEY_ALT,
        KEY_F3,  KEY_4,     NO_KEY,  NO_KEY,        KEY_C,             KEY_SPACE,
        KEY_F4,  KEY_5,     KEY_R,   KEY_F,         KEY_V,             NO_KEY,
        NO_KEY,  KEY_6,     KEY_T,   KEY_G,         KEY_B,             NO_KEY
      }
    };
    
    uint16_t layoutsLeft[LAYOUT_NBR][RIGHT_COLS*RIGHT_ROWS]{
      {
        KEY_F5,          KEY_7,         KEY_Y,           KEY_H,         KEY_N,                   KEY_SPACE,
        KEY_F6,          KEY_8,         KEY_U,           KEY_J,         KEY_M,                   1,
        KEY_F7,          KEY_9,         KEY_I,           KEY_K,         KEY_COMMA,               NO_KEY,
        KEY_F8,          KEY_0,         KEY_O,           KEY_L,         KEY_PERIOD,              MODIFIERKEY_RIGHT_ALT,
        KEY_F9,          KEY_MINUS,     KEY_P,           KEY_SEMICOLON, KEY_SLASH,               MODIFIERKEY_RIGHT_GUI,
        KEY_F10,         KEY_EQUAL,     KEY_LEFT_BRACE,  KEY_QUOTE,     NO_KEY,                  NO_KEY,
        KEY_F11,         KEY_BACKSPACE, KEY_RIGHT_BRACE, KEY_TILDE,     MODIFIERKEY_RIGHT_SHIFT, KEY_MENU,
        KEY_F12,         NO_KEY,        KEY_ENTER,       NO_KEY,        NO_KEY,                  MODIFIERKEY_RIGHT_CTRL,
        KEY_PRINTSCREEN, KEY_INSERT,    KEY_DELETE,      NO_KEY,        NO_KEY,                  KEY_LEFT,
        KEY_SCROLL_LOCK, KEY_HOME,      KEY_END,         NO_KEY,        KEY_UP,                  KEY_DOWN,
        KEY_PAUSE,       KEY_PAGE_UP,   KEY_PAGE_DOWN,   NO_KEY,        NO_KEY,                  KEY_RIGHT
      },
      {
        KEY_F5,          KEY_7,         KEY_Y,           KEY_H,         KEY_N,                   0,
        KEY_F6,          KEY_8,         KEY_U,           KEY_J,         KEY_M,                   KEYPAD_0,
        KEY_F7,          KEY_9,         KEY_I,           KEY_K,         KEY_COMMA,               NO_KEY,
        KEY_F8,          KEY_0,         KEY_O,           KEY_L,         KEY_PERIOD,              KEYPAD_PERIOD,
        KEY_F9,          KEY_MINUS,     KEY_P,           KEY_SEMICOLON, KEY_SLASH,               KEYPAD_ENTER,
        KEY_F10,         KEY_EQUAL,     KEY_LEFT_BRACE,  KEY_QUOTE,     NO_KEY,                  NO_KEY,
        KEY_F11,         KEY_BACKSPACE, KEY_RIGHT_BRACE, KEY_TILDE,     MODIFIERKEY_RIGHT_SHIFT, KEY_MENU,
        KEY_F12,         NO_KEY,        KEY_ENTER,       NO_KEY,        NO_KEY,                  MODIFIERKEY_RIGHT_CTRL,
        KEY_PRINTSCREEN, KEY_INSERT,    KEY_DELETE,      NO_KEY,        NO_KEY,                  KEY_LEFT,
        KEY_SCROLL_LOCK, KEY_HOME,      KEY_END,         NO_KEY,        KEY_UP,                  KEY_DOWN,
        KEY_PAUSE,       KEY_PAGE_UP,   KEY_PAGE_DOWN,   NO_KEY,        NO_KEY,                  KEY_RIGHT
      }
    };
    
    char keys[RIGHT_COLS][RIGHT_ROWS] = {
    {'A', 'B', 'C', 'D', 'E', 'F'},
    {'G', 'H', 'I', 'J', 'K', 'L'},
    {'M', 'N', 'O', 'P', 'Q', 'R'},
    {'S', 'T', 'U', 'V', 'W', 'X'},
    {'Y', 'Z', 'a', 'b', 'c', 'd'},
    {'e', 'f', 'g', 'h', 'i', 'j'},
    {'k', 'l', 'm', 'n', 'o', 'p'}
    };
    byte rowPins[RIGHT_ROWS] = {21, 20, 19, 18, 17, 16};
    byte colPins[RIGHT_COLS] = { 9, 22, 11, 13, 14, 15, 12};
    
    Keypad kpd = Keypad( makeKeymap(keys), colPins, rowPins, RIGHT_COLS, RIGHT_ROWS );
    
    unsigned long loopCount;
    unsigned long startTime;
    String msg;
    byte currentLayout;
    
    void setup() {
        Serial.begin(9600);
        
        Wire.begin(I2C_ADDRESS);
        Wire.onReceive(receiveKey);
        
        loopCount = 0;
        startTime = millis();
        msg = "";
        currentLayout = 0;
    }
    
    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.
            {
                char keyPressed = kpd.key[i].kchar;
                uint16_t keyChar = layoutsRight[currentLayout][kpd.key[i].kcode];
                
                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:
                        Keyboard.press(keyChar);
                        msg = " PRESSED.";
                    break;
                        case HOLD:
                        msg = " HOLD.";
                    break;
                        case RELEASED:
                        Keyboard.release(keyChar);
                        msg = " RELEASED.";
                    break;
                        case IDLE:
                        msg = " IDLE.";
                    }
                    Serial.print("Key ");
                    Serial.print(keyPressed);
                    Serial.println(msg);
                }
            }
        }
    }  // End loop
    
    void receiveKey(int howMany) {
      int x = Wire.read();    // receive byte as an integer
      uint16_t keyChar;
      if(x < 128)
      {
        keyChar = layoutsLeft[currentLayout][x];
        if(keyChar < LAYOUT_NBR){
          Serial.print("Switching layout to");
          Serial.println(keyChar);
          currentLayout = keyChar;
        }
        else {
          Keyboard.press(keyChar);
          Serial.print("Key ");
          Serial.print(x);
          Serial.println(" PRESSED.");
        }
      }
      else
      {
        keyChar = layoutsLeft[currentLayout][x - 128];
        
        if(keyChar > LAYOUT_NBR){  
          Keyboard.release(keyChar);
          Serial.print("Key ");
          Serial.print(x - 128);
          Serial.println(" RELEASED.");
        }
      }
    }

  4. #4
    If you look in keymap.h it is limited to 10 row's. I haven't looked at the source code thoroughly, but maybe you just can increase the value. -)

    #define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns)

  5. #5
    Junior Member
    Join Date
    Feb 2019
    Posts
    4
    Indeed, it works! Thanks!

Posting Permissions

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