Multiple key hold

I have a Arduino Micro using keypad.h to create a custom gaming keypad array. and keyboard.h
All the buttons work great can click between they send all keys as intended. A few keys need to be held down at times. The keys emulating W (move Forward) A (move left) S (Move Back) D (Move right) and space (Jump/swimup) mainly. I can hold down one key and it will repeat as intended.
W for example will move forward until released. If I click and hold W then A in sequence it will move forward but will move left as if i clicked A one time W still keeps moving forward. If i repeat the A click while still holding W the A will no longer register. Any key click down will register one time as a single click untill the original hold key is released.

Every key has a diode on the row side connection if this info is needed.

Also we can deal with this later

My code might have extra items in, this is my first project using an Arduino or of this type at all. I have been trying to understand what works with trial and error of the original multi key example and many posts I have read through. In the project there are LED on each key that turn on when plugged in listed in the code so that is intended to to be there but its not finished (will deal with getting that setting it to only being on for duration after a key is clicked)

[code]
/* @file MultiKey.ino
  || @version 1.0
  || @author Mark Stanley
  || @contact mstanley@technologist.com
  ||
  || @description
  || | The latest version, 3.0, of the kpd 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 kpd or
  || | keyboard.
  || #
*/

#include <Keypad.h>
#include <Keyboard.h>
int led = 4;
const int ROW_NUM = 6; //four rows
const int COLUMN_NUM = 7; //four columns

char keys[ROW_NUM][COLUMN_NUM] = {
  {'.', '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', '.', '.', '.', '1', '2'},
  {'.', '3', '.', '.', '.', '4', '5'}
};

byte pin_rows[ROW_NUM] = {A0, A1,  A2, A3, A4, A5}; //connect to the row pinouts of the kpd
byte pin_column[COLUMN_NUM] = {6, 7, 8, 9, 10, 11, 12}; //connect to the column pinouts of the kpd

Keypad kpd = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

unsigned long loopCount;
unsigned long startTime;
String msg;


void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  loopCount = 0;
  startTime = millis();
  msg = "";
}


void loop() {
  digitalWrite(led, HIGH);
  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.";
        }
        if (kpd.getState() == PRESSED) {
          if (kpd.isPressed('A')) {
            Keyboard.press(KEY_LEFT_SHIFT);
            Keyboard.press('1');

          }

          if (kpd.isPressed('B')) {
            Keyboard.press(KEY_LEFT_SHIFT);
            Keyboard.press('2');

          }

          if (kpd.isPressed('C')) {
            Keyboard.press(KEY_LEFT_SHIFT);
            Keyboard.press('3');

          }

          if (kpd.isPressed('D')) {
            Keyboard.press(KEY_LEFT_SHIFT);
            Keyboard.press('4');

          }

          if (kpd.isPressed('E')) {
            Keyboard.press(KEY_LEFT_SHIFT);
            Keyboard.press('5');

          }

          if (kpd.isPressed('F')) {
            Keyboard.press(KEY_LEFT_SHIFT);
            Keyboard.press('6');

          }

          if (kpd.isPressed('G')) {
            Keyboard.press('1');

          }

          if (kpd.isPressed('H')) {
            Keyboard.press('2');

          }

          if (kpd.isPressed('I')) {
            Keyboard.press('3');

          }

          if (kpd.isPressed('J')) {
            Keyboard.press('4');

          }

          if (kpd.isPressed('K')) {
            Keyboard.press('5');

          }

          if (kpd.isPressed('L')) {
            Keyboard.press('6');

          }

          if (kpd.isPressed('M')) {
            Keyboard.press('u');

          }

          if (kpd.isPressed('N')) {
            Keyboard.press('8');


          }
          if (kpd.isPressed('O')) {
            Keyboard.press('q');

          }
          if (kpd.isPressed('P')) {
            Keyboard.press('w');

          }
          if (kpd.isPressed('Q')) {
            Keyboard.press('e');

          }
          if (kpd.isPressed('R')) {
            Keyboard.press('r');

          }

          if (kpd.isPressed('S')) {
            Keyboard.press('7');

          }

          if (kpd.isPressed('T')) {
            Keyboard.press('9');

          }
          if (kpd.isPressed('U')) {
            Keyboard.press('a');
          }
          if (kpd.isPressed('V')) {
            Keyboard.press('s');
          }
          if (kpd.isPressed('W')) {
            Keyboard.press('d');
          }
          if (kpd.isPressed('X')) {
            Keyboard.press('f');

          }

          if (kpd.isPressed('Y')) {
            Keyboard.press('g');

          }

          if (kpd.isPressed('Z')) {
            Keyboard.press('0');

          }

          if (kpd.isPressed('1')) {
            Keyboard.press('y');

          }

          if (kpd.isPressed('2')) {
            Keyboard.press('b');


          }

          if (kpd.isPressed('3')) {
            Keyboard.press('-');

          }

          if (kpd.isPressed('4')) {
            Keyboard.press('=');

          }

          if (kpd.isPressed('5')) {
            Keyboard.press(' ');
          }
        }
        if (kpd.getState() == IDLE) {

          Keyboard.releaseAll();

        }
      }
    }
  }
}  // End loop

[/code]

        if (kpd.getState() == IDLE) {

          Keyboard.releaseAll();

        }

Whenever any key goes from RELEASED to IDLE, release all of the keys? That doesn't sound right.

Why are you having your keypad generate A through Z and 1 through 5 and then spending a lot of time changing each one to a different character?!? You can put your characters in the keypad. If you use "!@#$%^" instead of "ABCDEF" for the first row, you don't have to force the shift key after translating ABCDEF to 123456.

char keys[ROW_NUM][COLUMN_NUM] =
{
  {'.', '!', '@', '#', '

Then you can use the character directly from the keypad:

Keyboard.press(kpd.key[i].kchar);

, '%', '^'},
  {'.', '1', '2', '3', '4', '5', '6'},
  {'u', '8', 'q', 'w', 'e', 'r', '7'},
  {'.', '9', 'a', 's', 'd', 'f', 'g'},
  {'.', '0', '.', '.', '.', 'y', 'b'},
  {'.', '-', '.', '.', '.', '=', ' '}
};


Then you can use the character directly from the keypad:

§DISCOURSE_HOISTED_CODE_2§

Will give this a try tonight . This makes more sense then translating the keys.

With the current I have the release all due to without it the keyboard.press will go crazy and keep the key repeating until release or release all. Will try without this as well with the new code

Thank You

zirkon:
With the current I have the release all due to without it the keyboard.press will go crazy and keep the key repeating until release or release all. Will try without this as well with the new code

You get PRESSED and RELEASED events for each key of the keypad. If the keypad is already producing the right character codes you just need to pass those character codes to the Keyboard:

  // 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 key events: PRESSED or RELEASED
        {
          case PRESSED:
            Keyboard.press(kpd.key[i].kchar);
            break;
            
          case RELEASED:
            Keyboard.release(kpd.key[i].kchar);
            break;
        }
      }
    }
  }

Ok got to alter and test the code
It works GREAT!
Thank you!

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