Need help with saving written text into string

Hello i have a problem with this project im trying to finish, it's about typing from a Keypad and alphanumeric text typed will be display in lcd screen, i want to store every wrote char into a String, size of lcd display max 15 chars i guess.
This is the code, its not complete but it only needs some more "switch cases" for the other keypad buttons, and an attempt i made to solve this but it does not work as intended. i might be able to upload the code if needed.

#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8);  
#include <Keypad.h>
const byte filas = 4;     //number of rows
const byte columnas = 4;  //Number of columns 

//Define a matrix 4x4 with pos of rows and columns
char matriz[filas][columnas] =
{

  { '1', '2', '3', 'A'},
  { '4', '5', '6', 'B'},
  { '7', '8', '9', 'C'},
  { '*', '0', '#', 'D'},

};

byte pinesFilas[filas] = {22, 24, 26, 28};       //key pad rows pins
byte pinesColumnas[columnas] = {30, 32, 34, 36}; //Keypad column pins

//Initialize the keyboard with the number of rows, columns, the Arduino pins used and the matrix
Keypad teclado = Keypad( makeKeymap(matriz), pinesFilas, pinesColumnas, filas, columnas);

//Variables to control cursor position.
int posX = 0;
int posY = 0;

//Variables to control keys
char presionando;    // holding key
int veces_presionada = 0;   // times_pressed
int mayuscula_activada = 0; //mayus_ON
int mostrar_cursorPantalla = 1; //show_cursor on screen
int contador = 0;  //counter
// Variables for the control of the counter, since no delay () is used in this code
unsigned long tiempo_anterior = 0;
int periodo = 500;  //500 millisecconds

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);                    //Initializing screen
  lcd.setCursor(3, 0);
  lcd.print("Escribe un");
  lcd.setCursor(4, 1);
  lcd.print("mensaje");
  delay(2000);
  lcd.clear();
}

void loop() {
  char tecla_presionada = teclado.getKey();  //Store the key pressed
   /*String outputString="";// This comented seccion is my attempt to save the text but it only saves 
                                                 keypad value not the written text.
      if(tecla_presionada){
      Serial.println(tecla_presionada);
      outputString.concat(tecla_presionada);
     //lcd.write(Serial.read());
      Serial.println(outputString);
  }*/
  if (millis() > tiempo_anterior + periodo)  //Conditional to evaluate if 500 milliseconds passed
  {
    tiempo_anterior = millis();

// If 500 milliseconds passed and there was a key pressed, the counter increases by +1
    if (veces_presionada > 0)
    {
      contador++;

      if (contador == 3)            // If the counter reaches 3, the cursor advances a position
      {
        posX++;
        veces_presionada = 0;
      }
    }

    mostrar_cursorPantalla++;     // Variable for the control of the blinking of the cursor

    if (mostrar_cursorPantalla > 1)
    {
      mostrar_cursorPantalla = 0;
    }
  }

  if (mostrar_cursorPantalla == 1)    // Show the cursor on the screen
  {
    lcd.setCursor(posX, posY);
    lcd.cursor();
  }

  if (mostrar_cursorPantalla == 0)   // Hide the cursor on the screen
  {
    lcd.setCursor(posX, posY);
    lcd.noCursor();
  }

  if (posX > 15)       // The position in X can not be greater than 15 (the X axis goes from 0 to 15)
  {
    posX = 0;
    posY++;
  }

  if (posX < 0)       // The position in X can not be less than 0
  {
    posX = 0;
  }

  if (posY > 1)      // The position in Y can not be greater than 1 (the Y axis goes from 0 to 1)
  {
    posY = 0;
  }

  switch (tecla_presionada)        // Switch-case according to the key pressed
  {
    case 'A':                      // The A key is the spacebar. Increase the cursor position by +1
      posX++;
      veces_presionada = 0;
     // data[tecla_presionada];
      break;

    case 'B':                     // The B key is used to erase the previous character written
      posX--;
      lcd.setCursor(posX, posY);
      lcd.print(" ");
      veces_presionada = 0;
      break;

    case 'C':     // The C key erases EVERYTHING written on the screen and positions the cursor at (0,0)
      lcd.clear();
      posX = 0;
      posY = 0;
      veces_presionada = 0;
      break;

    case 'D':                   // The D key moves the cursor on the Y axis
      posY++;
      veces_presionada = 0;
      break;

    case '0':
    // Conditional so that the cursor advances if a different key was previously pressed
      if (presionando != '0' && veces_presionada > 0)
      {
        posX++;
        veces_presionada = 0;
      }

      lcd.setCursor(posX, posY);
      veces_presionada++;
      contador = 0;
      presionando = '0';

      if (veces_presionada > 5)
      {
        veces_presionada = 1;
      }

      if (veces_presionada == 1)
      {
        lcd.print('+');
      }

      if (veces_presionada == 2)
      {
        lcd.print('-');
      }

      if (veces_presionada == 3)
      {
        lcd.print('*');
      }

      if (veces_presionada == 4)
      {
        lcd.print('/');
      }

      if (veces_presionada == 5)
      {
        lcd.print('0');
      }
      break;

    case '*':                    // The * key activates and deactivates the capital letters
      mayuscula_activada++;

      if (mayuscula_activada > 1)
      {
        mayuscula_activada = 0;
      }
      break;

    case '#':
      // Conditional so that the cursor advances if a different key was previously pressed
      if (presionando != '#' && veces_presionada > 0)
      {
        posX++;
        veces_presionada = 0;
      }

      lcd.setCursor(posX, posY);
      veces_presionada++;
      contador = 0;
      presionando = '#';

      if (veces_presionada > 5)
      {
        veces_presionada = 1;
      }

      if (veces_presionada == 1)
      {
        lcd.print('>');
      }

      if (veces_presionada == 2)
      {
        lcd.print('<');
      }

      if (veces_presionada == 3)
      {
        lcd.print('=');
      }

      if (veces_presionada == 4)
      {
        lcd.print('!');
      }

      if (veces_presionada == 5)
      {
        lcd.print('#');
      }
      break;

    case '1':
// Conditional so that the cursor advances if a different key was previously pressed
      if (presionando != '1' && veces_presionada > 0)
      {
        posX++;
        veces_presionada = 0;
      }

      lcd.setCursor(posX, posY);
      veces_presionada++;
      contador = 0;
      presionando = '1';

      if (veces_presionada > 5)
      {
        veces_presionada = 1;
      }

      if (veces_presionada == 1)
      {
        lcd.print('(');
      }

      if (veces_presionada == 2)
      {
        lcd.print(')');
      }

      if (veces_presionada == 3)
      {
        lcd.print('.');
      }

      if (veces_presionada == 4)
      {
        lcd.print(',');
      }

      if (veces_presionada == 5)
      {
        lcd.print('1');
      }
      break;

    case '2':
     // Conditional so that the cursor advances if a different key was previously pressed
      if (presionando != '2' && veces_presionada > 0)
      {
        posX++;
        veces_presionada = 0;
      }

      lcd.setCursor(posX, posY);
      veces_presionada++;
      contador = 0;
      presionando = '2';

      if (veces_presionada > 4)
      {
        veces_presionada = 1;
      }

      if (veces_presionada == 1)
      {
        if (mayuscula_activada == 1 || (posX == 0 && posY == 0))
        {
          lcd.print('A');
        }
        else
        {
          lcd.print('a');
        }
      }

      if (veces_presionada == 2)
      {
        if (mayuscula_activada == 1 || (posX == 0 && posY == 0))
        {
          lcd.print('B');
        }
        else
        {
          lcd.print('b');
        }
      }

      if (veces_presionada == 3)
      {
        if (mayuscula_activada == 1 || (posX == 0 && posY == 0))
        {
          lcd.print('C');
        }
        else
        {
          lcd.print('c');
        }
      }

      if (veces_presionada == 4)
      {
        lcd.print('2');
      }
      break;
 }
}

To make it easy for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

Also please use the AutoFormat tool to indent your code for easier reading.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

I have already modifed my post, im still trying to solve this with cStrings, thanks for the help any other kind of tip would be appreciated.

Post the latest version of your program in a new Reply. I don't see any attempt to use a cstring in the code in the Original Post.

...R

ok, heres the latest version of the code its been translated, but it works fine i just tested it.
im using a generic keypad i attached an image, also using arduino mega, what this code basicly does is printing a character for example: if i press 1 it will print "(" or ")" or "." or ","or "1", and prints it on lcd screen, if i press 2 it will print "A", or "b", or "c", or "2" with consecutive key pressing, if i stop pressing the key, cursor will step one pos and goes on and on, etc. I want to know if theres a way to store that printed char such as"a,b,c,2,4,etc" into a String.

translated_code.ino (14.8 KB)

61JPRn6su1L.SX425.jpg

...
...
String text;

...
...

void setup()
{
  ...
  ...
}

void loop()
{
  ...
  ...
}

Every time that you print to the lcd, you can add the character to the text variable using

text += somechar;

where somechar is what you have just written to the lcd (e.g. 'A', 'b' etc).

Be aware that heavy use of String (capital S) will eventually bite you due to the fact that you can easily run out of memory. One way to alleviate (not solve) that problem is by reserving a number of bytes for the String variable. In above example, use text.reserve(33) in setup() for 2x16 characters plus a terminating '\0'.

Instead of String, you can use c-strings; you will have to set a maximum number of characters that you want to store. Below uses again 33.

...
...
char text[33];
byte index;

...
...

void setup()
{
  ...
  ...
}

void loop()
{
  ...
  ...
}

This declares a character array and an index variable to keep track where you want to place the character in the array (valid values 0..32).

Again, every time that you print to the lcd, you can add the character to the text variable using

if (index < sizeof(text) -1)
{
  text[index++] = somechar;
}

The if statement is needed to prevent you from adding the character outside the array.

When you want to clear the array, it's basically sufficient to set index back to 0. It depends on the rest of the code if you also need to clear the first byte or the complete array. Clearing the complete array

// clear buffer
memset(text, 0, sizeof(text));
// reset index
index = 0;

Note:
you might also want to save the space.

===

There is an unwritten rule that a single function must fit on a single A4 page (without cheating with the font size :wink: ). Your loop() is far too big from that perspective :wink:

@Tom512
I can't find an OutputStreamWriter in the default Arduino libraries; what does one need to install?

@OP

Please, begin with something what we call basic unit. Basic has been defined as a unit that is simple and elementary. Once the first basic unit is completed, add the next basic unit and test it. This is known as SSS (Small Start Strategy) Methodology. There are many functionalities that you want to achieve with your Keypad project which I think you can accomplish comfortably by SSS Strategy.

1. Let us develop a program to accept any three alphanumerical charcaters (now upper case A, B, C, D) from the Keypad; show the characters on the Top Line of the LCD as they (characters) are entered from the Keypad; save the charcaters in a character type array named char myArray[4] as they (characters) are entered from the Keypad; at the end of the entry of 3 charcaters, let us show the content of the array on the Bottom Line of the LCD.
kbBlk-mega.png

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
#include <Keypad.h>

char myArray[4] = ""; // to hold ASCII codes of keys
byte keyCounter = 0; // to count number of keys pressed

const byte filas = 4;     //number of rows
const byte columnas = 4;  //Number of columns

//Define a matrix 4x4 with pos of rows and columns
char matriz[filas][columnas] =
{

  { '1', '2', '3', 'A'},
  { '4', '5', '6', 'B'},
  { '7', '8', '9', 'C'},
  { '*', '0', '#', 'D'},

};

byte pinesFilas[filas] = {22, 24, 26, 28}; //R1R2R3R4=22242628 key pad rows pins
byte pinesColumnas[columnas] = {30, 32, 34, 36}; //C1C2C3C4=30323436 Keypad column pins

//Initialize the keyboard with the number of rows, columns, the Arduino pins used and the matrix
Keypad teclado = Keypad( makeKeymap(matriz), pinesFilas, pinesColumnas, filas, columnas);

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);                    //Initializing screen
  lcd.setCursor(0, 0);  //1st column Top line
  lcd.clear();
}

void loop()
{
  char tecla_presionada = teclado.getKey();  //Store the key pressed
  if (tecla_presionada != 0) //Key has been pressed
  {
    lcd.print(tecla_presionada); //show on LCD
    myArray[keyCounter] = tecla_presionada; //save in array
    keyCounter++;   //increment keyCounter
    if (keyCounter == 3)  //3 charctaers are entered
    {
      lcd.setCursor(0, 1);  //1st column Bottom Line
      lcd.print(myArray); //show 3-character on Bottom Line
      delay (5000); //wait for 5-sec
      lcd.clear(); //clear LCD
      lcd.setCursor(0, 0); //cursor at 1st column at Top Line
      myArray[4] = "";  //reset array
      keyCounter = 0; //reset keyCounter
    }
  }
}

2. Now add codes with the program of Step-1 so that after the entry of 3-character, there is a gap (space) (this idea is in your original sketch) and then the LCD (array) accepts 3-more characters. This way, you can enter 3-block of characters each block contains 4 characters including the space. And so on (other functionalities).....

kbBlk-mega.png

I would first remove the (nearly) duplicate cases for '0'..'9'. It will make life easier for a next step.

You can store the possible characters for the numeric keys in a two-dimensional array.

// array of characters associated with each numeric key on the keypad
const char numericCharacters[][5] =
{
  {'+', '-', '*', '/', '0'},  // 0
  {'(', ')', '.', ',', '1'},  // 1
  {'a', 'b', 'c', '2', 0},    // 2; 0 indicates 'not an option'
  {'d', 'e', 'f', '3', 0},    // 3
  {'g', 'h', 'i', '4', 0},    // 4
  {'j', 'k', 'l', '5', 0},    // 5
  {'m', 'n', 'o', '6', 0},    // 6
  {'p', 'q', 'r', 's', '7'},  // 7
  {'t', 'u', 'v', '8', 0},    // 8
  {'w', 'x', 'y', 'z', '9'},  // 9
};

Each row in above is associated with one of the keys '0'..'9'. In each row, we have the characters that are associated with the number of times that a key is pressed. Because you sometimes have a maximum of 4 key presses and sometimes a maximum of 5, the array has 5 columns to fit it all. To be able to identify if a row has 4 or 5 columns, the 5th column contains the value 0 (not the character '0') if the maximum pressed_times equals 4 in your existing code.

Now you can write a function that takes a character (pressed_key) and converts that to one of the values in the array.

/*
  handle an numeric key
  In
   pressed key
  Returns
   0 on error, else character based on pressed key and the number of times it's pressed
*/
char handleNumeric(char pressed_key)
{
  // character related to number of numeric presses
  char ch = 0;

  Serial.print("[Debug]"); Serial.println(pressed_key);
  Serial.print("[Debug]press_times = "); Serial.println(press_times);

  // just a safeguard
  if (pressed_key < '0' || pressed_key > '9')
  {
    Serial.println("[Debug]you called handleNumeric and did not pass 0..9");
    // hang forever
    for (;;);
  }

  // subtracting the ascii value for '0' from the pressed_key gives us the index in the 'numericCharacters' array
  byte numericIndex = pressed_key - '0';
  // get the number of valid characters;
  byte numValidChars;
  for (numValidChars = 0; numValidChars < sizeof(numericCharacters[0]); numValidChars++)
  {
    if (numericCharacters[numericIndex][numValidChars] == 0)
    {
      break;
    }
  }
  Serial.print("[Debug]number of valid chars = "); Serial.println(numValidChars);
  if (numValidChars == 0)
  {
    Serial.println("[Debug]you need at least one valid character in each row in the 'characters' array");
    // hang forever
    for (;;);
  }

  // overflow
  if (press_times > numValidChars)
  {
    press_times = 1;
  }

  // get the character associated with the number of presses; number of presses starts at 1 so subtract 1
  ch = numericCharacters[numericIndex][press_times - 1];
  Serial.print("[Debug]character = "); Serial.println(ch);
  return ch;
}

I think the code explains itself; if not, ask.

Next you can do the same thing for the '#' key. This can be a one-dimensional array.

// array of characters associated with the hash key on the keypad
char hashCharacters[5] =
{
  '>', '<', '=', '!', '#'
};

And the function to return a character based on the number of times that the '#' was pressed

/*
  handle the hash key
  In
   pressed key
  Returns
   0 on error, else character based on pressed key and the number of times it's pressed
*/
char handleHash(char pressed_key)
{
  // character related to number of numeric presses
  char ch = 0;

  Serial.print("[Debug]"); Serial.println(pressed_key);
  Serial.print("[Debug]press_times = "); Serial.println(press_times);

  // just a safeguard
  if (pressed_key != '#')
  {
    Serial.println("[Debug]you called handleHash and did not pass #");
    // hang forever
    for (;;);
  }

  // get the number of valid characters;
  byte numValidChars;
  for (numValidChars = 0; numValidChars < sizeof(hashCharacters); numValidChars++)
  {
    if (hashCharacters[numValidChars] == 0)
    {
      break;
    }
  }
  Serial.print("[Debug]number of valid chars = "); Serial.println(numValidChars);
  if (numValidChars == 0)
  {
    Serial.println("[Debug]you need at least one valid character in the 'hash' array");
    // hang forever
    for (;;);
  }

  if (press_times > numValidChars)
  {
    press_times = 1;
  }

  // get the character associated with the number of presses; number of presses starts at 1 so subtract 1
  ch = hashCharacters[press_times - 1];
  Serial.print("[Debug]character = "); Serial.println(ch);
  return ch;
}

You can still optimise and combine the functions in one, but for now this will do.

Now you can simplify the switch. The case for the '#'

    case '#':
      //Conditional to advance the cursor if a different key was previously pressed
      if (pressing != pressed_key && press_times > 0)
      {
        posX++;
        press_times = 0;
      }

      lcd.setCursor(posX, posY);
      press_times++;
      counter = 0;
      pressing = pressed_key;

      ch = handleHash(pressed_key);

      lcd.print(ch);
      Serial.print("Printed on lcd = "); Serial.println(ch);

      break;

And the case for the numeric keys

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      //Conditional to advance the cursor if a different key was previously pressed
      if (pressing != pressed_key && press_times > 0)
      {
        posX++;
        press_times = 0;
      }

      lcd.setCursor(posX, posY);
      press_times++;
      counter = 0;
      pressing = pressed_key;

      ch = handleNumeric(pressed_key);
      // if ch equals 'a'..'z' and we need uppercase
      if (isAlpha(ch) == true &&
          (uppercase_activated == 1 || (posX == 0 && posY == 0))
         )
      {
        // there is a fixed offset in the ascii table between lowercase and uppercase characters
        // subtarcting 0x20 from lowercase gives uppercase
        ch -= 0x20;
      }

      lcd.print(ch);
      Serial.print("Printed on lcd = "); Serial.println(ch);

      break;

You will need to add the following line at the beginning of loop

  // the character after conversion
  char ch;

Notes:
1)
Your original code compared pressing against hard-coded values for each case. The new code above compares pressing against pressed_key
2)
There is still a bit of duplication but that can be sorted later if needed.

This reduces the number of lines of your code by over 50%. More importantly, it reduces the number of places where you have to store the character in a String or c-string.

Additional notes:
1)
I did not have a setup with keypad and lcd so tested this with serial input and output.
2)
You have an 'bug' in your timing code; you should not add, only subtract.

To prevent you from making mistakes in copying, below the full code; there are no changes to setup and to make it fit within 9000 character limit, I create a placeholder for it

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8); //Pin where the display is connected (RS, E, D4, D5, D6, D7)
#include <Keypad.h>
const byte rows = 4; //Number of keyboard rows
const byte columns = 4; //Number of keyboard columns

//I define a 4x4 matrix with the position of the rows and columns.
char matrix[rows][columns] =
{
  { '1', '2', '3', 'A'},
  { '4', '5', '6', 'B'},
  { '7', '8', '9', 'C'},
  { '*', '0', '#', 'D'},
};

byte pinsRows[rows] = {22, 24, 26, 28}; //Pins where the keyboard rows are connected.
byte pinsColumns[columns] = {30, 32, 34, 36}; //Pins where keyboard columns are connected

//I start the keyboard with the number of rows, columns, the Arduino pins used and the matrix.
Keypad key = Keypad( makeKeymap(matrix), pinsRows, pinsColumns, rows, columns);

//Variables for cursor position control
int posX = 0;
int posY = 0;

//Variales for the control of the keys
char pressing;
int press_times = 0;  //times_pressed key
int uppercase_activated = 0;
int show_cursorScreen = 1;
int counter = 0;
//Variables for counter control, since no delay() is used in this code.
unsigned long previous_time = 0;
int period = 500; //500 milliseconds

// array of characters associated with each numeric key on the keypad
const char numericCharacters[][5] =
{
  {'+', '-', '*', '/', '0'},  // 0
  {'(', ')', '.', ',', '1'},  // 1
  {'a', 'b', 'c', '2', 0},    // 2; 0 indicates 'not an option'
  {'d', 'e', 'f', '3', 0},    // 3
  {'g', 'h', 'i', '4', 0},    // 4
  {'j', 'k', 'l', '5', 0},    // 5
  {'m', 'n', 'o', '6', 0},    // 6
  {'p', 'q', 'r', 's', '7'},  // 7
  {'t', 'u', 'v', '8', 0},    // 8
  {'w', 'x', 'y', 'z', '9'},  // 9
};

// array of characters associated with the hash key on the keypad
char hashCharacters[5] =
{
  '>', '<', '=', '!', '#'
};

// Hallo = *44*2555 555666


void setup()
{
  ...
  ...
}

void loop()
{
  // the character after conversion; will be remembered
  char ch;

  char pressed_key = key.getKey(); //Save the key pressed

  // for use with serial monitor
  if (Serial.available() > 0)
  {
    pressed_key = Serial.read();
    Serial.print("key = "); Serial.println(pressed_key);
    //lastKeypressTime = millis();
  }
  else
  {
    pressed_key = 0;
  }

  if (millis() > previous_time + period) //Conditional to assess whether 500 milliseconds have elapsed
  {
    previous_time = millis();

    //If 500 milliseconds have elapsed and a key has been pressed, the counter increases by +1.
    if (press_times > 0)
    {
      counter++;

      if (counter == 3) //If the counter reaches 3, the cursor advances one position.
      {
        posX++;
        press_times = 0;
      }
    }

    show_cursorScreen++; //Variable for cursor flicker control

    if (show_cursorScreen > 1)
    {
      show_cursorScreen = 0;
    }
  }

  if (show_cursorScreen == 1) // Displays the cursor on the screen
  {
    lcd.setCursor(posX, posY);
    lcd.cursor();
  }

  if (show_cursorScreen == 0) //Hide the cursor on the screen
  {
    lcd.setCursor(posX, posY);
    lcd.noCursor();
  }

  if (posX > 15) //The position in X cannot be greater than 15 (the X axis goes from 0 to 15)
  {
    posX = 0;
    posY++;
  }

  if (posX < 0) //The position in X cannot be less than 0
  {
    posX = 0;
  }

  if (posY > 1) //The Y position cannot be greater than 1 (the Y axis goes from 0 to 1)
  {
    posY = 0;
  }

  switch (pressed_key) //Switch-case according to the pressed key
  {
    case 'A': //The A key is the spacer. Increases cursor position by +1
      posX++;
      press_times = 0;
      // data[key_pressed];
      break;
    case 'B': //The B key is used to delete the previous written character
      posX--;
      lcd.setCursor(posX, posY);
      lcd.print(" ");
      press_times = 0;
      break;
    case 'C': //The C key deletes ALL that is written on the screen and positions the cursor at (0,0)
      lcd.clear();
      posX = 0;
      posY = 0;
      press_times = 0;
      break;
    case 'D': //The D key moves the cursor on the Y axis
      posY++;
      press_times = 0;
      break;
    case '*': //The * key activates and deactivates capital letters
      uppercase_activated++;
      if (uppercase_activated > 1)
      {
        uppercase_activated = 0;
      }
      break;
    case '#':
      //Conditional to advance the cursor if a different key was previously pressed
      if (pressing != pressed_key && press_times > 0)
      {
        posX++;
        press_times = 0;
      }

      lcd.setCursor(posX, posY);
      press_times++;
      counter = 0;
      pressing = pressed_key;

      ch = handleHash(pressed_key);
      lcd.print(ch);
      Serial.print("Printed on lcd = "); Serial.println(ch);
      break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      //Conditional to advance the cursor if a different key was previously pressed
      if (pressing != pressed_key && press_times > 0)
      {
        posX++;
        press_times = 0;
      }

      lcd.setCursor(posX, posY);
      press_times++;
      counter = 0;
      pressing = pressed_key;

      ch = handleNumeric(pressed_key);
      // if ch equals 'a'..'z' and we need uppercase
      if (isAlpha(ch) == true &&
          (uppercase_activated == 1 || (posX == 0 && posY == 0))
         )
      {
        // there is a fixed offset in the ascii table between lowercase and uppercase characters
        // subtarcting 0x20 from lowercase gives uppercase
        ch -= 0x20;
      }
      lcd.print(ch);
      Serial.print("Printed on lcd = "); Serial.println(ch);
      break;
  }
}

/*
  handle an numeric key
  In
   pressed key
  Returns
   0 on error, else character based on pressed key and the number of times it's pressed
*/
char handleNumeric(char pressed_key)
{
  // character related to number of numeric presses
  char ch = 0;

  Serial.print("[Debug]"); Serial.println(pressed_key);
  Serial.print("[Debug]press_times = "); Serial.println(press_times);

  // just a safeguard
  if (pressed_key < '0' || pressed_key > '9')
  {
    Serial.println("[Debug]you called handleNumeric and did not pass 0..9");
    // hang forever
    for (;;);
  }

  // subtracting the ascii value for '0' from the pressed_key gives us the index in the 'numericCharacters' array
  byte numericIndex = pressed_key - '0';
  // get the number of valid characters;
  byte numValidChars;
  for (numValidChars = 0; numValidChars < sizeof(numericCharacters[0]); numValidChars++)
  {
    if (numericCharacters[numericIndex][numValidChars] == 0)
    {
      break;
    }
  }
  Serial.print("[Debug]number of valid chars = "); Serial.println(numValidChars);
  if (numValidChars == 0)
  {
    Serial.println("[Debug]you need at least one valid character in each row in the 'characters' array");
    // hang forever
    for (;;);
  }

  // overflow
  if (press_times > numValidChars)
  {
    press_times = 1;
  }

  // get the character associated with the number of presses; number of presses starts at 1 so subtract 1
  ch = numericCharacters[numericIndex][press_times - 1];
  Serial.print("[Debug]character = "); Serial.println(ch);
  return ch;
}

/*
  handle the hash key
  In
   pressed key
  Returns
   0 on error, else character based on pressed key and the number of times it's pressed
*/
char handleHash(char pressed_key)
{
  // character related to number of numeric presses
  char ch = 0;

  Serial.print("[Debug]"); Serial.println(pressed_key);
  Serial.print("[Debug]press_times = "); Serial.println(press_times);

  // just a safeguard
  if (pressed_key != '#')
  {
    Serial.println("[Debug]you called handleHash and did not pass #");
    // hang forever
    for (;;);
  }

  // get the number of valid characters;
  byte numValidChars;
  for (numValidChars = 0; numValidChars < sizeof(hashCharacters); numValidChars++)
  {
    if (hashCharacters[numValidChars] == 0)
    {
      break;
    }
  }
  Serial.print("[Debug]number of valid chars = "); Serial.println(numValidChars);
  if (numValidChars == 0)
  {
    Serial.println("[Debug]you need at least one valid character in the 'hash' array");
    // hang forever
    for (;;);
  }

  if (press_times > numValidChars)
  {
    press_times = 1;
  }

  // get the character associated with the number of presses; number of presses starts at 1 so subtract 1
  ch = hashCharacters[press_times - 1];
  Serial.print("[Debug]character = "); Serial.println(ch);
  return ch;
}

Note:
In the full code in my previous reply I did forget to remove the serial reading that replaced the keypad.

To get the characters in a character array, we first declare the character array. I've decided to use posX and posY for the
indexing so no additional index variable.

...
...
// array to text; size is 2x16 plus 1
char text[33];

void setup()

...
...

For the hash key, we add some code after we printed the character to the lcd

    case '#':
      ...
      ...
      lcd.print(ch);
      text[(posY * 16) + posX] = ch;
      Serial.print("[Debug]Currently on lcd = '"); Serial.print(text); Serial.println("'");
      break;

We do the same for the numeric keys

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      ...
      ...
      lcd.print(ch);
      text[(posY * 16) + posX] = ch;
      Serial.print("[Debug]Currently on lcd = '"); Serial.print(text); Serial.println("'");
      break;

For the 'C' key, we clear the character array.

    case 'C': //The C key deletes ALL that is written on the screen and positions the cursor at (0,0)
      // clear the display
      lcd.clear();
      // clear the character array
      memset(text, 0, sizeof(text));
      Serial.print("[Debug]Currently on lcd = '"); Serial.print(text); Serial.println("'");
      
      posX = 0;
      Serial.print("[Debug]'C' posX = "); Serial.println(posX);
      posY = 0;
      press_times = 0;
      break;

The tricky parts are case 'A': and case 'B':. I've added a restriction that the 'A' and 'B' are only honoured if press_times equals 0. If you want it differently, you will need to figure it out yourself.

    case 'A': //The A key is the spacer. Increases cursor position by +1
      if (press_times == 0)
      {
        Serial.print("[Debug]'A' index = "); Serial.println((posY * 16) + posX);
        text[(posY * 16) + posX] = ' ';
        Serial.print("[Debug]Currently on lcd = '"); Serial.print(text); Serial.println("'");

        if (posX < 15)
        {
          posX++;
        }
        else
        {
          posX = 0;
          posY++;
          if (posY > 1)
          {
            posY = 0;
          }
        }
        Serial.print("[Debug]'A' posX = "); Serial.println(posX);
      }
      else
      {
        Serial.println("[Debug]'A' ignored");
      }
      break;
    case 'B': //The B key is used to delete the previous written character
      if (press_times == 0)
      {
        if (posX > 0)
        {
          posX--;
        }
        Serial.print("[Debug]'B' posX = "); Serial.println(posX);
        lcd.setCursor(posX, posY);
        lcd.print(" ");
        //press_times = 0;

        text[(posY * 16) + posX] = '\0';
        Serial.print("[Debug]Currently on lcd = '"); Serial.print(text); Serial.println("'");
      }
      else
      {
        Serial.println("[Debug]'B' ignored");
      }
      break;

I've also added some, what I think are needed, bug fixes for those two cases.

I did mention a bug in your timing code. You can replace

if (millis() > previous_time + period)

by

if (millis() - previous_time >= period)

Your loop() code is still massive. You can consider to move the part between char pressed_key = key.getKey(); //Save the key pressed and switch (pressed_key) into one or two function(s) with appropriate name(s). E.g.

/*
  Description here 
 */
void functionWithAppropriateName()
{
  // bug fix
  if (millis() - previous_time >= period) //Conditional to assess whether 500 milliseconds have elapsed
  {
    previous_time = millis();

    //If 500 milliseconds have elapsed and a key has been pressed, the counter increases by +1.
    if (press_times > 0)
    {
      counter++;

      if (counter == 3) //If the counter reaches 3, the cursor advances one position.
      {
        posX++;
        Serial.print("[Debug]TO posX = "); Serial.println(posX);
        press_times = 0;
      }
    }

    show_cursorScreen++; //Variable for cursor flicker control

    if (show_cursorScreen > 1)
    {
      show_cursorScreen = 0;
    }
  }

  if (show_cursorScreen == 1) // Displays the cursor on the screen
  {
    lcd.setCursor(posX, posY);
    lcd.cursor();
  }

  if (show_cursorScreen == 0) //Hide the cursor on the screen
  {
    lcd.setCursor(posX, posY);
    lcd.noCursor();
  }

  if (posX > 15) //The position in X cannot be greater than 15 (the X axis goes from 0 to 15)
  {
    posX = 0;
    Serial.print("[Debug]posX = "); Serial.println(posX);
    posY++;
  }

  if (posX < 0) //The position in X cannot be less than 0
  {
    Serial.print("[Debug]posX = "); Serial.println(posX);
    posX = 0;
  }

  if (posY > 1) //The Y position cannot be greater than 1 (the Y axis goes from 0 to 1)
  {
    posY = 0;
  }
}

And the beginning of loop()

void loop()
{
  // the character after conversion; will be remembered
  char ch;

  char pressed_key = key.getKey(); //Save the key pressed

  functionWithAppropriateName();

  switch (pressed_key) //Switch-case according to the pressed key
  ...
  ...
}

Good luck, hope this helps you on the way.

Thank you very much everyone for the feedback, especially sterretje, savior!, I implemented everything you said and it worked, finally I was able to get the String, I made the "D" button to print the chain, instead of going up / down on the Y axis, I wanted to get this String because I will add an NRF24L01 to this project, with this module which works as Rx and Tx at a frequency of 2.4ghz and there are several examples of Send a String or integer / floating data to another Arduino, serial communication basicly. Maybe new troubles will come up, ill make a new post but you guys are awesome, I appreciate all of your help ty!!.

I hope you understood it all. I did not use a String (capital S), by the way, and you should not either.