Reading and displaying multiple numbers from a keypad

Hi!
I promised myself I would do everything I could to get this to work without having to ask for help.
Well that didn’t happen…

The problem I have is that I want to read different numbers that are pushed on a keypad and then do something with the number like control a voltage with a DAC. For example, if I pushed 2.5, I would want it to display 2.5 on my display and then read the 2.5 input and output 2.5 volts through a DAC. For my code, I have it where it will display one number perfect like for say 2 but I cant add the .5. If I press another number it simply erases the first number and prints the second number. Secondly, I cant do anything with the number. I guess I would need to turn it into an integer to use it? I know its not in numerical form straight from the keypad but with the code I have it displays it numerically. What I want to do with the number is not attached in the code as I already have it figured out and simplifies it not having it included. Also I realize that this is really two different questions but I feel they are attached to each other.

Thank you if you have time

ps* If I replace the last line with tft.print(i); instead of tft.print(I); it displays the number I select on the keypad. Otherwise it says it was not declared. I believe this is because of the myNum
```
*#include <Keypad.h>

#include <Adafruit_GFX.h>

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

int myNum[4];

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

char hexaKeys[ROWS][COLS] = {
  {‘1’, ‘4’, ‘7’, ‘*’},
  {‘2’, ‘5’, ‘8’, ‘0’},
  {‘3’, ‘6’, ‘9’, ‘.’},
  {‘A’, ‘B’, ‘C’, ‘D’}
};

byte rowPins[ROWS] = {31, 22, 23, 24};
byte colPins[COLS] = {25, 26, 27, 28};

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

#define BLACK  0x0000
#define BLUE    0x001F
#define RED    0xF800
#define GREEN  0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE  0xFFFF

void setup() {

}

void loop()

{

for (int i = 0; i < 4; ++i) {
    while ((myNum[i] = keypad.getKey()) == NO_KEY) {
      delay(1);
    }
    while (keypad.getKey() != NO_KEY) {
      delay(1);

int I = myNum[i];

}

int number = 1;
    tft.reset();
    uint16_t id = tft.readID();
    tft.begin(id);
    tft.setRotation(1);
    tft.fillScreen(WHITE);
    tft.setTextColor(BLUE, WHITE);
    tft.setTextSize(4);
    tft.setCursor(10, 10);
    tft.print (I);
  }
}*
```

This...

int I;

Is a variable declaration. It declares a new variable “I” but does not give it a value.
The “scope” of the variable is within the braces { } where it is declared. That means it cannot be seen by any code outside of those braces (undeclared), and is completely separate from any other variable you may have defined elsewhere in your code with the same name “I” (although doing that is considered very bad practice - sort of the programming equivalent of calling both your kids “Bob”).

This...

I = myNum[i];

Is a variable assignment. It assigns a value (on the right of the equals) to the variable (on the left).

This...

int I = myNum[i];

Is c/c++ shorthand for a new declaration and an assignment in a single step.
Note that the “scope“ of the variable is still within the braces { } where it is defined.

I is also a very bad choice of variable names. In certain fonts I, i, l, 1 all look very similar. But C is case sensitive with regard to naming. Try to give your variables meaningful names. numberEntered would be a good choice perhaps.

Okay I mostly follow you. I have since changed the name of the variable and deleted one of the braces so that all of the keypadNumber are in the same set of braces. Now when I uploaded it all I have is a white screen and pressing the keypad keys doesn’t change anything.

Here is my new code

#include <Keypad.h>

#include <Adafruit_GFX.h>

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

int myNum[4];

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

char hexaKeys[ROWS][COLS] = {
  {'1', '4', '7', '*'},
  {'2', '5', '8', '0'},
  {'3', '6', '9', '.'},
  {'A', 'B', 'C', 'D'}
};

byte rowPins[ROWS] = {31, 22, 23, 24};
byte colPins[COLS] = {25, 26, 27, 28};

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


#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF




void setup() {

}


void loop()


{

  for (int i = 0; i < 4; ++i) {
    while ((myNum[i] = keypad.getKey()) == NO_KEY) {
      delay(1);
    }
    while (keypad.getKey() != NO_KEY) {
      delay(1);


      int keypadNumber = myNum[i];



      int number = 1;
      tft.reset();
      uint16_t id = tft.readID();
      tft.begin(id);
      tft.setRotation(1);
      tft.fillScreen(WHITE);
      tft.setTextColor(BLUE, WHITE);
      tft.setTextSize(4);
      tft.setCursor(10, 10);
      tft.print (keypadNumber);
    }
  }
}

Braces have meaning for other things, you can’t just go deleting them.
You need to separate your declaration and your assignment to the variable.
Declaration outside the braces (at least to the same level as everywhere you want to use it), assignment possibly inside some braces, if that’s where it is needed. This is what is meant by “scope”.

Edit: Your code now reads...
While no key was available, wait until you get one
While you get a key press display something

Trouble is, after you have just got a key (first while has just terminated), there won’t be another key to get - you can’t press keys that fast - so you’ll never go in the second while and you will never display anything.

Okay thanks. You said to declare it everywhere so would that be at the beginning of the code? Sorry I have a hard time following.

roessleralec:
Okay thanks. You said to declare it everywhere so would that be at the beginning of the code? Sorry I have a hard time following.

As a global you mean? If you want, but at the start of loop() will do. Generally you should only make things global if really necessary.

In this case "keypadNumber" is used ONLY in loop(), and does not need to maintain its value over multiple calls to loop. So it doesn't need to be global. Good practice would be to declare it ONLY with in the "scope" of the code where it is needed (loop in this case).

void loop()
{
  int keypadNumber;
  ...
  ...
}

I understand you now thanks. However I still can't display the keypadnumber on my screen. How would I for say turn it into an int and display it?

I have since tried out some new code and modified it. Now I can press keys on the keypad and multiple numbers will show up on the display like for example 1234. But the problem now is that if I press 1 then a 1 shows up but then if I press a 2 a 1 shows up again but if I press a 2 a second time then a 2 shows up. If I then press 3 then two shows up unless I press 3 again. How could I fix this?

Here is the new code

#include <Keypad.h>

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;


String v1;


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

char hexaKeys[ROWS][COLS] = {
  {'1', '4', '7', '*'},
  {'2', '5', '8', '0'},
  {'3', '6', '9', '.'},
  {'A', 'B', 'C', 'D'}  //rearranged for correct numbers to show up
};

byte rowPins[ROWS] = {31, 22, 23, 24};
byte colPins[COLS] = {25, 26, 27, 28};

Keypad kpd = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define DATAOUT 11//MOSI
#define DATAIN 12//MISO - not used, but part of builtin SPI
#define SPICLOCK  13//sck
#define SLAVESELECT0 10//ss

void setup()
{
  
}

void loop() {
  v1 = GetNumber();
  v1.toInt();
}
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':
        tft.reset();
        uint16_t id = tft.readID();
        tft.begin(id);
        tft.setRotation(1);
        tft.fillScreen(WHITE);
        tft.setTextColor(BLUE, WHITE);
        tft.setTextSize(5);
        tft.setCursor(10, 50);
        tft.print(num);
        num = num + key;
        break;

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

}