keypad 12 rows x 4 columns only works with 10 rows

This is a matrix-keypad 12 rows x 4 columns made out of 3 4x4 keypads, the hardware is all working fine. A Sparfun Pro Micro board is been used.
Initially I wrote a code for 12 rows and 4 collumns but that didn't work. I can only make things work with a 10 rows code. This working 10-rows code is shown below:

#include <Keypad.h>
#include <MIDIUSB.h>

const byte ROWS = 10; // number of rows (add 2 more for 12 rows)
const byte COLS = 4; // number of columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'a','b','c','d'},
  {'e','f','g','h'},
  {'i','j','k','l'},
  {'m','n','o','p'},  
  {'1','2','3','4'},
  {'5','6','7','8'},
  {'9','0','X','Y'},
  {'A','B','C','D'},
  {'E','F','G','H'},
  {'I','J','K','L'}
  //   {'M','N','O','P'}    : add for two more rows
  //   {'Q','R','S','T'}  
};

byte rowPins[ROWS] = { 6, 7, 8, 9, 10, 16, 14, 15, 2, 3 };  // add pin 4 and 5 for 12 rows
byte colPins[COLS] = { 21, 20, 19, 18 }; 
 
// Create the Keypad

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

  void noteOn(byte channel, byte pitch, byte velocity) {
    midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOn);
    }
  void noteOff(byte channel, byte pitch, byte velocity) {
    midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOff);
    }

void setup() 
{
 Serial.begin(115200);
}

void loop(){
    char key = keypad.getKey();  //read key
      
    if (key){
      
      Serial.println(key);
        noteOn(0, (key), 127);   
        MidiUSB.flush();
            delay(10);
      
        noteOff(0, (key), 127);  
        MidiUSB.flush();
            delay(10);
  }
}

With 12 rows code a continuous sort of loop occurs. No way a keypress is detected, instead it prints millions of "Q" (row 12 column 1) .

I guess it has something to do with my code. I'm new to programming Arduino. Any help would be very much appreciated!

I am having the exact same problem. The only difference is I made a custom PCB that has a 14 x 4 matrix. Did you by chance find a solution?

Please post your code

Which Arduino board ?
Are you using the Arduino pin associated with the built in LED by any chance ?

To get more than 10 rows you have to edit Keypad.h and change this line:

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

If you have 16 or fewer rows and 10 or fewer columns you could just swap them. Call the rows columns and the columns rows.

johnwasser:
To get more than 10 rows you have to edit Keypad.h and change this line:

Editing the .h file worked. Thank you so much.

I am using an arduino pro micro. I have a 4x14 matrix of keys. I could not get it to work by simply flipping the rows and columns though. I would get no output no matter where I flipped the rows and columns. Could you explain what you mean.

Below is my current working code after editing the .h file. This code did not work beforehand. I should note I have diodes on each key so I am not sure if based on the way its wired it I have to represent my keypad as a 14x4 rather than the 4x14 that it actually is. Flipping things around yields no output

#include <Keyboard.h>
#include <Keypad.h>

/////////////////////////////// Pin Setup //////////////////////////////

const byte ROWS = 14;
const byte COLS = 4; 

byte rowPins[ROWS] =  {21,20,19,18,15,14,16,6,5,4,3,2,0,1}; //cant get these t work
byte colPins[COLS] =  {7,8,9,10};


//////////////////////////// Define keypad /////////////////////////////

char keys1[ROWS][COLS] = {
{'/','q','w','e'},
{'r','t','/','/'},
{'y','u','i','o'},
{'p','/','*','a'},
{'s','d','f','g'},
{'*','*','h','j'},
{'k','l',';','*'},
{'-','z','x','c'},
{'v','b',' ',' '},
{'n','m',',','.'},
{'/','-','+','1'},
{'2','3','4','5'},
{'+','+','6','7'},
{'8','9','0','+'}

};                 

Keypad kpd1 = Keypad( makeKeymap(keys1), rowPins, colPins, ROWS, COLS);

///// Initialize ///////////////////////////////////////////////////////
void setup(){
  Serial.begin(9600);    
}

///// Main Loop ////////////////////////////////////////////////////////
void loop(){
  

  char customKey = kpd1.getKey();
  
  if (customKey){
    Serial.println(customKey);
  }

}

//

It's probably the diodes. You would have to reverse all of them. :slight_smile:

Much easier to edit Keypad.h.

I tried the easy way since I will not use more than 12 rows, so I swapped ROWS and COLS to solve the problem. Also I changed char keys[ROWS][COLS] from characters to MIDI note numbers, in my case ranging from 26 to 73.
This worked fine. For use with my DAW I have a controller X-touch One. That controller only has a few buttons to program, so I made this 4x12 controller to operate alongside the X-Touch One. It's really great to have it now all finally working.

Thanks JohnWasser! You supply digital nutrients amongst the needy! :slight_smile:

Pim

Final code (on a SparkfunMicro), including debounce:

#include <Keypad.h>
#include <MIDIUSB.h>

const byte ROWS = 4; 
const byte COLS = 12;
 
// Keymap
char keys[ROWS][COLS] = {
  { 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 66, 70 },
  { 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71 },
  { 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72 },
  { 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73 } 
};

// Connect keypad to Arduino pins.
byte rowPins[ROWS] = { 21, 20, 19, 18 };
byte colPins[COLS] = { 6, 7, 8, 9, 10, 16, 14, 15, 2, 3, 4, 5 }; 
 
// Create Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.begin(115200);
}

 const unsigned long debounceTime = 25;

void loop(){
    char key = kpd.getKey(); 
      
    if (key){
      
      Serial.println(key);
        noteOn(0, (key), 127);   
        MidiUSB.flush();
            delay(10);
      
        noteOff(0, (key), 127);  
        MidiUSB.flush();
            delay(10);
  }
}