Keypad library more than 10 rows

Status
Not open for further replies.

Gimly

New member
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?
 
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.");
    }
  }
}
 
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)
 
Status
Not open for further replies.
Back
Top