PROBLEMI memorizzazione numero inserito con keypad

ahhh ecco perchè non mi funzionava, avevo anche io provato a mettere la A in quel punto, ora funziona grazie! in caso io volessi impostare oltre ad Hmin anche Hmax mi basta ricopiare la parte sopra e cambiare dove viene menzionato Hmin con Hmax? (ho già messo un altro int Hmax = 0).
Ultima cosa, io vorrei salvare Hmin nel float facendo "float a = Hmin" però mi dice che Hmin non va bene, come posso risolvere?

Prova a dare un'occhiata qua.

Ciao,
P.

ci sto provando in tutti i modi ma non riesco :confused:
Ho definito int salv1 = 0 (salvataggio1 per Hmin) poi dovrò fare un int salv2 = 0 (per Hmax)
poi ho scritto

{
          if(key == FINE_NUMERO){
            (salv1 = key);
            Serial.println(salv1);
            delay(3000);
          }

in modo tale da porre salv1 = al numero scritto,
ma boh non riesco a capire dove sto sbagliando...

Salve, avevo già aperto un argomento ma si stava incasinando quindi ne apro un altro simile (al momento non chiudo l'altro perchè ho delle risposte anche lì che mi servono).
Io sto lavorando ad un progetto da dover portare per forza all'esame di maturità, partendo dal fatto che io (come tutta la classe) ho 0 competenze con arduino, nonostante ciò hanno deciso ad inizio anno di farci accendere 1 led, e ora di chiederci la progettazione di un sistema idrico per la città con tanto di fungo alto 20 metri totalmente automatizzato da arduino... vabbeh.

Oltre al mio piccolo sfogo, questo è quello che (con l'aiuto di altri utenti) sono riuscito a fare, ma sono bloccato;


#include <LiquidCrystal.h>
#include <Keypad.h>



#define VIRGOLA 'A' 
#define FINE_NUMERO 'B'
#define CANCELLA 'C'


LiquidCrystal lcd(5, 4, 3, 2, A4, A5);


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] = {A0, A1, A2, 10}; 
byte colPins[COLS] = {9, 8, 7, 6}; 

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

int LCDRow = 0;
int livello = 0;
int i = 0;




void setup() {
  
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);

  
}

void loop()
{
  lcd.begin(16, 2);
  delay(2000);
  {
    lcd.print("Avvio...");
    delay(5000);
    lcd.clear();
    {
      delay(3000);
      lcd.print("Inserire altezza");
    }
    {
      lcd.setCursor(0, 1);
      lcd.print("Hmin:");
      delay(1000);
    }
    {
      lcd.setCursor(5, 1);
      int hMin = 0;
      char key;
      while (true) {
        key = keypad.waitForKey();
        if (key == VIRGOLA) {
          Serial.println(',');
          lcd.print(',');          
          continue;
        }
        if (key == CANCELLA) {
          Serial.println("Cancellato");
          lcd.setCursor(5, 1);      //POSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
          lcd.print("           "); //SCRIVI UN NUMERO DI SPAZI PER CANCELLARE
          lcd.setCursor(5, 1);      //RIPOSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
          continue;
        }
        if (key == FINE_NUMERO) {
          break;
        }
        if (key-48 >= 0 && key-48 <=9) {   
          Serial.println(key);
          lcd.print(key);                    
          hMin = hMin * 10 + (key-48);
        }
      }
    }
  }
}

devo fare in modo da scrivere con keypad un numero da dover leggere sull'lcd,(questo sono riuscito a farlo), ma questo che sto per dirvi no:

il numero va salvato come Hmin (altezza minima)
poi bisogna scrivere sempre con keypad un numero da dover salvare questa volta come Hmax (altezza massima)

questi valori dovranno poi essere confrontati con un valore dato da un sensore (dato che uso tinkercad sto usando un potenziometro per simularlo)
ma a quest'ultima cosa ci sto lavorando io dato che credo di essere in grado.

Potreste aiutarmi con questa cosa? ho praticamente 2 settimane per completarlo e studiare tutte le altre cose che ci hanno dato, stiamo praticamente impazzendo, il vostro aiuto sarebbe il TOP, Grazie in anticipo!

Ecco, questa cosa si chiama "crossposting" ed è proibita da regolamento. Se tratti un argomento continui a trattarlo nel thread dove ne stai già parlando e NON apri nuovi thread. Grazie. :slight_smile:

Guglielmo

P.S.: ho riunito io i due thread.

Quel potenziometro ti da un valore 0-1023 letto su un pin analogico, quali sono i valori che ti da il 'sensore' di cui parli? Sono altezze in metri e decimi di metro (che si chiamano decimetri)? Sono valori analogici di una tensione cha va da Vmin a Vmax? Qualcos'altro?

Ciao,
P.

Ciao, come detto nel post da pgiagno devi capire che tipo di dato restituisce il sensore;

Fatto ciò secondo me puoi fare cosi:

#include <LiquidCrystal.h>
#include <Keypad.h>



#define VIRGOLA 'A'
#define FINE_NUMERO 'B'
#define CANCELLA 'C'


LiquidCrystal lcd(5, 4, 3, 2, A4, A5);


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] = {A0, A1, A2, 10};
byte colPins[COLS] = {9, 8, 7, 6};

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

int LCDRow = 0;
int livello = 0;
int i = 0;




void setup() {

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.print("file: ");
  Serial.print(__FILE__);
  Serial.print(" Date: ");
  Serial.print(__DATE__);
  Serial.print(" ");
  Serial.print(__TIME__);
  Serial.println("\n Starting...");
}

void loop() {
  lcd.begin(16, 2);
  delay(2000);

  lcd.print("Avvio...");
  delay(5000);

  //hMin
  lcd.clear();
  delay(3000);
  lcd.print("Inserire altezza");

  lcd.setCursor(0, 1);
  lcd.print("Hmin:");
  delay(1000);
  lcd.setCursor(5, 1);

  float hMin = getNumberInput();

  //hMax
  lcd.clear();
  delay(3000);
  lcd.print("Inserire altezza");

  lcd.setCursor(0, 1);
  lcd.print("Hmax:");
  delay(1000);
  lcd.setCursor(5, 1);
  float hMax = getNumberInput();

  //Qui metti il confronto con dati del sensore

  // sens < min         --> sotto la soglia
  // min <= sens < max  --> tra min e max
  // max <= sens        --> sopra al max

  if (valSens < hMin) {
    //SOTTO AL MIN
  } else if (hMin <= valSens && valSens < hMax) {
    //TRA LE DUE SOGLIE
  } else if (hMax <= valSens) {
    //SOPRA AL MAX
  }


}

float getNumberInput() {
  String input = "";
  while (true) {
    key = keypad.waitForKey();
    if (key == VIRGOLA) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(',');
        lcd.print(',');
        input += '.';
      } else {
        return input.toFloat();
      }
      continue;
    }
    if (key == CANCELLA) {
      Serial.println("Cancellato");
      lcd.setCursor(5, 1);      //POSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      lcd.print("           "); //SCRIVI UN NUMERO DI SPAZI PER CANCELLARE
      lcd.setCursor(5, 1);      //RIPOSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      input = "";
      continue;
    }
    if (key == FINE_NUMERO) {
      if (input.length() < 16) { //altrimenti non sta nel display
        return input.toFloat();
      }
    }
    if (key - 48 >= 0 && key - 48 <= 9) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(key);
        couter++;
        lcd.print(key);
        input += String(key);
      } else {
        return input.toFloat();
      }
    }
  }
}

Non ho potuto provarlo perché non ho il Keypad, ma potrebbe essere una prova da fare.

Diciamo anche che ho utilizzato una String che credo si possa cambiare con una SafeString se ne hai la competenza.

Facci sapere de funziona

PS.
ho aggiunto anche una cosa nel setup per avere info su che programma hai caricato nella scheda cosi da aiutarti a gestire le versioni del software.

Alan

Scusate se non ho più risposto, ma ho avuto problemi di connessione, comunque sono andato avanti e sono riuscito a passare quel problema quindi per ora va tutto ok ^-^

Ora sono davanti a questo problema: devo far ripetere all'infinito il void controllo(), ma se premo # deve uscire e andare su void impostazioni().
il punto è che il void controllo() viene chiamato o all'inizio del programma, oppure subito dopo la fine del programma di controllo(), quindi in entrambi i casi me lo legge una sola volta, ho provato a mettere un "while(a < 100) e alla fine a++, ma giustamente se premo # non me lo fa funzionare anche se metto "if (key = NO){ impostazioni(); ecco il programma.

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Keypad.h>

#define VIRGOLA 'A' 
#define FINE_NUMERO 'B'
#define CANCELLA 'C'
#define IMPOSTAZIONI 'D'
#define SI '*'
#define NO '#'


LiquidCrystal lcd(5, 4, 3, 2, A4, A5);


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] = {A0, A1, A2, 10}; 
byte colPins[COLS] = {9, 8, 7, 6}; 

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

int LCDRow = 0;
int i = 0;
int a = 0;
int valore;
int valore2;
int analogPin = A3;
int livello = 0;

char key; 

// SETUP______________________________________________

void setup(){   
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}
  
  
//START_______________________________________________

void loop() {
  delay(2000);
  lcd.begin(16, 2);
  lcd.print("Avvio...");
  delay(3000);
  lcd.clear();
  delay(1000);
  lcd.print("Scegliere programma");
  lcd.setCursor(0, 1);
  lcd.print("Work=*Impost.=#");
  while (true){
    key = keypad.waitForKey();
    if (key == SI){
      controllo();
    }    
    if (key == NO){
      impostazioni();
    }
  }
}


//CONTROLLO SENSORE___________________________________
    
void controllo(){
  lcd.clear();
  livello = analogRead(3);
  lcd.setCursor(12, 1);
  lcd.print(livello);
}

    

//IMPOSTAZIONI________________________________________

void impostazioni(){
  lcd.clear();
  delay(1000);
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);  
  lcd.print("Hmin:");
  delay(1000);
  lcd.setCursor(5, 1);
  int hMin = 0;
  while (true) {
    key = keypad.waitForKey();
    if (key == VIRGOLA){
      Serial.println(',');
      lcd.print(',');          
      continue;
    }
    if (key == CANCELLA) {
      Serial.println("Cancellato");
      lcd.setCursor(5, 1);      
      lcd.print("           "); 
      lcd.setCursor(5, 1);
      continue;
    }
    if (key == FINE_NUMERO){  
      break;
    }
    if (key-48 >= 0 && key-48 <=9){   
      Serial.println(key);
      lcd.print(key);                    
      hMin = hMin * 10 + (key-48);
    }
  }
  {
    if (key-48 >= 0 && key-48 <=9){   
      Serial.println(key);
      lcd.print(key);                    
      hMin = hMin + (key-48);
      EEPROM.write(0, hMin);   //SCRIVO EEPROM HMIN==============================================   
    }
  }
  {
    lcd.clear();
    delay(1000);
    lcd.print("Inserire altezza");
    lcd.setCursor(0, 1);  
    lcd.print("Hmax:");
    delay(1000);
    lcd.setCursor(5, 1);
    int hMax = 0;
    while (true) {
      key = keypad.waitForKey();
      if (key == VIRGOLA){
        Serial.println(',');
        lcd.print(',');          
        continue;
      }
      if (key == CANCELLA) {
        Serial.println("Cancellato");
        lcd.setCursor(5, 1);      
        lcd.print("           "); 
        lcd.setCursor(5, 1);
        EEPROM.write(1, 0);
        continue;
      }
      if (key == FINE_NUMERO) {
        break;
      }
      if (key-48 >= 0 && key-48 <=9){   
        Serial.println(key);
        lcd.print(key);                    
        hMax = hMax * 10 + (key-48);
      }
    }
    {
      if (key-48 >= 0 && key-48 <=9){   
        Serial.println(key);
        lcd.print(key);                    
        hMax = hMax + (key-48);
        EEPROM.write(1, hMin); //SCRIVO EEPROM HMAX ********************************************
      }
      {
        lcd.clear();
        delay(1000);
        lcd.print("Fine Impost.");
        delay(2000);
        lcd.clear();
        lcd.print("Avvio?");
        lcd.setCursor(0, 1);
        lcd.print("SI = *   NO = #");
        while (true){
          key = keypad.waitForKey();
          if (key == SI){
            controllo();
          }    
          if (key == NO){
            impostazioni();
          }
        }
      }
    }
  }
}
        
              
      
      /*
      {
        lcd.clear();
        delay(2000);
        valore = EEPROM.read(hMin);
        lcd.setCursor(0, 0);
        lcd.print(hMin);
      }
      {
        valore2 = EEPROM.read(hMax);
        lcd.setCursor(0, 1);
        lcd.print(hMax);
        delay(8000);
      }
    }
  }
}
        */

Ciao @chiriacoclaudio,
allora, quello che hai fatto non è proprio il massimo, nel senso che mettere un while(true) in entrambe le routine è pericoloso e non ne esci più! (Deathloop)

Detto ciò, ho corretto quello che a mio avviso non andava bene e, secondo me, l'ultimo ciclo che avevi messo era completamente inutile!

Poi, noto altre incongruenze:

  1. nei post precedenti chiedi di memorizzare dei dati hHmin e hHmax per confrontarli poi con la lettura del sensore, dove lo fai?
  2. Perché salvi dei dati in EEPROM se poi non li leggi mai?

Comunque tralasciando gli interrogativi di cui sopra, il tuo algoritmo dovrebbe essere cosi

Il nuovo codice quindi diventa questo di seguito:

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Keypad.h>

#define VIRGOLA 'A'
#define FINE_NUMERO 'B'
#define CANCELLA 'C'
#define IMPOSTAZIONI 'D'  
#define SI '*'
#define NO '#'


LiquidCrystal lcd(5, 4, 3, 2, A4, A5);


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] = {A0, A1, A2, 10};
byte colPins[COLS] = {9, 8, 7, 6};

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

int LCDRow = 0;
int i = 0;
int a = 0;
int valore;
int valore2;
int analogPin = A3;
int livello = 0;
const int interval = 500;
char key;

// SETUP______________________________________________

void setup() {
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}


//START_______________________________________________

void loop() {
  unsigned long lastControllo = 0;
  delay(2000);
  lcd.begin(16, 2);
  lcd.print("Avvio...");
  delay(3000);
  lcd.clear();
  delay(1000);
  lcd.print("Scegliere prog.");
  lcd.setCursor(0, 1);
  lcd.print("Work=*Impost.=#");
  while (true) {
    char keyPress = keypad.getKey();
    if(keyPress != NO_KEY){
      key = keyPress;
      Serial.println(String(key));
    }
    if (key == SI) {
      if(millis() - lastControllo > interval){ //Delay non bloccante
        lastControllo = millis();
      	controllo();
      }
    }
    if (key == NO) {
      impostazioni();
      delay(2000);
      lcd.clear();
      lcd.print("Avvio?");
      lcd.setCursor(0, 1);
      lcd.print("SI = *   NO = #");
      key = NO_KEY;
    }
  }
  /*key = keypad.waitForKey();
  Serial.println(String(key));*/
}


//CONTROLLO SENSORE___________________________________

void controllo() {
  lcd.clear();
  livello = analogRead(3);
  lcd.setCursor(12, 1);
  lcd.print(livello);
}



//IMPOSTAZIONI________________________________________
void impostazioni() {
  byte eeIndex = 0;
  float eeRead;
  lcd.clear();
  delay(1000);

  //INSERIMENTO DATO hHmin ********************************************************
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);
  lcd.print("Hmin:");
  delay(1000);
  lcd.setCursor(5, 1);
  float hMin = getNumberInput(); //COME AVEVO GIA' SUGGERITO CREATI LA FUNZIONE CHE DAL KEYPAD TI DA GIA' IL NUMERO; PER IL TIPO DI DATO VEDI I COMMENTI NELLA FUNZIONE
  if(hMin != 0){
    Serial.print("hMin: ");
    Serial.println(hMin);
  }
  EEPROM.get(eeIndex, eeRead);
  // SICCOME LA EEPROM HA 10000 CICLI DI SCRITTURA CONTROLLO CHE QUELLO CHE VOLGIAMO 
  // METTERCI DENTRO SIA DIVERSO DA QUELLO GIA' PRESENTE NELLA CELLA
  if ( eeRead != hMin) {   
    EEPROM.put(eeIndex, hMin);
    eeIndex += sizeof(float);
  } else {
    Serial.println("hHmin: Dato non modificicato");
  }

  //INSERIMENTO DATO hHmax *********************************************
  lcd.clear();
  delay(1000);
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);
  lcd.print("Hmax:");
  delay(1000);
  lcd.setCursor(5, 1);
  float hMax = getNumberInput();
  if(hMax != 0){
    Serial.print("hMax: ");
    Serial.println(hMax);
  }
  EEPROM.get(eeIndex, eeRead);
  if ( eeRead != hMax) {
    EEPROM.put(eeIndex, hMax);
    eeIndex += sizeof(float);
  } else {
    Serial.println("hHmax: Dato non modificicato");
  }
  lcd.clear();
  delay(1000);
  lcd.print("Fine Impost.");
  delay(2000);
}

//CALCOLO IL NUMERO INSERITO DAL KEYPAD ********************************************
float getNumberInput() {
  String input = "";
  char keyTemp;
  
  while (true) {
    keyTemp = keypad.waitForKey();
    if (keyTemp == VIRGOLA) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(',');
        lcd.print(',');
        input += '.';
      } else {
        return input.toFloat();
      }
      continue;
    }
    if (keyTemp == CANCELLA) {
      Serial.println("Cancellato");
      lcd.setCursor(5, 1);      //POSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      lcd.print("           "); //SCRIVI UN NUMERO DI SPAZI PER CANCELLARE
      lcd.setCursor(5, 1);      //RIPOSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      input = "";
      continue;
    }
    if (keyTemp == FINE_NUMERO) {
      if (input.length() < 16) { //altrimenti non sta nel display
        return input.toFloat();
      }
    }
    if (keyTemp - 48 >= 0 && keyTemp - 48 <= 9) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(keyTemp);
        lcd.print(keyTemp);
        input += String(keyTemp);
      } else {
        //SE QUI METTI return input.toInt() restituirà un numero intero; 
        //ricorda di cambiare anche il tipo di funzione sopra che diventerà: int getNumberInput()
        return input.toFloat(); 
      }
    }
  }
}

Per altre informazioni siamo qua!!

Alan Masutti

perfetto, effettivamente funziona meglio questo tuo, comunque per le varie domande che mi hai fatto... io sto impicciatissimo con le idee, manca pochissimo alla consegna del prog. e sto impazzendo ahaha, se manca qualcosa in particolare non fa nulla, la cosa importante è che funziona tutto, cosa in più o cosa in meno

Ciao @chiriacoclaudio,
Per il discorso di recuperare i dati dalla EEPROM basta una funzione nel Setup!

Poi, adesso che penso le variabili hMin e hMax dovrebbero essere dichiarate pubbliche e non private alla funzione Impostazioni, visto che ci sei inizializzale a -1 così controlli che il backup sia stato ripristinato! Fatto ciò per la EEPROM chiama la funzione seguente:

void loadBackup() {
  byte eeIndex = 0;
  EEPROM.get(eeIndex, hMin);
  eeIndex += sizeof(float);
  EEPROM.get(eeIndex, hMax);
}

Alan

ieri ne ho parlato con il prof, mi ha consigliato di fare la stessa cosa che mi stai dicendo tu, quindi provvederò ad implementarla al codice, anche perchè mi rimane una sola cosa da sistemare e potrò dire di aver completato il prog.

Devo far in modo che il pulsante D della tastiera mi tenga aperto la valvola EV2 ma chiudendo allo stesso momento EV1/EV3.
Ho già definito D come SCARICO d all'inizio deve essere d = 0 se durante il loop io premo quel pulsante deve diventare d = 1 e quindi aprire quelle valvole, e SOLO se ripremo D deve tornare a 0, però sono riuscito a fare solo quello che vedi, il problema è che ad ogni inizio loop si resetta e quindi non apre nulla, rimane bloccato [ tutto questo è nella void controllo().

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Keypad.h>

#define VIRGOLA 'A'
#define FINE_NUMERO 'B'
#define CANCELLA 'C'
#define SCARICO 'D'  
#define SI '*'
#define NO '#'


LiquidCrystal lcd(5, 4, 3, 2, A4, A5);


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] = {A0, A1, A2, 10};
byte colPins[COLS] = {9, 8, 7, 6};

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

int LCDRow = 0;
int i = 0;
int a = 0;
int valore;
int valore2;


int livello = 0;

const int interval = 500;
char key;

float hMin;
float hMax;


// SETUP______________________________________________

void setup() {
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  
  Serial.begin(9600);
}


//START_______________________________________________
void loop() {
  unsigned long lastControllo = 0;
  delay(2000);
  lcd.begin(16, 2);
  lcd.print("Avvio...");
  delay(3000);
  lcd.clear();
  delay(1000);
  lcd.print("Scegliere prog.");
  lcd.setCursor(0, 1);
  lcd.print("Work=*Impost.=#");
  while (true) {
    char keyPress = keypad.getKey();
    if(keyPress != NO_KEY){
      key = keyPress;
      Serial.println(String(key));
    }
    if (key == SI) {
      if(millis() - lastControllo > interval){ //Delay non bloccante
        lastControllo = millis();
      	controllo();
      }
    }
    if (key == NO) {
      impostazioni();
      delay(2000);
      lcd.clear();
      lcd.print("Avvio?");
      lcd.setCursor(0, 1);
      lcd.print("SI = *   NO = #");
      key = NO_KEY;
    }
  }
}


//CONTROLLO SENSORE___________________________________

void controllo(){
  char keyTemp;
  lcd.clear();
  livello = analogRead(3)/51.15; //se divido il valore massimo del potenziometro 1023 per 51.15 ottengo 20
  lcd.setCursor(12, 1);
  lcd.print(livello);
  Serial.println(livello);
  Serial.println(hMin);
  Serial.println(hMax);
  
  //EV1 CARICO
  if (livello < hMin){
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(13, HIGH);
    Serial.println("livello basso");
  }
  //EV2 SCARICO
  if (livello > hMax){
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    Serial.println("livello alto");
  }
  if (keyTemp == SCARICO){
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
    digitalWrite(11, LOW);
    Serial.println("SCARICO...");
      
  }
}
 

    




//IMPOSTAZIONI________________________________________
void impostazioni(){
  byte eeIndex = 0;
  float eeRead;
  lcd.clear();
  delay(1000);
  
  //INSERIMENTO DATO hHmin ********************************************************
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);
  lcd.print("Hmin:");
  delay(1000);
  lcd.setCursor(5, 1);
  hMin = getNumberInput(); //COME AVEVO GIA' SUGGERITO CREATI LA FUNZIONE CHE DAL KEYPAD TI DA GIA' IL NUMERO; PER IL TIPO DI DATO VEDI I COMMENTI NELLA FUNZIONE
  if(hMin != 0){
    Serial.print("hMin: ");
    Serial.println(hMin);
  }
  EEPROM.get(eeIndex, eeRead);
  // SICCOME LA EEPROM HA 10000 CICLI DI SCRITTURA CONTROLLO CHE QUELLO CHE VOGLIAMO 
  // METTERCI DENTRO SIA DIVERSO DA QUELLO GIA' PRESENTE NELLA CELLA
  if ( eeRead != hMin) {   
    EEPROM.put(eeIndex, hMin);
    eeIndex += sizeof(float);
  } else {
    Serial.println("hHmin: Dato non modificicato");
  }
  lcd.clear();
  delay(1000);
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);
  lcd.print("Hmax:");
  delay(1000);
  lcd.setCursor(5, 1);
  float hMax = getNumberInput();
  if(hMax != 0){
    Serial.print("hMax: ");
    Serial.println(hMax);
  }
  EEPROM.get(eeIndex, eeRead);
  if (eeRead != hMax) {
    EEPROM.put(eeIndex, hMax);
    eeIndex += sizeof(float);
  } else {
    Serial.println("hHmax: Dato non modificicato");
  }
  lcd.clear();
  delay(1000);
  lcd.print("Fine Impost.");
  delay(2000);
}

//CALCOLO IL NUMERO INSERITO DAL KEYPAD ********************************************
float getNumberInput() {
  String input = "";
  char keyTemp;
  while (true) {
    keyTemp = keypad.waitForKey();
    if (keyTemp == VIRGOLA) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(',');
        lcd.print(',');
        input += '.';
      } else {
        return input.toFloat();
      }
      continue;
    }
    if (keyTemp == CANCELLA) {
      Serial.println("Cancellato");
      lcd.setCursor(5, 1);      //POSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      lcd.print("           "); //SCRIVI UN NUMERO DI SPAZI PER CANCELLARE
      lcd.setCursor(5, 1);      //RIPOSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      input = "";
      continue;
    }
    if (keyTemp == FINE_NUMERO) {
      if (input.length() < 16) { //altrimenti non sta nel display
        return input.toFloat();
      }
    }
    if (keyTemp - 48 >= 0 && keyTemp - 48 <= 9) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(keyTemp);
        lcd.print(keyTemp);
        input += String(keyTemp);
      } else {
        //SE QUI METTO return input.toInt() restituirà un numero intero; 
        //(cambiare anche il tipo di funzione sopra che diventerà: int getNumberInput())
        return input.toFloat(); 
      }
    }
  }
}

Ciao @chiriacoclaudio,
mi scuso pe non averti più risposto, ma sono stato via tutto il fine settimana;

Ho corretto quel problema dello scarico, in più mi sono permesso di inserire il ripristino dei dati dalla EEPROM!

Ovviamente non ha nemmeno senso dare la possibilità di iniziare il ciclo di controllo se i dati non sono impostati!!

Ecco il codice:

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Keypad.h>

#define VIRGOLA 'A'
#define FINE_NUMERO 'B'
#define CANCELLA 'C'
#define SCARICO 'D'
#define SI '*'
#define NO '#'


LiquidCrystal lcd(5, 4, 3, 2, A4, A5);


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] = {A0, A1, A2, 10};
byte colPins[COLS] = {9, 8, 7, 6};

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

int LCDRow = 0;
int i = 0;
int a = 0;
int valore;
int valore2;

bool backup = false;
bool scarico = 0;
int livello = 0;

const int interval = 500;
char key;

float hMin = -1;
float hMax = -1;


// SETUP______________________________________________

void setup() {
  //inizializzo la seriale
  Serial.begin(9600);
  
  //inizializzo i pin
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  
  //inizializzo il display QUI
  lcd.begin(16, 2);
  lcd.print("Avvio...");
  delay(3000);
  lcd.clear();
  delay(1000);
  
  //Carico i dati dalla EEPROM
  loadBackup();
  if( hMin <= 0 || hMax <= 0){
    backup = false;
    Serial.println("Dati non ripristinati!");
    lcd.print("Dati non");
    lcd.setCursor(0, 1);
    lcd.print("ripristinati");
  }else{
    backup = true;
    Serial.println("Dati ripristinati!");
    lcd.print("Dati ripristinati");
    delay(3000);
  	lcd.clear();
    
    lcd.setCursor(0, 0);  //lcd.home();
    lcd.print("Hmin:");
    lcd.setCursor(5, 0);
    lcd.print(hMin);
    
    lcd.setCursor(0, 1);  //lcd.home();
    lcd.print("Hmax:");
    lcd.setCursor(5, 1);
    lcd.print(hMax);
    delay(2500);
  }
  
}

void loadBackup() {
  byte eeIndex = 0;
  EEPROM.get(eeIndex, hMin);
  eeIndex += sizeof(float);
  EEPROM.get(eeIndex, hMax);
}

//START_______________________________________________
void loop() {
  unsigned long lastControllo = 0;
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Scegliere prog.");
  lcd.setCursor(0, 1);
  lcd.print("Work=*Impost.=#");
  while (true) {
    char keyPress = keypad.getKey();
    if (keyPress != NO_KEY) {
      if(keyPress == SCARICO){
        scarico = !scarico;
        Serial.print("Scarico: ");
        Serial.println(scarico);
      }else{
        key = keyPress;
        Serial.println(String(key));
      }
      
    }
    if (key == SI) {
      if(backup){
        if (millis() - lastControllo > interval) { //Delay non bloccante
          lastControllo = millis();
          controllo();
        }
      }else{
        key = NO_KEY;
      	lcd.clear();
        lcd.print("Dati non");
        lcd.setCursor(0, 1);
        lcd.print("ripristinati");
    	delay(2000);
        break;
      }
    }
    if (key == NO) {
      impostazioni();
      backup = true;
      delay(2000);
      lcd.clear();
      lcd.print("Avvio?");
      lcd.setCursor(0, 1);
      lcd.print("SI = *   NO = #");
      key = NO_KEY;
    }
  }
}


//CONTROLLO SENSORE___________________________________

void controllo() {
  char keyTemp;
  lcd.clear();
  livello = analogRead(3) / 51.15; //se divido il valore massimo del potenziometro 1023 per 51.15 ottengo 20
  lcd.setCursor(12, 1);
  lcd.print(livello);
  Serial.println(livello);
  Serial.println(hMin);
  Serial.println(hMax);

  //EV1 CARICO
  if (livello < hMin && !scarico) {
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(13, HIGH);
    Serial.println("livello basso");
  }
  //EV2 SCARICO
  if (livello > hMax && !scarico) {
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    Serial.println("livello alto");
  }
  if(scarico){
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
    digitalWrite(11, LOW);
    Serial.println("SCARICO...");
  }
}



//IMPOSTAZIONI________________________________________
void impostazioni() {
  byte eeIndex = 0;
  float eeRead;
  lcd.clear();
  delay(1000);

  //INSERIMENTO DATO hHmin ********************************************************
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);
  lcd.print("Hmin:");
  lcd.setCursor(5, 1);
  hMin = getNumberInput();
  EEPROM.get(eeIndex, eeRead);
  // SICCOME LA EEPROM HA 10000 CICLI DI SCRITTURA CONTROLLO CHE QUELLO CHE VOLGIAMO 
  // METTERCI DENTRO SIA DIVERSO DA QUELLO GIA' PRESENTE NELLA CELLA
  if ( eeRead != hMin) {   
    EEPROM.put(eeIndex, hMin);
    eeIndex += sizeof(float);
  } else {
    Serial.println("hHmin: Dato non modificicato");
  }

  //INSERIMENTO DATO hHmax *********************************************
  lcd.clear();
  delay(1000);
  lcd.print("Inserire altezza");
  lcd.setCursor(0, 1);
  lcd.print("Hmax:");
  lcd.setCursor(5, 1);
  hMax = getNumberInput();
  EEPROM.get(eeIndex, eeRead);
  if ( eeRead != hMax) {
    EEPROM.put(eeIndex, hMax);
    eeIndex += sizeof(float);
  } else {
    Serial.println("hHmax: Dato non modificicato");
  }
  lcd.clear();
  delay(1000);
  lcd.print("Fine Impost.");
  delay(2000);
}

//CALCOLO IL NUMERO INSERITO DAL KEYPAD ********************************************
float getNumberInput() {
  String input = "";
  char keyTemp;
  while (true) {
    keyTemp = keypad.waitForKey();
    if (keyTemp == VIRGOLA) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(',');
        lcd.print(',');
        input += '.';
      } else {
        return input.toFloat();
      }
      continue;
    }
    if (keyTemp == CANCELLA) {
      Serial.println("Cancellato");
      lcd.setCursor(5, 1);      //POSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      lcd.print("           "); //SCRIVI UN NUMERO DI SPAZI PER CANCELLARE
      lcd.setCursor(5, 1);      //RIPOSIZIONA IL CURSORE ALL'INIZIO DEL NUMERO
      input = "";
      continue;
    }
    if (keyTemp == FINE_NUMERO) {
      if (input.length() < 16) { //altrimenti non sta nel display
        return input.toFloat();
      }
    }
    if (keyTemp - 48 >= 0 && keyTemp - 48 <= 9) {
      if (input.length() < 16) { //altrimenti non sta nel display
        Serial.println(keyTemp);
        lcd.print(keyTemp);
        input += String(keyTemp);
      } else {
        //SE QUI METTO return input.toInt() restituirà un numero intero;
        //(cambiare anche il tipo di funzione sopra che diventerà: int getNumberInput())
        return input.toFloat();
      }
    }
  }
}

Altri consigli per implementazioni:

  • attenzione che secondo me sui controlli del livello ci sono delle imprecisioni... Ora
    se scrivi qualche riga su cosa deve fare sistemiamo anche i livelli intermedi.
  • Potrebbe migliorare notevolmente il codice fare dei controlli sulla validità del numero immesso: non può essere ne uguale a 0 ne maggiore di 20, e hMax deve essere maggiore di hMin!!

Resto a disposizione

Alan Masutti

Alan tranquillo, il weekend serve per staccare da tutto!
Comunque, al momento io vorrei lasciarlo così il programma, giusto perchè devo mostrarlo all'esame e quindi non devo costruire un modello reale funzionante (tanto lo hanno detto anche i prof che non si mettono a guardare proprio tutti i dettagli), preferirei finirlo e basta, poi magari dopo l'esame sarebbe carino perfezionarlo.
L'unica cosa che mi resta è implementare quel pulsante D come avevo detto il problema è che il pulsante D deve essere all'inizio = 0 e poi se viene premuto deve diventare = 1, però deve mantenere questa posizione fino a quando non lo ripremo, nel mentre il programma deve continuare a "girare" per fare gli altri controlli.

Comunque oggi rivedo il prof che ci fa questa materia, vedo se riesco a risolvere anche con lui

@chiriacoclaudio

il codice che ti ho mandato ha già quella funzione!!

Alan

AHHHH non avevo visto la parte con l' if scusami!!

perfetto, ho consegnato l'elaborato ,speriamo bene! Grazie a tutti dell'aiuto!!