[SOLVED] Keypad number input and store

Hi.
I'm a beginner with Arduino programming and need some advice. My project is a bit bigger, but I'm stuck right now on this (quite simple?) problem.
What I need is read numbers that are typed on o 4x3 keypad, then store them in a variable and put on LCD display. The variables are three, and for each one the user can enter values. My code looks somtehing like this (the setup part is not shown):

void loop()
{
// for 12V -----------------------------------------------------------
char key1 = kpd.getKey();
switch (key1) {
case NO_KEY:
break;

case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
lcd.print(key1);
firstvariable = firstvariable* 10 + key1 - '0';
break;

case '#':
Serial.println ();
Serial.print ("Value for 12V is: ");
Serial.print (firstvariable );
break;

case '*':
firstvariable = 0;
lcd.clear();
Serial.println ();
Serial.print ("Reset value:");
Serial.print (firstvariable );
}
// for 12V end -----------------------------------------------------------
}

This is only for the first value. What I need is when the user press #, the firstvalue is stored, and the program continues on the input of the second value. After the second value, it continues with the input of the last (third) value.

I've tried doing some functions and calling it after the # button press, but with no luck. Can someone please give me a hint, how should it look like?
Thank you.

You need to keep track of whether the keypad input is for the first variable, the second variable, or the third variable. The easiest way to do this is to put the code you have in a function that returns an int.

int GetNumber()
{
   int num = 0;
   char key1 = kpd.getKey();
   switch (key1)
   {
     case NO_KEY:
      break;

    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      lcd.print(key1);
      num = num * 10 + (key1 - '0');
      break;

    case '#':
        return num;
        break;

    case '*':
        num = 0;
        lcd.clear();
   }
}

Then call the function as required:

void loop()
{
   v1 = GetNumber();
   // Do something with v1
   v2 = GetNumber();
   // Do something with v2
   v3 = GetNumber();
   // Do something with v3
}

Thank you.
I've tried that code, but I must doing something wrong (dunno what). To me, it looks like the program never 'waits' for the # button to pass the stored number out of the called function.
When I read the output in the function, it gives me only zero, whatever is pressed. And when the output is read in void loop, there is only a constatn flow of zeroes.
What I need to do is count the numbers in one variable until # is pressed, then the program should continue the same way for the second variable etc. After that the code will work with the inserted numbers...

#include <Keypad.h>
#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2); 

int v1 = 0;
int v2 = 0;
int v3 = 0;
const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {                    
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[ROWS] = { 22, 23, 24, 25 };    
byte colPins[COLS] = { 26, 27, 28 }; 
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 

void setup()
{
  lcd.init();                             
  lcd.commandWrite(0x0F);                
  lcd.clear();                             
  Serial.begin(9600);                     
}

void loop()
{
   v1 = GetNumber();
   //Serial.println ();
   //Serial.print (v1);
   v2 = GetNumber();
   v3 = GetNumber();

}


int GetNumber()
{
   int num = 0;
   char key = kpd.getKey();
   switch (key)
   {
     case NO_KEY:
      break;

    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      lcd.print(key);
      num = num * 10 + (key - '0');
      break;

    case '#':
        //Serial.println ();
	//Serial.print (num);
        return num;
        break;

    case '*':
        num = 0;
        lcd.clear();
   }
}

Sorry if I ask dumb questions, and thanks for patience :slight_smile:

Sorry. There needs to be a while loop in the GetNumber function. Something like this:

int GetNumber()
{
   int num = 0;
   char key = kpd.getKey();
   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            lcd.print(key);
            num = num * 10 + (key - '0');
            break;

         case '*':
            num = 0;
            lcd.clear();
            break;
      }

      key = kpd.getKey();
   }

   return num;
}
1 Like

Excellent! Now its working fine.
Many thanks :slight_smile:

1 Like

in this part

num = num * 10 + (key - '0');

why its reduced by zero?

why its reduced by zero?

The value of '5' as a number is 5. The value of '7' as a number is 7. The value of '0' as a number is 0.

So, subtracting '0' from a character representing a digit results in the digit that the character represents.

PaulS:
The value of '5' as a number is 5. The value of '7' as a number is 7. The value of '0' as a number is 0.

So, subtracting '0' from a character representing a digit results in the digit that the character represents.

Actually, each of these characters has two values: the one that we want, and the one that is used internally by the software.

As far as the software is concerned:
the value of the character '0' is the number 48;
the value of the character '1' is the number 49;
the value of the character '2' is the number 50; and so forth.
But (as I'm sure you know) those aren't the values we want!
So we subtract 48 from each of these values to get the values we want.

The value of the character '0' is the number 48, but we want the number 0, so we subtract 48 from 48 to get 0.
The value of the character '1' is the number 49, but we want the number 1, so we subtract 48 from 49 to get 1.
The value of the character '2' is the number 50, but we want the number 2, so we subtract 48 from 50 to get 2.
And so forth.

For more characters, please see this link: https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html

sorry i comment on an old post,,
when i tried pauls code, if i type more than 5 character the value become negative. how to solve this?

when i press 111111 it become -19961

when i tried pauls code, if i type more than 5 character the value become negative. how to solve this?

Don't store the value in an int. Use a long.

Sorry to comment in this older post but I also encountered having negative values when I entered a 5-digit number. I have tried what pauls said to change int into long but still I get negative values. Hope you can read this and help me with my problem

art_a_game:
Sorry to comment in this older post but I also encountered having negative values when I entered a 5-digit number. I have tried what pauls said to change int into long but still I get negative values. Hope you can read this and help me with my problem

Please post your code.

hello everyone.

I'm trying to use this code as it is posted by PaulS only with a different lcd library:

#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LCD.h>

LiquidCrystal_I2C  lcd(0x27, 2, 1, 0, 4, 5, 6, 7);

int kdelay = 50;
int period = 0;

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

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

int v1 = 0;
int v2 = 0;





void setup() {
  lcd.begin(20, 4);
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);

}

void loop() {  
   v1 = GetNumber();
   v2 = GetNumber();
}
int GetNumber()
{
   int num = 0;
   char key = kpd.getKey();
   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            lcd.print(key);
            num = num + key;
            break;

         case '*':
            num = 0;
            lcd.clear();
            break;
      }
      key = kpd.getKey();      
   }
   return num;
}

My problem is that when I press the # button nothing happens. Everything else works. The numbers are printed on the LCD and the * button clears the LCD but.

Thanks in advance for the help

My problem is that when I press the # button nothing happens.

What are you expecting to happen? Add Serial.print() statements at the top and bottom of GetNumber(), and you'll see that something is happening.

yeah right I didn't know what I was thinking there thanks for that. I also had the negative number problem and solved it by using a string instead of an int and then converting it with toInt(). I think it should work for the others as well.

here it is:

String v1;
String v2;

void setup() {
  Serial.begin(9600);
  lcd.begin(20, 4);
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);

}

void loop() {  
   v1 = GetNumber();
   v1.toInt();
   Serial.println(v1);
   lcd.clear();
//   v2 = GetNumber();
//   Serial.println(v2);
}
String GetNumber()
{
   String num;
   char key = kpd.getKey();
   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            lcd.print(key);
            num = num +key;
            break;

         case '*':
            num = "";
            lcd.clear();
            break;
      }
      key = kpd.getKey();      
   }
   return num;
   
}

I tried PaulS code but '#' buttn is not giving any result. Can anybody help me

You read the post #13?

PaulS´hint with the Serial.print...?

Freddie

Is the #3 code a non-blocking code?

i have the same problem as hici but i cant cnfigure whats wrong i dont know where to put serial.print and how
(My problem is that when I press the # button nothing happens. Everything else works. The numbers are printed on the LCD and the * button clears the LCD but. )
always this message came to me :
conversion from 'int' to 'String' is ambiguous
i want answer fast please.

#include <Keypad.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(53, 51, 49, 47, 45, 43);

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] = {38, 40, 42, 44};
byte colPins[COLS] = {46, 48, 50, 52};

String x=0;
String y=0;

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

void setup(){
Serial.begin(9600);
pinMode(8,OUTPUT);

}

void clearscreen()
{
lcd.setCursor(0,0);
lcd.print(" ");

lcd.setCursor(0,1);
lcd.print(" ");
}

void loop(){

analogWrite(8,100);

x = GetNumber();
x.toInt();
Serial.println(x);
lcd.clear();
y = GetNumber();
y.toInt();
Serial.println(y);
lcd.clear();
}

String GetNumber()
{
String num = 0;
char key = keypad.getKey();
while(key!='#')
{
switch(key)
{
case NO_KEY:
break;
case'0': case'1': case'2': case'3': case'4':
case'5': case'6': case'7': case'8': case'9':
lcd.print(key);
num =(key-'0');
break;
case'#':
return num;
case'*':
num=0;
clearscreen();
break;
}
key = keypad.getKey();
}
return num;
}

hello frnds.... i have a problem something like this.. i need to enter a phone number using keypad and store it to send sms alerts through gsm module.. i have the code for entering one phone number and can able to read and store that number. but the problem is i need to enter 3 r 4 phone numbers... but am not getting this.. plz..hlp me.. am giving my code below...

eepromnum.ino (5.83 KB)