Keypad.h keypad.isPressed() does not work

Basically, I'm running this code:
(Everything is compiling fine)

#include <Keypad.h>


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


char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {9, 8, 7, 6};


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


void setup(){
  Serial.begin(9600);
}
  
void loop(){
  if (keypad.isPressed('1')){
    Serial.println(".");
  }
}

And when I press 1, nothing is printed.
What am I doing wrong?

Hi,
Welcome to the forum.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Please not a Fritzy picture.

Thanks.. Tom.... :slight_smile:

I connect my keypad to 2-9 pins and I checked it already.
Functions like getKey() work fine, but this one doesn't for some reason.

beeing hestistant with information will rise the time needed for finding a solution.

post a description of what your code does when pressing every single key of your keypad.
attach a handdrawn picture of how you wired your keypad. Writing

I connect my keypad to 2-9

is not sufficient.
For analysing what is going on you should code a even more simpler program

  if (keypad.isPressed('1')){[color=#222222][/color]
    Serial.println(".");[color=#222222][/color]
  }

means only if the function isKeypressed('1') returns true print a dot.
the keypad-library has a lot more functions.
what do you get for results if you just let print the value of the key?
DId you run some ready to use demo-programs? What where the results of these demo-programs?
replace your setup and loop functions with this ones

void setup(){
  Serial.begin(9600);
  Serial.println("Setup Start");
}
  
void loop(){
  char key = keypad.getKey();
  
  if (key){
    Serial.print("pressed key:#");
    Serial.print(key);
    Serial.print("#");
  }
}

This program enable to check if the serial connection works at all
by printing Setup Start
and it will print the value of the key received
enclosed in hashtags # #
to make even visible if the received value is printable or not.

best regards Stefan

isPressed() is one of the library functions used to test whether multiple keys are pressed at the same time. If that is not what you are trying to do then the functions functions designed to detect a single keypress should be used

See Keypad data entry

Are you saying that isPressed() will not work in the manner the OP has attempted?

Casual googling (I was thinking it was being misused as far as the argument passed was concerned) leads to examples using it on a single character.

I accept it may not be the easiest or best, but it seems like if you were on a dessert island and it was all you had it would in fact be usable.

a7

The isPressed() function iterates through the key array of the Keypad library for a match

The key array is populated by calling the getKeys()) function which returns true if a key state has changed

For example

#include <Keypad.h>

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

char keys[ROWS][COLS] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte colPins[COLS] = {10, 11, 12, A4}; //column pins
byte rowPins[ROWS] = {2, 4, 7, 8}; //row pins

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

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

void loop()
{
  if (keypad.getKeys())
  {
    if (keypad.isPressed('1'))
    {
      Serial.println(".");
    }
  }
}

Clear as an azure sky of deepest summer.

THX

a7

For everyone who asked. Yes, I need keypad.isPressed function.

My goal is to check if key is pressed or not. Of course, keypad.getKey can do this partially. However, it works only for one key and it detects only pressing a button, but not holding (which is my main goal).

As I said before, keypad.isPressed function does work for me. (Constantly returns false)
So, I you know how use it correctly or a different method for this, please reply this port.
Thanks.

OK, I found a solution for my own problem.
However, this requires modifying Keypad.h library.

  1. Edit Keypad.h (at line 92)
bool isPressed(char keyChar);

Replace with

byte getState(char keyChar);
  1. Edit Keypad.cpp (at line 178)
bool Keypad::isPressed(char keyChar) {
	for (byte i=0; i<LIST_MAX; i++) {
		if ( key[i].kchar == keyChar ) {
			if ( key[i].kstate == PRESSED && key[i].stateChanged )
				return true;
		}
	}
	return false;
}

Replace with

byte Keypad::getState(char keyChar) {
	for (byte i=0; i<LIST_MAX; i++) {
		if ( key[i].kchar == keyChar ) {
			if ( key[i].stateChanged )
				return int(key[i].kstate);
		}
	}
	return 0;
}
  1. Edit keywords.txt (at line 21)
isPressed	KEYWORD2

Replace with

getState	KEYWORD2

In result, we get keypad.getState function which will return IDLE / PRESSED / HOLD / RELEASED (0, 1, 2, 3) constants.
Here's quick example for using our new function:

#include <Keypad.h>

const byte colPins[4] {5, 4, 3, 2};
const byte rowPins[4] {9, 8, 7, 6}; // or any other pins you connect your keypad to

Keypad pad = Keypad( makeKeymap("123A456B789C*0#D"), rowPins, colPins, 4, 4);

// char that we are testing
const char test = '#';
// usage of IDLE state
const bool usingIDLE = false;

byte state = 0;

void setup() {
  Serial.begin(9600);
  Serial.print("Key states for ");
  Serial.print(test);
  Serial.println(":");
  if (usingIDLE) Serial.println("State: IDLE");
};

void loop() {
  if (pad.getKeys()) {
    state = pad.getState(test);
    if (usingIDLE || state) Serial.print("State: ");
    switch (state) {
      case 0:
      if (usingIDLE) Serial.println("IDLE");
      break;

      case 1:
      Serial.println("PRESSED");
      break;

      case 2:
      Serial.println("HOLD");
      break;

      case 3:
      Serial.println("RELEASED");
      break;
    };
  };
};

I hope you will find this helpful but anyways, thanks for your all replies. :slight_smile:

As I said before, keypad.isPressed function does work for me. (Constantly returns false)

So, I you know how use it correctly or a different method for this, please reply this port.

Did you try the code in reply #6 ?

Yes, but it only works for PRESSED state of button. So, I won't know if the button has already been released or still held. Thanks anyway, because after debugging I came up with some patches to the code that works perfectly for me.

I found a solution (for me) with event. Maybe someone can use it:

// Source: http://wiring.org.co/learning/libraries/dynamickeypad.html

#include <Keypad.h>

char keys[4][4] = {
  { 1, 2, 3, 4 },
  { 5, 6, 7, 8 },
  {10, 11, 12, 13 },
  {14, 15, 16, 17 }
};

byte rowPins[] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

//create a new Keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, sizeof(rowPins), sizeof(colPins));

void setup() {
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent);                                      // Add an event listener.
  keypad.setHoldTime(500);                                                   // Default is 1000mS
  keypad.setDebounceTime(250);                                               // Default is 50mS
}

void loop() {
  int key = keypad.getKey();
  if (key > 0) Serial.print(key);
}

// Take care of some special events.
void keypadEvent(KeypadEvent key) {
  switch (keypad.getState()) {
    case PRESSED:
      Serial.print("pressed: ");
      break;
    case HOLD:
      Serial.print(" hold");
      break;

    case RELEASED:
      Serial.println(" released");
      break;
  }
}

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