how to detect long, dobule press in a button matrix

// mutantC keyboard v2.2.3

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

int led = 10;
int power = 16;
const byte ROWS = 5;
const byte COLS = 11;
bool state = 0;

char hexaAlphabets[ROWS][COLS] = {
  {'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' '},
  {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_LEFT_ARROW},
  {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW },
  {KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE  },
  {KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN  }
};

char hexaSymbols[ROWS][COLS] = {
  {'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' '},
  {KEY_ESC, '!', '@', '#', '

at " // poweroff the device" line i want to do is if the button is hold for 2 seconds then it “power” pin to low.
But i can’t find a way to do that in a matrix keypad.

here is the actual project with that keyboardhere, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, KEY_LEFT_ARROW},
  {KEY_TAB, ‘|’, KEY_UP_ARROW , ‘_’, ‘~’, ‘:’, ‘;’, ‘"’, ‘’’, ‘`’, KEY_RIGHT_ARROW},
  {KEY_CAPS_LOCK, ‘E’ , KEY_DOWN_ARROW, ‘E’, ‘[’, ‘]’,’{’, ‘}’, ‘<’, ‘>’,  KEY_BACKSPACE},
  {KEY_LEFT_CTRL, KEY_LEFT_GUI, ‘+’, ‘-’, ‘/’, ‘*’, ‘=’, ‘,’, ‘.’, ‘?’, KEY_RETURN}
};

byte rowPins[ROWS] = {A2, 15, 0, 1, A3};
byte colPins[COLS] = {14, A0, 9, 8, 7, 6, 5, 4, 3, 2, A1};

Keypad Alphabets  = Keypad(makeKeymap(hexaAlphabets), rowPins, colPins, ROWS, COLS);
Keypad Symbols    = Keypad(makeKeymap(hexaSymbols), rowPins, colPins, ROWS, COLS);

void setup(){
  //reduce the clock to 1/4
  noInterrupts();
  CLKPR = 0x80;  // enable change of the clock prescaler
  CLKPR = 0x02;  // divide frequency by 2
  interrupts();
 
  pinMode(led, OUTPUT);
  pinMode(power, OUTPUT);
 
  delay(50);
  digitalWrite(power, HIGH);
}

void loop() {
  char key;
  if (state == 0) {  // print the keys
    key = Alphabets.getKey();
  } else {
    key = Symbols.getKey();
  }

Keyboard.begin();
  if (key) {
    if (key != ‘\’ && key != ‘O’) {
      Keyboard.write(key);
      delay(50);
    }

if (key == ‘O’) {  // poweroff the device
      digitalWrite(led, HIGH);
      delay(250);
      digitalWrite(led, LOW);
      delay(250);
      digitalWrite(led, HIGH);
      delay(250);
      digitalWrite(power, LOW);
    }
   
    if (key == ‘\’ && state) { // change the layout and led
      digitalWrite(led, LOW);
      state = 0;
    } else if (key == ‘\’ && !state) {
      digitalWrite(led, HIGH);
      state = 1;
    }
  }
  Keyboard.end();
}
[/code]

at " // poweroff the device" line i want to do is if the button is hold for 2 seconds then it “power” pin to low.
But i can’t find a way to do that in a matrix keypad.

here is the actual project with that keyboardhere

checke the examples ---> EventKeypad/EventKeypad.ino you'll see you can capture, PRESS, RELEASE or HOLD state.

--> note the time upon press, note the time upon release, the difference is how long it was pressed. use that in your logic to decide if you switch off or not

came up with this
not working

// mutantC keyboard v2.2.3

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

int led = 10;
int power = 16;

unsigned long releseTime = 0; 
unsigned long pressTime = 0; 

const byte ROWS = 5;
const byte COLS = 11;
bool state = 0;

char hexaAlphabets[ROWS][COLS] = {
  {'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' '},
  {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_LEFT_ARROW},
  {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW },
  {KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE  },
  {KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN  }
};

char hexaSymbols[ROWS][COLS] = {
  {'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' '},
  {KEY_ESC, '!', '@', '#', '

, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, KEY_LEFT_ARROW},
  {KEY_TAB, ‘|’, KEY_UP_ARROW , ‘_’, ‘~’, ‘:’, ‘;’, ‘"’, ‘’’, ‘`’, KEY_RIGHT_ARROW},
  {KEY_CAPS_LOCK, ‘E’ , KEY_DOWN_ARROW, ‘E’, ‘[’, ‘]’,’{’, ‘}’, ‘<’, ‘>’,  KEY_BACKSPACE},
  {KEY_LEFT_CTRL, KEY_LEFT_GUI, ‘+’, ‘-’, ‘/’, ‘*’, ‘=’, ‘,’, ‘.’, ‘?’, KEY_RETURN}
};

byte rowPins[ROWS] = {A2, 15, 0, 1, A3};
byte colPins[COLS] = {14, A0, 9, 8, 7, 6, 5, 4, 3, 2, A1};

Keypad Alphabets  = Keypad(makeKeymap(hexaAlphabets), rowPins, colPins, ROWS, COLS);
Keypad Symbols    = Keypad(makeKeymap(hexaSymbols), rowPins, colPins, ROWS, COLS);

void setup(){
  //reduce the clock to 1/4
  noInterrupts();
  CLKPR = 0x80;  // enable change of the clock prescaler
  CLKPR = 0x02;  // divide frequency by 2
  interrupts();
 
  pinMode(led, OUTPUT);
  pinMode(power, OUTPUT);
 
  digitalWrite(power, HIGH);

Alphabets.addEventListener(keypadEvent); // Add an event listener for this keypad
  Symbols.addEventListener(keypadEvent); // Add an event listener for this keypad
}

void loop() {
  char key;
  if (state == 0) {  // print the keys
    key = Alphabets.getKey();
  } else {
    key = Symbols.getKey();
  }

Keyboard.begin();
  if (key) {
    if (key != ‘\’ && key != ‘O’) {
      Keyboard.write(key);
      delay(50);
    }

if ((releseTime - pressTime) > 750) {  // poweroff the device
      digitalWrite(led, HIGH);
      delay(250);
      digitalWrite(led, LOW);
      delay(250);
      digitalWrite(led, HIGH);
      delay(250);
      digitalWrite(power, LOW);
    }
   
    if (key == ‘\’ && state) { // change the layout and led
      digitalWrite(led, LOW);
      state = 0;
    } else if (key == ‘\’ && !state) {
      digitalWrite(led, HIGH);
      state = 1;
    }
  }
  Keyboard.end();
}

// Taking care of some special events.
void keypadEvent(KeypadEvent key){
    switch (Symbols.getState()){
    case PRESSED:
        if (key == ‘O’) {
            pressTime = millis();
        }
        break;

case RELEASED:
        if (key == ‘O’) {
            releseTime = millis();
        }
        break;

case HOLD:
        if (key == ‘*’) {
        }
        break;
    }
}
[/code]

i want make a real keyboard that supports

  1. multi-pal key press to support modifiers
  2. change the layout when a key is pressed.
  3. when a key is hold for 3 sec it will put low to a pin(to shutdown the device)
  4. Add mouse movement with 8 keys with left, right click.

if someone can help me out i will be really grateful.

there is pic in bottom of the circuit

I don’t see (well I guess) why you want to use two keypad instances. You physically have only one.
→ A possible trick is that you could use the keypad instance to collect the index of the key that is pressed and then based on a flag (if you have shifted keyboard or not) you print the symbol you want from an alphabet dictionary.

I hacked quickly the below together here based on the example above and your code, totally untested, not even sure it compiles, but this could give you ideas.

It won’t send keyboard events (not hard to add as you’ll see) but will print information about what’s going on to the Serial monitor if you open it at 115200 bauds. Some symbols might not have a printed representation so won’t show of course.

give it a try and let me know if you have questions

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

const byte ROWS = 5;
const byte COLS = 11;

const char hexaAlphabets[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_LEFT_ARROW,
  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN
};

const char hexaSymbols[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  KEY_ESC, '!', '@', '#', '

, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, KEY_LEFT_ARROW,
  KEY_TAB, ‘|’, KEY_UP_ARROW , ‘_’, ‘~’, ‘:’, ‘;’, ‘"’, ‘’’, ‘`’, KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, ‘E’ , KEY_DOWN_ARROW, ‘E’, ‘[’, ‘]’, ‘{’, ‘}’, ‘<’, ‘>’,  KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI, ‘+’, ‘-’, ‘/’, ‘*’, ‘=’, ‘,’, ‘.’, ‘?’, KEY_RETURN
};

const char symbolIndexes[ROWS][COLS] = {
  {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
  {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
  {23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33},
  {34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44},
  {45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55}
};

byte rowPins[ROWS] = {A2, 15, 0, 1, A3};
byte colPins[COLS] = {14, A0, 9, 8, 7, 6, 5, 4, 3, 2, A1};
Keypad matrixKeypad = Keypad(makeKeymap(symbolIndexes), rowPins, colPins, ROWS, COLS);

bool matrixShift = false;
const byte matrixShiftKey = 10; // this is the code for the ‘’ character

bool magicKeyAction = false;
const byte magicKey = 21; // this is the code for the ‘0’ character
unsigned long magicKeyPressTime = 0;
unsigned long magicKeyReleaseTime = 0;

// handling special events as they occur
void keypadEvent(KeypadEvent key) {
  switch (matrixKeypad.getState()) {
    case PRESSED:
      if (key == magicKey && !matrixShift) {
        magicKeyPressTime = millis();
      }
      break;

case RELEASED:
      if (key == magicKey && !matrixShift) {
        magicKeyReleaseTime = millis();
        magicKeyAction = true;
      }
      break;

case HOLD:
      break;
  }
}

// main code
void setup()
{
  Serial.begin(115200);
  matrixKeypad.addEventListener(keypadEvent); // Add an event listener for this keypad
}

void loop() {
  char key = matrixKeypad.getKey(); // key will vary between 1 and 55, it’s the index (+1) of the charcter in the arrays

if (key != NO_KEY) {

Serial.print(F("key = “)); Serial.print(key);
    Serial.print(F(”, matrix is “));
    if (!matrixShift) Serial.print(F(” NOT "));
    Serial.println(F(“shifted”));

Serial.print(F(“Associated keyboard symbol is”));
    if (matrixShift) {
      Serial.println(hexaSymbols[key - 1]);
    } else {
      Serial.println(hexaAlphabets[key - 1]);
    }

if (key == matrixShiftKey) {
      matrixShift = !matrixShift;
      Serial.print(F("SHIFT IS NOW "));
      if (matrixShift) Serial.println(F(“ON”));
      else Serial.println(F(“OFF”));
    }

if (magicKeyAction) {
      Serial.print(F(“MAGIC KEY PRESSED FOR “));
      Serial.print(magicKeyReleaseTime - magicKeyPressTime);
      Serial.println(F(” ms.”));
      magicKeyAction = false;
    }
  }
}
[/code]

it's working fine but i am not getting the delay hold of the O key.
and is it possible to add what i told before?

  1. multi-pal key press to support modifiers
  2. change the layout when a key is pressed.
  3. when a key is hold for 3 sec it will put low to a pin(to shutdown the device)
  4. Add mouse movement with 8 keys with left, right click.
  5. continus output if a key is pressed on like a real keyborad

I won't do your homework.... :slight_smile:

in what I wrote, the special key should be '0'. it's defined like this

const byte magicKey = 21; // this is the code for the '0' character

and 21 is mapped to

[color=bue]
const char hexaAlphabets[] = {
  'P', [color=red][b]'O'[/b][/color], 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  '1', '2', '3', '4', '5', '6', '7', '8', '9', [color=green][b]'0'[/b][/color], KEY_LEFT_ARROW,
  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN
};[/color]

the mapping is what you see in the keypad codes:

const char symbolIndexes[ROWS][COLS] = {
  {1, [color=red][b]2[/b][/color], 3, 4, 5, 6, 7, 8, 9, 10, 11},
  {12, 13, 14, 15, 16, 17, 18, 19, 20, [color=green][b]21[/b][/color], 22},
  {23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33},
  {34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44},
  {45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55}
};

so if you want the 'O' (capital O) then the index is 2.

what you want to do is possible but requires programing and probably a better state machine than what I had hacked together here

22:26:06.129 -> key = , matrix is  NOT shifted
22:26:06.129 -> Associated keyboard symbol isO
22:26:06.129 -> MAGIC KEY PRESSED FOR 4294965544 ms.
22:26:09.329 -> key = , matrix is  NOT shifted
22:26:09.329 -> Associated keyboard symbol isO
22:26:09.329 -> MAGIC KEY PRESSED FOR 4294966281 ms.
22:26:12.987 -> key = , matrix is  NOT shifted
22:26:12.987 -> Associated keyboard symbol isO
22:26:12.987 -> MAGIC KEY PRESSED FOR 4294966077 ms.
22:26:14.093 -> key = , matrix is  NOT shifted
22:26:14.093 -> Associated keyboard symbol isO
22:26:14.093 -> MAGIC KEY PRESSED FOR 4294966826 ms.
22:26:15.533 -> key = , matrix is  NOT shifted
22:26:15.533 -> Associated keyboard symbol isO
22:26:15.533 -> MAGIC KEY PRESSED FOR 4294966705 ms.
22:26:19.733 -> key = , matrix is  NOT shifted
22:26:19.733 -> Associated keyboard symbol isO
22:26:19.733 -> MAGIC KEY PRESSED FOR 4294966632 ms.

no matter how long i press and hold down it shows same.

try with this (as I said, I typed it here so can’t be sure of anything)

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

const byte ROWS = 5;
const byte COLS = 11;

const char hexaAlphabets[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_LEFT_ARROW,
  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN
};

const char hexaSymbols[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  KEY_ESC, '!', '@', '#', '

, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, KEY_LEFT_ARROW,
  KEY_TAB, ‘|’, KEY_UP_ARROW , ‘_’, ‘~’, ‘:’, ‘;’, ‘"’, ‘’’, ‘`’, KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, ‘E’ , KEY_DOWN_ARROW, ‘E’, ‘[’, ‘]’, ‘{’, ‘}’, ‘<’, ‘>’,  KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI, ‘+’, ‘-’, ‘/’, ‘*’, ‘=’, ‘,’, ‘.’, ‘?’, KEY_RETURN
};

const char symbolIndexes[ROWS][COLS] = {
  {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
  {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
  {23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33},
  {34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44},
  {45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55}
};

byte rowPins[ROWS] = {A2, 15, 0, 1, A3};
byte colPins[COLS] = {14, A0, 9, 8, 7, 6, 5, 4, 3, 2, A1};
Keypad matrixKeypad = Keypad(makeKeymap(symbolIndexes), rowPins, colPins, ROWS, COLS);

bool matrixShift = false;
const byte matrixShiftKey = 10; // this is the code for the ‘’ character

bool magicKeyAction = false;
const byte magicKey = 21; // this is the code for the ‘0’ character
unsigned long magicKeyPressTime = 0;
unsigned long magicKeyReleaseTime = 0;

// handling special events as they occur
void keypadEvent(KeypadEvent key) {
  switch (matrixKeypad.getState()) {
    case PRESSED:
      if (key == magicKey && !matrixShift && !magicKeyAction) {
        magicKeyPressTime = millis();
      }
      break;

case RELEASED:
      if (key == magicKey && !matrixShift && !magicKeyAction) {
        magicKeyReleaseTime = millis();
        magicKeyAction = true;
      }
      break;

case HOLD:
      break;
  }
}

// main code
void setup()
{
  Serial.begin(115200);
  matrixKeypad.addEventListener(keypadEvent); // Add an event listener for this keypad
}

void loop() {
  uint8_t key = matrixKeypad.getKey(); // key will vary between 1 and 55, it’s the index (+1) of the charcter in the arrays

if (key != NO_KEY) {

Serial.print(F("key = “)); Serial.print(key);
    Serial.print(F(”, matrix is “));
    if (!matrixShift) Serial.print(F(” NOT "));
    Serial.println(F(“shifted”));

Serial.print(F("Associated keyboard symbol is : "));
    if (matrixShift) {
      Serial.println(hexaSymbols[key - 1]);
    } else {
      Serial.println(hexaAlphabets[key - 1]);
    }

if (key == matrixShiftKey) {
      matrixShift = !matrixShift;
      Serial.print(F("SHIFT IS NOW "));
      if (matrixShift) Serial.println(F(“ON”));
      else Serial.println(F(“OFF”));
    }
  }

if (magicKeyAction) {
    Serial.print(F(“MAGIC KEY PRESSED FOR “));
    Serial.print(magicKeyReleaseTime - magicKeyPressTime);
    Serial.println(F(” ms.”));
    magicKeyAction = false;
  }
}
[/code]

it's working nice.
i tried to get the hold down the key to get the continuos key press by this

    case HOLD:
      Serial.print(F("hold"));
      break;
  }
}

but it's not working.

It’s not working does not mean anything.

What do you see ? What’s the rest of the code ? Etc...

sorry

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

const byte ROWS = 5;
const byte COLS = 11;

const char hexaAlphabets[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_LEFT_ARROW,
  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN
};

const char hexaSymbols[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  KEY_ESC, '!', '@', '#', '

i think because the serial setup is after the keypadevent. but also i can’t put it after the setup.

Not working means i only get one key when i hold down the button. it should be continuous output until i release the button.

And i need to work on the multi-pal key-press. but can’t understand where to fit this code

also not sure if i add this it will effect the magic key hold down for 2 second, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, KEY_LEFT_ARROW,
  KEY_TAB, ‘|’, KEY_UP_ARROW , ‘_’, ‘~’, ‘:’, ‘;’, ‘"’, ‘’’, ‘`’, KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, ‘E’ , KEY_DOWN_ARROW, ‘E’, ‘[’, ‘]’, ‘{’, ‘}’, ‘<’, ‘>’,  KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI, ‘+’, ‘-’, ‘/’, ‘*’, ‘=’, ‘,’, ‘.’, ‘?’, KEY_RETURN
};

const char symbolIndexes[ROWS][COLS] = {
  {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
  {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
  {23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33},
  {34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44},
  {45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55}
};

byte rowPins[ROWS] = {A2, 15, 0, 1, A3};
byte colPins[COLS] = {14, A0, 9, 8, 7, 6, 5, 4, 3, 2, A1};
Keypad matrixKeypad = Keypad(makeKeymap(symbolIndexes), rowPins, colPins, ROWS, COLS);

bool matrixShift = false;
const byte matrixShiftKey = 10; // this is the code for the ‘’ character

bool magicKeyAction = false;
const byte magicKey = 2; // this is the code for the ‘0’ character
unsigned long magicKeyPressTime = 0;
unsigned long magicKeyReleaseTime = 0;
unsigned long magicHoldTime = 0;

// handling special events as they occur
void keypadEvent(KeypadEvent key) {
  switch (matrixKeypad.getState()) {
    case PRESSED:
      if (key == magicKey && !matrixShift && !magicKeyAction) {
        magicKeyPressTime = millis();
      }
      break;

case RELEASED:
      if (key == magicKey && !matrixShift && !magicKeyAction) {
        magicKeyReleaseTime = millis();
        magicKeyAction = true;
      }
      break;

case HOLD:
      Serial.print(F(“hold”));
      break;
  }
}

// main code
void setup()
{
  //reduce the clock to 1/4
  noInterrupts();
  CLKPR = 0x80;  // enable change of the clock prescaler
  CLKPR = 0x02;  // divide frequency by 2
  interrupts();

Serial.begin(115200);
  matrixKeypad.addEventListener(keypadEvent); // Add an event listener for this keypad
}

void loop() {
  uint8_t key = matrixKeypad.getKey(); // key will vary between 1 and 55, it’s the index (+1) of the charcter in the arrays

if (key != NO_KEY) {

Serial.print(F("key = “)); Serial.print(key);
    Serial.print(F(”, matrix is “));
    if (!matrixShift) Serial.print(F(” NOT "));
    Serial.println(F(“shifted”));

Serial.print(F("Associated keyboard symbol is : "));
    if (matrixShift) {
      Serial.println(hexaSymbols[key - 1]);
    } else {
      Serial.println(hexaAlphabets[key - 1]);
    }

if (key == matrixShiftKey) {
      matrixShift = !matrixShift;
      Serial.print(F("SHIFT IS NOW "));
      if (matrixShift) Serial.println(F(“ON”));
      else Serial.println(F(“OFF”));
    }
  }

if (magicKeyAction) {
    magicHoldTime = magicKeyReleaseTime - magicKeyPressTime;
    Serial.print(F(“MAGIC KEY PRESSED FOR “));
    Serial.print(magicHoldTime);
    Serial.println(F(” ms.”));
    if( magicHoldTime > 500){
      Serial.print(F(“Power off”));
    }
    magicKeyAction = false;
  }
}
[/code]

i think because the serial setup is after the keypadevent. but also i can’t put it after the setup.

Not working means i only get one key when i hold down the button. it should be continuous output until i release the button.

And i need to work on the multi-pal key-press. but can’t understand where to fit this code

also not sure if i add this it will effect the magic key hold down for 2 second

here is an example you can build on top of

#include <Keypad.h> // https://github.com/Chris--A/Keypad

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns

//define the symbols on the buttons of the keypads
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

// to memorize moment when key went down and calculate duration
uint32_t keyChrono[ROWS * COLS];

// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 7, 6, 5, 4 };
// Connect keypad COL0, COL1, COL2 and COL3 to these Arduino pins.
byte colPins[COLS] = {11, 10, 9, 8};

//initialize an instance of class NewKeypad
Keypad membraneKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);

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

void loop() {
  // Fills membraneKeypad.key[ ] array with up-to 10 active keys.
  membraneKeypad.getKeys();  // Returns true if there are ANY active keys. we don't test here so that the loop can always test states

  for (int i = 0; i < LIST_MAX; i++) { // Scan the whole key list.
    switch (membraneKeypad.key[i].kstate) {  // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
      
      case PRESSED:
        if ( membraneKeypad.key[i].stateChanged) {  // Only find keys that have changed state.
          keyChrono[i] = millis();
          Serial.print(membraneKeypad.key[i].kchar);
          Serial.println(F(" PRESSED."));
          membraneKeypad.key[i].stateChanged = false;
        }
        break;
      case HOLD:
        break;
        
      case RELEASED:
        if ( membraneKeypad.key[i].stateChanged) {  // Only find keys that have changed state.
          Serial.print(membraneKeypad.key[i].kchar);
          Serial.print(F(" RELEASED AFTER "));
          Serial.print(millis() - keyChrono[i]);
          Serial.println(F(" ms"));
          membraneKeypad.key[i].stateChanged = false;
        }
        break;

      case IDLE:
        if ( membraneKeypad.key[i].stateChanged) {  // Only find keys that have changed state.
          Serial.print(membraneKeypad.key[i].kchar);
          Serial.println(" NOW IDLE.");
          membraneKeypad.key[i].stateChanged = false;
        }
        break;
    }
  }
}

it will track for your keypad all the activity per key and report for each key how long it has been held down. it handles multiple key down at once (10 active keys - with 10 fingers that should be enough :)) )

To Know if something is a double press, we would need to memorize more information, the time of the last release for example, and if that’s close enough to the time of the next press, then it’s a double click.

→ left as an exercise :slight_smile:

this does not gives continuous key output if i hold the button down.
also can't figure out how to add the actula keyboard output, i mean HID output as there is 2 ways to do it. press and write.
i need that continuous output .

this gives random output

#include <Keypad.h> // https://github.com/Chris--A/Keypad
#include <Keyboard.h>

const byte ROWS = 5;
const byte COLS = 11;

//define the symbols on the buttons of the keypads
const char hexaAlphabets[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_LEFT_ARROW,
  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI,  'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', KEY_RETURN
};

const char hexaSymbols[] = {
  'P', 'O', 'E', 'E', 'E', 'E', 'E', 'E', 'E', '\\', ' ',
  KEY_ESC, '!', '@', '#', '

output

23:20:12.907 -> 1P PRESSED.
23:20:13.107 -> & RELEASED AFTER 216 ms
23:20:13.107 -> & NOW IDLE.
23:20:13.567 -> 1P PRESSED.
23:20:13.798 -> & RELEASED AFTER 240 ms
23:20:13.837 -> & NOW IDLE.
23:20:14.873 -> 1P PRESSED.
23:20:15.037 -> % RELEASED AFTER 180 ms
23:20:15.037 -> % NOW IDLE.
23:20:15.437 -> 1P PRESSED.
23:20:15.597 -> % RELEASED AFTER 168 ms
23:20:15.637 -> % NOW IDLE.
23:20:16.358 -> 1P PRESSED.
23:20:16.557 -> % RELEASED AFTER 206 ms
23:20:16.557 -> % NOW IDLE.
23:20:16.957 -> 1P PRESSED.
23:20:17.187 -> % RELEASED AFTER 230 ms
23:20:17.227 -> % NOW IDLE.

, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, KEY_LEFT_ARROW,
  KEY_TAB, ‘|’, KEY_UP_ARROW , ‘_’, ‘~’, ‘:’, ‘;’, ‘"’, ‘’’, ‘`’, KEY_RIGHT_ARROW,
  KEY_CAPS_LOCK, ‘E’ , KEY_DOWN_ARROW, ‘E’, ‘[’, ‘]’, ‘{’, ‘}’, ‘<’, ‘>’,  KEY_BACKSPACE,
  KEY_LEFT_CTRL, KEY_LEFT_GUI, ‘+’, ‘-’, ‘/’, ‘*’, ‘=’, ‘,’, ‘.’, ‘?’, KEY_RETURN
};

const char symbolIndexes[ROWS][COLS] = {
  {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11},
  {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
  {23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33},
  {34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44},
  {45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55}
};

// to memorize moment when key went down and calculate duration
uint32_t keyChrono[ROWS * COLS];

byte rowPins[ROWS] = {A2, 15, 0, 1, A3};
byte colPins[COLS] = {14, A0, 9, 8, 7, 6, 5, 4, 3, 2, A1};

//initialize an instance of class NewKeypad
Keypad membraneKeypad = Keypad(makeKeymap(symbolIndexes), rowPins, colPins, ROWS, COLS);

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

void loop() {
  // Fills membraneKeypad.key array with up-to 10 active keys.
  uint8_t key = membraneKeypad.getKeys();  // Returns true if there are ANY active keys. we don’t test here so that the loop can always test states

for (int i = 0; i < LIST_MAX; i++) { // Scan the whole key list.
    switch (membraneKeypad.key[i].kstate) {  // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
   
      case PRESSED:
        if ( membraneKeypad.key[i].stateChanged) {  // Only find keys that have changed state.
          keyChrono[i] = millis();
          Serial.print(key );
          Serial.print(hexaSymbols[key - 1]);
          Serial.println(F(" PRESSED."));
          membraneKeypad.key[i].stateChanged = false;
        }
        break;
      case HOLD:
        break;
     
      case RELEASED:
        if ( membraneKeypad.key[i].stateChanged) {  // Only find keys that have changed state.
          Serial.print(membraneKeypad.key[i].kchar);
          Serial.print(F(" RELEASED AFTER “));
          Serial.print(millis() - keyChrono[i]);
          Serial.println(F(” ms"));
          membraneKeypad.key[i].stateChanged = false;
        }
        break;

case IDLE:
        if ( membraneKeypad.key[i].stateChanged) {  // Only find keys that have changed state.
          Serial.print(membraneKeypad.key[i].kchar);
          Serial.println(" NOW IDLE.");
          membraneKeypad.key[i].stateChanged = false;
        }
        break;
    }
  }
}
[/code]

output

§_DISCOURSE_HOISTED_CODE_1_§

rahmanshaber:
this does not gives continuous key output if i hold the button down.
also can't figure out how to add the actula keyboard output, i mean HID output as there is 2 ways to do it. press and write.
i need that continuous output .

well as I said, that's just an example. I did not put any code when the button is held down but it's in the switch / case..

Seems you are missing the basics of programing to achieve your goal. I would suggest you put this project aside for a few days / weeks and you spend time with simpler tutorials to get acquainted with the language and typical code constructs as well as the different librairies. Then come back to this