4x4 keypad for menu driven functions

Hi all,

I've a standard 4x4 membrane keypad.
What I want to do is accept key A/B/C/D as option & then accept corresponding 4 digit number. I thought switch-case should work like this -

void loop ()
{
    key = kpd.getKey();
     if (key != NO_KEY)
    {
        Serial.print(key);
     }
     switch(key)
    {  
      case 'A':
            getA();      
      break;
      case 'B':
           getB();
      break;
      case 'C':
           getC();
       break;
       case 'D':
           getD();
       break;
    }

The code accepts 1st key (A/B/C/D) perfectly. But switch-case doesn't work. The functions to get numbers like getA() isn't called.

Can anyone help me?

I've tried declaring strings to accept numbers & then converting the strings to int in those functions. Not working.

Also tried making 2 instances of keypad. One with only A/B/C/D & another with only numbers (1-0,*,#). Accepting A/B/C/D using one keypad object "kpd1" & accepting number using second keypad object "kpd2" in respective function. This isn't working either.

Time for bed, but maybe this will be of some help.

Thanks but I've seen tonixstuff tutorial.

Only thing I see different is switch-case was put inside if statement. So my code should be

if (key != NO_KEY)
  {
    Serial.print(key);
    switch(key)
    {
         case ' ':
         ~some function;
         break;
     }
  }

I'm pretty sure I've tried this. Also I'll need to manage 2 different getKey functions (already tried so now re-arrange)
Will try again for sure.

Any other suggestions are always welcome :slight_smile:

Whats the output of the Serial Monitor?

PS:
Add this on the bottom of the Switch statement:

default:
Serial.Println("Receive Error");
break;

If the readback from the Key variable is anything other, you'll get a message.

In loop, serial monitor shows whichever key pressed i.e. one of these - A/B/C/D
But doesn't go to next function from switch-case where digit entry is taken & number is displayed.

Meanwhile I change my code a bit -

char getKpd1()     //This function will accept A/B/C/D return the same char value
{
	char key1 = kpd1.getKey();
	if (key1 != NO_KEY)
	{
		Serial.print(key1);
	}
	return(key1);
}
   
void getA()     //This function will accept 4 digit number A --- similar function can be written for B/C/D
{
	char key2 = kpd2.getKey();
	int bar=Num.length(); 
	if (key2 != NO_KEY && bar<4)
	{
		Num = Num + key2;
	}
        else if (bar>=4)     // This will keep 4-digit number
	        Num={};
        numberA = Num.toInt();     //NumberA is globally declared variable
        Serial.print(numberA);
}

void loop()
{
	char entry = getKpd1();
	switch(entry)
	{  
		case 'A':
			getA();
		break;
		case 'B':
			getB();
		break;
		case 'C':
			getC();
		break;
	}
}

I'll try "Receive Error" code in previous sketch & will post reply. Thanks

void getA()     //This function will accept 4 digit number A --- similar function can be written for B/C/D
{
	char key2 = kpd2.getKey();
	int bar=Num.length(); 
	if (key2 != NO_KEY && bar<4)
	{
		Num = Num + key2;
	}
        else if (bar>=4)     // This will keep 4-digit number
	        Num={};
        numberA = Num.toInt();     //NumberA is globally declared variable
        Serial.print(numberA);
}

First, this code does not block until 4 characters are entered.
Second, what the hell is this:

	        Num={};

Yes. I want a 4-digit number.
Num={} makes "Num" string empty.
So if someone provides number with >5 digits it'll go to null & need to be entered again.
Num is String object...not an array..

Am I wrong? :stuck_out_tongue:

Make Num an array, NOT String Object and use a counter to see how many digits are entered. If the user enters more than 4, clear the array and start over.

It's very simple.

so array instead of string and then array to int conversion? i think i read somewhere about function atoi()
will work on that.

If you use atoi(), the array will need to be Null terminated. Meaning the 4th index will need to be set to a null character (myArray[4] = '\0')

Here is an example.

myArray[0] = '1';
myArray[1] = '5';
myArray[2] = '9';
myArray[3] = '3';
myArray[4] = '\0';

int Value = atoi(myArray);

Yup. Got it.
I'll accept 4 digits & then add last '\0' myself. Easy to manage that in code.

But the original problem! Will that swith-case condition work (now referring to modified switch-case code..not the one in OP) ??
Accepting digits & saving to string/array is the next part. :stuck_out_tongue:

When you are inside the switch case, you will need to re-read the chars again and collect four, so you would probably want a while loop that will allow you to stay inside the case and continue to collect the numbers.

So what you want to write is this:

  1. read the keypad and get a letter, this letter will bring you into the corresponding case.
  2. using a while or do while loop, you re-read the keypad and collect the correct amount of numbers, anymore and you can show an error message
  3. after all the numbers have been obtained, you add the null character.
  4. use atoi and do whatever you want with the value

Thanks mate. :slight_smile: