Keypad Library HOLD Question

Is there any method to disable the HOLD return or for that matter Both the HOLD and IDLE returns from the library.

Maybe even the Pressed and Released signals as I know a couple of places in my code where that would be beneficial.. anyway...

I know I can extend the hold time to a number that would make it relatively improbable that HOLD would be initiated.

The Reason I ask is that I am doing a simple button press (event) and of course every time I press the button it gets pressed three instances (Pressed, Released, and Idle) so the event is called upon 3 times.. I have worked around this with a counter to ignore the State(s) that I don't want.. However if for some reason the button is held down for the allotted HOLD time then there is a fourth event called and of course that screws up the counter and the number of events called and when they are called.

I might be able to do a state table for the single button but haven't quite figured that out for a single button in a larger matrix. I have other situations where a state table May not work as wanted and Disabling or ignoring a output would work better.

Anyway any help would be appreciated.

Thank you
Brion Sohn

No way for me to test it, but would a simple getKey() not solve your problem? Else you will have to post your code (or a representative example).

Which library are you using? assuming you use Chris--A/Keypad latest version just don't add an EventListener (with addEventListener) and stick to polling the key that is pressed in the loop

#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'}
};

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

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

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

void loop() {
  char entry = membraneKeypad.getKey();
  if (entry != NO_KEY) {
    Serial.println(entry);
  }
}

of course in that example if you press and hold a key, you don't get the event and if you press and release another key while holding the first one, you don't get the event either. but if you want to stick to 1 key press/release at the time and ignore other user actions, then that would be enough

J-M-L:
Which library are you using? assuming you use Chris--A/Keypad latest version just don't add an EventListener (with addEventListener) and stick to polling the key that is pressed in the loop

#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'}
};

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

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

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

void loop() {
  char entry = membraneKeypad.getKey();
  if (entry != NO_KEY) {
    Serial.println(entry);
  }
}




of course in that example if you press and hold a key, you don't get the event and if you press and release another key while holding the first one, you don't get the event either. but if you want to stick to 1 key press/release at the time and ignore other user actions, then that would be enough

Essentially that is what I was doing but the get key() still registers all four states as 1, 2, 3, and 0 for Pressed, Hold, Released, and Idle.. I was hoping to just eliminate the Hold state from that but it appears that it is just easier to send it through the switch/Case to eliminate any Hold action.. Anyway I think I have figured it out appropriately by just using the switch.. The other section of code that I was thinking I needed this for I had to scrap as it didn't work well anyway so that section is going to take a complete rethink.

There will always be a hold state... your processor is so much faster than your button and your physical actions

If you don’t want an event just don’t register for it... (ie not sure what you are trying to do)

J-M-L:
There will always be a hold state... your processor is so much faster than your button and your physical actions

If you don’t want an event just don’t register for it... (ie not sure what you are trying to do)

OK let me explain what happens..

When I read a physical button press through the serial with use of the keypad matrix. It outputs each state of the button as it's own instance of that button and unless a state loop is used it will not differentiate the states though they do happen in a certain order.. SO for an event if it is a quick press then it sends three signals Pressed, Released, and Idle.. so it triggers the event 3 times. With this I can do a hack around it with a counter so that some command will only run on the 1st, second, or third instance.. Problem is that if the Button is HELD it will then send a 4th instance for the hold state after the allocated time. This additional HELD instance would of course totally mess up the counter that determines at what point things are run in the Pressed, Release, Idle Sequence.

So if the HELD instance could be disabled in Keypad then it would solve that issue..

Granted if I was just running straight to ground with the buttons and pins it would just be a matter of turning the button on or off

All of that being said though I have figured out how to get the state function to work with what I was doing which has solved the issue for one part of what I am working, I am now hopeful that since I have figured out how to use the state function on that I can get it to work for me on the second part of what I am working on.

SO for an event if it is a quick press then it sends three signals Pressed, Released, and Idle

that depends on the holdTime you will set for your keypad. Set it to 100 seconds and you’ll likely never see that event, and set it to 0 and you’ll see it always due to the physical time for the button to action

so it triggers the event 3 times

No - it triggers 3 (or 4) different calls to the same function with different events. Just ignore the event states you don’t care about if you want to take this event notification (aka callback) approach to your problem. If you use the callback you don’t need a counter or whatever, just take action on press for example and ignore the others if you don’t need to do anything in releasing or holding the button

void keypadEvent(KeypadEvent key){
  if (keypad.getState() == PRESSED) {
      switch (key){
        case '#':
           // do something for that key
           break;

        case '*': 
           // do something else for that one 
          break;

        default:
           // and possibly anything else has the same treatment
           break;
      }
}

What I’m saying is that you don’t need to use addEventListener() at all nor implement a callback function for this. Just handle the status you care about in the loop like in the above code, which will print the key only once upon press.

J-M-L:
that depends on the holdTime you will set for your keypad. Set it to 100 seconds and you’ll likely never see that event, and set it to 0 and you’ll see it always due to the physical time for the button to action
No - it triggers 3 (or 4) different calls to the same function with different events. Just ignore the event states you don’t care about if you want to take this event notification (aka callback) approach to your problem. If you use the callback you don’t need a counter or whatever, just take action on press for example and ignore the others if you don’t need to do anything in releasing or holding the button

void keypadEvent(KeypadEvent key){

if (keypad.getState() == PRESSED) {
      switch (key){
        case '#':
          // do something for that key
          break;

case '*':
          // do something else for that one
          break;

default:
          // and possibly anything else has the same treatment
          break;
      }
}




What I’m saying is that you don’t need to use `addEventListener()` at all nor implement a callback function for this. Just handle the status you care about in the loop like in the above code, which will print the key only once upon press.

Yea, I figured that out, Prior to writing the last response.. and I knew about the HOLD timer and implemented the fix for the issue that way initially.. When I asked the question I was thinking that to eliminate the possibility of ever having it hold and error I wanted to disable that call ..

I now have it working with the Switch/Case set-up (which of course as you says eliminates the issue of the multiple calls) since it ignores states that you don't want. I was initially having issue with it as I wasn't figuring out how to narrow the scope of the Switch to only act on certain keys. I have now figured that out so it is all working with ignoring the unwanted calls.

bsohn:
I now have it working with the Switch/Case set-up (which of course as you says eliminates the issue of the multiple calls) since it ignores states that you don't want. I was initially having issue with it as I wasn't figuring out how to narrow the scope of the Switch to only act on certain keys. I have now figured that out so it is all working with ignoring the unwanted calls.

OK - and if you want to get rid of all the useless calls then don't use the call back approach at all. That was kinda my initial point, if you are only interested in one particular type of event, check for just that one, don't ask your code to be called for all the possibilities to end up rejecting all of them but one ---> your code will spend more time doing useful stuff (if timing matters)

J-M-L:
OK - and if you want to get rid of all the useless calls then don't use the call back approach at all. That was kinda my initial point, if you are only interested in one particular type of event, check for just that one, don't ask your code to be called for all the possibilities to end up rejecting all of them but one ---> your code will spend more time doing useful stuff (if timing matters)

Thank you, that makes sense to ignore the HOLD and IDLE states for one of my purposes.

good luck with your project!