How to add debounce to 4x4 keypad code

I want to make a program to turn ON turn OFF the LED using the 4x4 matrix keypad. Example, if I press "A' and release, the LED 1 will turn ON, then I press 'A' and release again, it will turn OFF the LED1. I dont understand how to add debounce for matrix keypad, or any programs that can make the LED turn ON and OFF like that. In my program, if I press 'A' the LED will turn ON, but if I release it the LED will turn OFF.

the details:
'A' for LED1
'B' for LED2
'C' for LED3

could you help me with the code? thank you

#include <Keypad.h>

const byte LED1 = 13;
const byte LED2 = 12;
const byte LED3 = 11;
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{
{'A', 'B', 'C', 'D'}, 
{'E', 'F', 'G', 'H'}, 
{'I', 'J', 'K', 'L'},
{'M', 'N', 'O', 'P'},
};
byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

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

void setup()
{
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}

void loop()
{
char keypressed = keypad.getKey();
  
  if (keypressed)
  {
    Serial.println(keypressed);
  }
 

	if (keypressed == 'A')
	{
		digitalWrite(LED1, HIGH);
		delay(250);
	}
	else
	{
		digitalWrite(LED1, LOW);
	}
  }

Welcome to the forum

What you need is not strictly debounce, rather you need to save the state of the LED then, when the 'A' key becomes pressed you change the state of the LED and write it to the LED pin

Something like this

#include <Keypad.h>

const byte LED1 = 13;
const byte LED2 = 12;
const byte LED3 = 11;
const byte ROWS = 4;  //four rows
const byte COLS = 4;  //three columns
char keys[ROWS][COLS] = {
    { 'A', 'B', 'C', 'D' },
    { 'E', 'F', 'G', 'H' },
    { 'I', 'J', 'K', 'L' },
    { 'M', 'N', 'O', 'P' },
};
byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

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

void setup()
{
    Serial.begin(115200);
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(LED3, OUTPUT);
}

void loop()
{
    char keypressed = keypad.getKey();

    if (keypressed)
    {
        Serial.println(keypressed);
    }

    if (keypressed == 'A')
    {
        led1State = !led1State;  //change to other state
        digitalWrite(LED1, led1State);
    }
}

not sure if you problem is solved by UKHeliBob's approach

but a simple approach to debounce is simply delay for 10-20 msec whenever a button state changes. a delay of 10-20 msec is typically not an issue in most programs

I think the title is wrong. @milmilmil doesn't need a debounce, that is done by the keypad library already. What he needs is state change detection. The LED must be switched, when the key becomes pressed, not while it is pressed. You must remember the last state of the key, and only if it changes from not pressed to is pressed the Led must be switched.

The code actually should not do that, getKey() should only return the 'A' when the key is pressed, and does not return any indication when it is held or released (you need the getKeys() function if you want to know the actual key state). If you held the 'A' key down, the LED should turn ON for 250mS, then turn back OFF until you release and press 'A' again.

To achieve the effect you are looking for, all you really need to do is toggle the state of the output pin whenever getKey() returns an 'A'.

If you mean only when the 'A' key goes from not pressed to pressed, it may depend on the library.

I believe a recent getKey() of some ilk was more like telling you which if any key is being held down.

There were calls or callbacks for events such as went down or came up and so forth.

a7

Hello milmilmil

Welcome to the worldbest forum.

Consider this sketch with the use of the switch/case statement.

#include <Keypad.h>
const byte LED1 = 13;
const byte LED2 = 12;
const byte LED3 = 11;
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{
  {'A', 'B', 'C', 'D'},
  {'E', 'F', 'G', 'H'},
  {'I', 'J', 'K', 'L'},
  {'M', 'N', 'O', 'P'},
};
byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}
void loop()
{
  char keypressed = keypad.getKey();
  if (keypressed)
  {
    Serial.println(keypressed);

    switch (keypressed) 
    {
      case 'A':
      digitalWrite(LED1,digitalRead(LED1)?LOW:HIGH);
      break; 
      case 'B':
      digitalWrite(LED2,digitalRead(LED2)?LOW:HIGH);
      break; 
      case 'C':
      digitalWrite(LED3,digitalRead(LED3)?LOW:HIGH);
      break; 
    }
  }
}

Have a nice day and enjoy coding in C++.

The "standard" Keypad library from the library manager, using the getKey() function, will only return a key code when the key goes from not being pressed to being pressed, and only does this for a single key at a time. The library does have methods to get the current state of the key, if you want to know if it is being held down, but the OP does not need that for what they are trying to accomplish.

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