Inserimento dati da keypad e visualizzazione su lcd

Buonasera a tutti,

apro questo topic per chiedere alcune informazioni riguardo l’inserimento di variabili da tastiera.
Per iniziare, studiando le diverse fonti, ho realizzato il programma riportato in seguito, grazie al quale è possibile digitare dei numeri, eventualmente cancellarli ed assegnarli ad una variabile, il tutto visualizzando ciò che accade attraverso uno schermo lcd.

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

LiquidCrystal_I2C lcd(0x27, 20, 4);

const byte righe = 4;                 
const byte colonne = 3;                 

char chiave[righe][colonne] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte pinrighe[righe] = {2, 3, 4, 5};
byte pincolonne[colonne] = {6, 7, 8};

Keypad keypad = Keypad( makeKeymap(chiave), pinrighe, pincolonne, righe, colonne );

char tastobattuto;                      // variabile di memorizzazione del carattere battuto
int i = 0;
int j = 0;
const int lunghezza_stringhe = 3;
char temperatura1[lunghezza_stringhe];
char temperatura2[lunghezza_stringhe];
int flag = 0;


void setup() {
  lcd.init();                           
  lcd.backlight();                      
 
  lcd.setCursor(3, 1);
  lcd.print("per confermare");
  delay(1000);
  lcd.setCursor(1, 2);
  lcd.print("digitare asterisco");
  delay(2000);
  lcd.clear();
  lcd.setCursor(3, 1);
  lcd.print("per cancellare");
  delay(1000);
  lcd.setCursor(0, 2);
  lcd.print("digitare cancelletto");
  delay(2000);
  lcd.clear();

  Serial.begin(9600);
}


void loop() {

  if (flag == 0) {

    lcd.setCursor(0, 0);
    lcd.print("Temp 1 = ");
    lcd.setCursor(16, 0);
    lcd.print("[");
    lcd.setCursor(17, 0);
    lcd.print((char)223);
    lcd.setCursor(18, 0);
    lcd.print("C]");

    j = 9;
    lcd.setCursor(j + i, 0);

    tastobattuto = keypad.getKey();

    if (tastobattuto != NO_KEY && tastobattuto != '*') {
      if (tastobattuto == '#') {
        i--;
        lcd.setCursor(j + i, 0);
      }
      temperatura1[i] = tastobattuto;
      lcd.write (tastobattuto);

      if (tastobattuto != '#') {
        i++;
      }
    }
    if (tastobattuto == '*') {
      lcd.clear();
      lcd.setCursor(4, 1);
      lcd.print("insrimento");
      lcd.setCursor(5, 2);
      lcd.print("riuscito");
      delay(1000);
      lcd.clear();

      lcd.setCursor(0, 0);
      lcd.print("Temp 1 = ");
      lcd.setCursor(9, 0);
      lcd.print (temperatura1);
      lcd.setCursor(16, 0);
      lcd.print("[");
      lcd.setCursor(17, 0);
      lcd.print((char)223);
      lcd.setCursor(18, 0);
      lcd.print("C]");

      flag++;
      i = 0;

      Serial.print("Temp 1 = ");
      Serial.println(temperatura1);
    }
  }

  if (flag == 1) {
    lcd.setCursor(0, 1);
    lcd.print("Temp 2 = ");
    lcd.setCursor(16, 1);
    lcd.print("[");
    lcd.setCursor(17, 1);
    lcd.print((char)223);
    lcd.setCursor(18, 1);
    lcd.print("C]");

    j = 9;
    lcd.setCursor(j + i, 1);

    tastobattuto = keypad.getKey();

    if (tastobattuto != NO_KEY && tastobattuto != '*') {
      if (tastobattuto == '#') {
        i--;
        lcd.setCursor(j + i, 1);
      }
      temperatura2[i] = tastobattuto;
      lcd.write (tastobattuto);
      if (tastobattuto != '#') {
        i++;
      }
    }
    if (tastobattuto == '*') {
      lcd.clear();
      lcd.setCursor(4, 1);
      lcd.print("insrimento");
      lcd.setCursor(5, 2);
      lcd.print("riuscito");
      delay(1000);
      lcd.clear();

      lcd.setCursor(0, 0);
      lcd.print("Temp 1 = ");
      lcd.setCursor(9, 0);
      lcd.print (temperatura1);
      lcd.setCursor(16, 0);
      lcd.print("[");
      lcd.setCursor(17, 0);
      lcd.print((char)223);
      lcd.setCursor(18, 0);
      lcd.print("C]");

      lcd.setCursor(0, 1);
      lcd.print("Temp 2 = ");
      lcd.setCursor(9, 1);
      lcd.print (temperatura2);
      lcd.setCursor(16, 1);
      lcd.print("[");
      lcd.setCursor(17, 1);
      lcd.print((char)223);
      lcd.setCursor(18, 1);
      lcd.print("C]");

      flag++;
      i = 0;
      Serial.print("Temp 2 = ");
      Serial.println(temperatura2);
    }
  }
}





void typewriting(String messaggio) {
  int lunghezza = messaggio.length();
  for (int k = 0; k < lunghezza; k++) {
    lcd.print(messaggio[k]);
    delay(150);
  }
}

Ora, utilizzando lo stesso codice solamente modificato nel contenuto delle stringhe che vengono visualizzate su schermo, ma non nella struttura, accadono alcuni problemi a mio avviso inspiegabili!

In particolare ho notato che nel momento in cui nello schermo è presente “molto testo” (=molti pixel anneriti), la velocità di scansione del tastierino cala drasticamente. In pratica, mentre nel codice riportato sopra la visualizzazione del tasto premuto è pressoché immediata, nel codice che “non funziona” il carattere viene visualizzato esclusivamente dopo ripetute e rapide pressioni, finchè una di queste non va a coincidere con l’esatto momento in cui viene eseguita la scansione della riga/colonna, che avviene circa una volta al secondo…

Non riesco a trovare una spiegazione a questo fenomeno.
Nel codice incriminato, che riporto di seguito, se si sostituisce la parte commentata alle righe precedeti, tutto funziona correttamente!

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

LiquidCrystal_I2C lcd(0x27, 20, 4);

const byte righe = 4;                   
const byte colonne = 3;                 

char chiave[righe][colonne] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte pinrighe[righe] = {2, 3, 4, 5};
byte pincolonne[colonne] = {6, 7, 8};

Keypad keypad = Keypad( makeKeymap(chiave), pinrighe, pincolonne, righe, colonne );

char tastobattuto;
int i = 0;
int j = 0;
const int lunghezza_stringhe = 5;
char num_stp[lunghezza_stringhe];
int flag = 0;


void setup() {
  lcd.init();
  lcd.backlight();

  lcd.setCursor(4, 1);
  typewriting("BIRRARDUINO");
  delay(2000);
  lcd.clear();
  delay(200);

  lcd.clear();
  lcd.setCursor(3, 1);
  lcd.print("per confermare");
  delay(1000);
  lcd.setCursor(1, 2);
  lcd.print("digitare asterisco");
  delay(2000);
  lcd.clear();
  delay(500);
  lcd.setCursor(3, 1);
  lcd.print("per cancellare");
  delay(1000);
  lcd.setCursor(0, 2);
  lcd.print("digitare cancelletto");
  delay(2000);
  lcd.clear();

  Serial.begin(9600);
}


void loop() {

  if (flag == 0) {

    lcd.setCursor(0, 0);                                      //NON FUNZIONA
    lcd.print("- INSERIMENTO DATI -");               //NON FUNZIONA
    delay(1000);                                               //NON FUNZIONA
    lcd.setCursor(0, 1);                                      //NON FUNZIONA
    lcd.print(" Specificare quanti");                     //NON FUNZIONA
    lcd.setCursor(0, 2);                                     //NON FUNZIONA
    lcd.print(" step sono previsti");                     //NON FUNZIONA
    lcd.setCursor(0, 3);                                     //NON FUNZIONA
    delay(500);                                                 //NON FUNZIONA
    lcd.print("STEP = ");                                    //NON FUNZIONA

    j = 7;
    lcd.setCursor(j + i, 3);

    //    SOSTITUENDO QUESTA PARTE INVECE FUNZIONA!
    //    lcd.setCursor(0, 0);                           
    //    lcd.print("STEP = ");
    //    j = 7;
    //    lcd.setCursor(j + i, 0);

    tastobattuto = keypad.getKey();

    if (tastobattuto != NO_KEY && tastobattuto != '*') {
      if (tastobattuto == '#') {
        i--;
        lcd.setCursor(j + i, 0);
      }
      num_stp[i] = tastobattuto;
      lcd.write (tastobattuto);

      if (tastobattuto != '#') {
        i++;
      }
    }
    if (tastobattuto == '*') {
      lcd.clear();
      lcd.setCursor(4, 1);
      lcd.print("insrimento");
      lcd.setCursor(5, 2);
      lcd.print("riuscito");
      delay(1000);
      lcd.clear();

      flag++;
      i = 0;

      Serial.print("Temp 1 = ");
      Serial.println(num_stp);
    }
  }


}





void typewriting(String messaggio) {
  int lunghezza = messaggio.length();
  for (int k = 0; k < lunghezza; k++) {
    lcd.print(messaggio[k]);
    delay(100);
  }
}

Può essere legato ad un problema di troppo assorbimento di corrente?
Ho eseguito le prove sia collegando Arduino tramite USB sia attraverso un alimentatore, ma il risultato resta invariato.

Grazie dell’aiuto.

Pensandoci, potrebbe essere anche la velocità di esecuzione dell'intero loop a rallentare enormemente, ma non ne capisco il motivo...

Approfitto inoltre per un'ulteriore domanda: le variabili inserite da tastiera sono di tipo char, mentre per poter essere utilizzate nel seguito del programma servirebbe trasformarle in int.
Non so a priori la lunghezza di di tali variabili, quindi sono costretto a dichiararle con una dimensione maggiore della massima prevista. Esiste un modo per convertire tali valori in int senza che gli "spazi vuoti" possano creare problemi?

Per essere più chiaro faccio un esempio: se definisco la variabile char numero[5]; e da tastiera inserisco 56, la variabile avrà solo i primi due spazi occupati dai caratteri 5 e 6, ed ulteriori tre spazi non occupati. Come è possibile trasformare questo nel NUMERO cinquantasei?

So che possono essere problemi banali, ma con un background meccanico sembrano insormontabili!

RISOLTO! La colpa è di qualche delay di troppo che mettono in attesa il loop!
Se servisse a qualcuno allego il codice corretto.

Resta il problema della conversione di cui sopra.

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

LiquidCrystal_I2C lcd(0x27, 20, 4);

const byte righe = 4;                   
const byte colonne = 3;              

char chiave[righe][colonne] = {
 {'1', '2', '3'},
 {'4', '5', '6'},
 {'7', '8', '9'},
 {'*', '0', '#'}
};

byte pinrighe[righe] = {2, 3, 4, 5};
byte pincolonne[colonne] = {6, 7, 8};

Keypad keypad = Keypad( makeKeymap(chiave), pinrighe, pincolonne, righe, colonne );


char tastobattuto;
int i = 0;
int j = 0;
const int lunghezza_stringhe = 5;
char num_stp[lunghezza_stringhe];
int flag = 0;
//int nstep;
//int step_attuale = 1;
//char variabile_inserita[] = {'/', '/', '/'};
//int numero = 0;
//int variabili_totali[18];
//int posizione_array = 0;

void setup() {

 lcd.init();
 lcd.backlight();


 lcd.setCursor(5, 0);
 typewriting("MODALITA'");
 lcd.setCursor(8, 1);
 typewriting("DI");
 lcd.setCursor(4, 2);
 typewriting("INSERIMENTO");
 delay(2000);
 lcd.clear();
 lcd.setCursor(3, 1);
 lcd.print("per confermare");
 delay(1000);
 lcd.setCursor(1, 2);
 lcd.print("digitare asterisco");
 delay(2000);
 lcd.clear();
 delay(500);
 lcd.setCursor(3, 1);
 lcd.print("per cancellare");
 delay(1000);
 lcd.setCursor(0, 2);
 lcd.print("digitare cancelletto");
 delay(2000);
 lcd.clear();

 Serial.begin(9600);
}


void loop() {

 if (flag == 0) {
   lcd.setCursor(0, 0);
   lcd.print("- INSERIMENTO DATI -");
   delay(1000);
   lcd.setCursor(0, 1);
   lcd.print(" Specificare quanti");
   lcd.setCursor(0, 2);
   lcd.print(" step sono previsti");
   lcd.setCursor(0, 3);
   delay(500);
   lcd.print("STEP = ");

   flag++;
 }

 if (flag == 1) {
   j = 7;
   lcd.setCursor(j + i, 3);

   tastobattuto = keypad.getKey();

   if (tastobattuto != NO_KEY && tastobattuto != '*') {
     if (tastobattuto == '#') {
       i--;
       lcd.setCursor(j + i, 3);
     }
     num_stp[i] = tastobattuto;
     lcd.write (tastobattuto);

     if (tastobattuto != '#') {
       i++;
     }
   }
   if (tastobattuto == '*') {
     lcd.clear();
     lcd.setCursor(4, 1);
     lcd.print("insrimento");
     lcd.setCursor(5, 2);
     lcd.print("riuscito");
     delay(1000);
     lcd.clear();

     flag++;
     i = 0;

     Serial.print("Temp 1 = ");
     Serial.println(num_stp);
   }
 }


}



void typewriting(String messaggio) {
 int lunghezza = messaggio.length();
 for (int k = 0; k < lunghezza; k++) {
   lcd.print(messaggio[k]);
   delay(100);
 }
}