Keypad multiple key press problem

I am using Keypad library to build a musical MIDI keyboard using salvaged keyboard keys.
The matrix is 6 rows x 8 columns, with keymap as follow:

To test it, I used MultiKey.ino from keypad library examples.

/* @file MultiKey.ino
|| @version 1.0
|| @author Mark Stanley
|| @contact mstanley@technologist.com
||
|| @description
|| | The latest version, 3.0, of the keypad library supports up to 10
|| | active keys all being pressed at the same time. This sketch is an
|| | example of how you can get multiple key presses from a keypad or
|| | keyboard.
|| #
*/

#include <Keypad.h>

const byte ROWS = 6; //four rows
const byte COLS = 8; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','4','5','6','7','8'}, 
  {'9','0','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'}
};
byte rowPins[ROWS] = {A3,A2,A1,A0,15,14}; //connect to the row pinouts of the kpd
byte colPins[COLS] = {2,3,4,5,6,7,8,9}; //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 = "";
}


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);
            }
        }
    }
}  // End looptype or paste code here

In general, all went well (incl. multi key press) except one thing:

  • when I pressed 'E' and '2' simultaneously, 'F' is also unintentionally registered as 'pressed'.
  • when I pressed 'F' and '3' simultaneously, '2' and 'G' is also unintentionally registered as 'pressed'.
  • etc.. with the problem keys indicated in red color in above sketch.

Serial output is as follow:
Average loops per second = 130797
Average loops per second = 130783
Key 1 PRESSED.
Key 9 PRESSED.
Average loops per second = 130797
Key 1 HOLD.
Key 9 HOLD.
Key 1 RELEASED.
Key 1 IDLE.
Key 9 RELEASED.
Key 9 IDLE.
Key 2 PRESSED.
Key E PRESSED.
Key F PRESSED.
Key 2 HOLD.
Key E HOLD.
Key F HOLD.
Key 2 RELEASED.
Key E RELEASED.
Key F RELEASED.
Key 2 IDLE.
Key E IDLE.
Key F IDLE.
Average loops per second = 130802
Key F PRESSED.
Key 2 PRESSED.
Key 3 PRESSED.
Key G PRESSED.
Key F HOLD.
Key 2 HOLD.
Key 3 HOLD.
Key G HOLD.
Average loops per second = 130779
Key 2 RELEASED.
Key 3 RELEASED.
Key F RELEASED.
Key 2 IDLE.
Key 3 IDLE.
Key G RELEASED.
Key F IDLE.
Key G IDLE.
Average loops per second = 130796
Average loops per second = 130799


Each key on the keyboard has diode. I've checked the diodes, all seems normal.

Please help to overcome this problem. Thanks.

Please post the schematic. Have you verified that all the diodes are functional, and the right way around?

1 Like

www.google.com/search?q=how+to+prevent+ghosting+keys

1 Like

I think the wiring goes like this:

Board is Pro Micro (Leonardo).
Resistors are 4K7 (I used external, array resistors).

As for the diodes, I cannot identify them, but here's the photo:

For every key where you get anomalous results (ghosting) you need to check the appropriate diodes for proper function and orientation.

With the diodes in that orientation, I would expect the pullups to be along the columns, not the rows. Like so:

It seems that the KeyPad library drives the columns low and reads from the rows, so you would have to transpose the entire thing (just swap the row and column pins in your code).

upper connector has 7 pins, lower has 8 pins. do you know why?

I think it's possible. I will try to install the pullup-resistors to the columns instead. Thanks

The keyboard has 49 keys. After scanning the matrix, I've found that it has 8 columns and 7 rows. However, row no 7 connects to only 1 key of the keyboard. So to simplify, I neglect the 7th row, and hence, use only 48 keys of the keyboard.

Yes I have. The orientation and the voltage of each diode is the same as the rest. Thanks

I have switch the pull-up resistors from rows to columns.
Using the same code, I had similar result.

The Serial Output is:

Average loops per second = 130781
Key E PRESSED.
Key E RELEASED.
Key E IDLE.
Key 2 PRESSED.
Key 2 RELEASED.
Key 2 IDLE.
E and 2 pressed together :

Key 2 PRESSED.
Key E PRESSED.
Key 2 HOLD.
Key E HOLD.
Key 2 RELEASED.
Key 2 IDLE.
Key E RELEASED.
Key E IDLE.
--> normal behaviour

Key F PRESSED.
Key F RELEASED.
Key F IDLE.
Key 3 PRESSED.
Key 3 RELEASED.
Key 3 IDLE.

F and 3 pressed together :

Key F PRESSED.
Key 2 PRESSED.
Key 3 PRESSED.
Key G PRESSED.
Key F HOLD.
Key 2 HOLD.
Key 3 HOLD.
Key G HOLD.
Average loops per second = 130797
Key G RELEASED.
Key 2 RELEASED.
Key 3 RELEASED.
Key G IDLE.
Key F RELEASED.
Key 2 IDLE.
Key 3 IDLE.
Key F IDLE.
Key G PRESSED.
Key G RELEASED.
Key G IDLE.
--> 2 and G are included unwantedly

Key G PRESSED.
Key G RELEASED.
Key G IDLE.
Key 4 PRESSED.
Key 4 RELEASED.
Key 4 IDLE.

G and 4 pressed together :

Key 4 PRESSED.
Key 4 RELEASED.
Key 4 IDLE.
Key 4 PRESSED.
Key 3 PRESSED.
Key G PRESSED.
Key H PRESSED.
Key 4 HOLD.
Key 3 HOLD.
Key G HOLD.
Key H HOLD.
Average loops per second = 130839
Key 4 RELEASED.
Key 3 RELEASED.
Key H RELEASED.
Key 4 IDLE.
Key 3 IDLE.
Key G RELEASED.
Key H IDLE.
Key G IDLE.
--> 3 and H are included unwantedly

Key H PRESSED.
Key H RELEASED.
Key H IDLE.
Key 5 PRESSED.
Key 5 RELEASED.
Key 5 IDLE.
Average loops per second = 130780

H and 5 pressed together :

Key H PRESSED.
Key 4 PRESSED.
Key 5 PRESSED.
Key I PRESSED.
Key H HOLD.
Key 4 HOLD.
Key 5 HOLD.
Key I HOLD.
Key 4 RELEASED.
Key I RELEASED.
Key H RELEASED.
Key 4 IDLE.
Key 5 RELEASED.
Key I IDLE.
Key H IDLE.
Key 5 IDLE.
--> 4 and I are included unwantedly

Key I PRESSED.
Key I RELEASED.
Key I IDLE.
Key 6 PRESSED.
Average loops per second = 130777
Key 6 RELEASED.
Key 6 IDLE.

I and 6 pressed together :

Key 5 PRESSED.
Key 6 PRESSED.
Key I PRESSED.
Key J PRESSED.
Key 5 HOLD.
Key 6 HOLD.
Key I HOLD.
Key J HOLD.
Key 5 RELEASED.
Key I RELEASED.
Key J RELEASED.
Key 5 IDLE.
Key 6 RELEASED.
Key I IDLE.
Key J IDLE.
Key 6 IDLE.
--> 5 and J are included unwantedly

Key J PRESSED.
Key J RELEASED.
Key J IDLE.
Key 7 PRESSED.
Key 7 RELEASED.
Key 7 IDLE.
Average loops per second = 130736

J and 7 pressed together :

Key J PRESSED.
Key 6 PRESSED.
Key 7 PRESSED.
Key K PRESSED.
Key J HOLD.
Key 6 HOLD.
Key 7 HOLD.
Key K HOLD.
Key 6 RELEASED.
Key K RELEASED.
Key 6 IDLE.
Key 7 RELEASED.
Key K IDLE.
Key J RELEASED.
Key 7 IDLE.
Key J IDLE.
--> 6 and K are included unwantedly

Key K PRESSED.
Key K RELEASED.
Key K IDLE.
Key 8 PRESSED.
Key 8 RELEASED.
Key 8 IDLE.
Key 8 PRESSED.

K and 8 pressed together :

Key K PRESSED.
Key L PRESSED.
Key 7 PRESSED.
Key 8 HOLD.
Key K HOLD.
Key L HOLD.
Key 7 HOLD.
Average loops per second = 130768
Key 7 RELEASED.
Key K RELEASED.
Key L RELEASED.
Key 7 IDLE.
Key 8 RELEASED.
Key K IDLE.
Key L IDLE.
Key 8 IDLE.
--> L is included unwantedly

you should not use pull-up resistors at all

Did you try this?

Yes I have tried this. If I transpose rows become columns and vice versa, it won't work.
No key-pressed recognized at all.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.