Millis va più lento del dovuto....codice da ottimizzare?

Ciao ragazzi,
il codice funziona e ci sono svariate cose da ottimizzare, ma non ho proprio idea su cosa devo fare per il problema che ho riportato nel titolo.... non lho cronometrato, ma se devo attendere 5 secondi ad esempio ne passeranno almeno il doppio....

qualche aiuto su dove concentrarmi? non ne vengo a capo....

nello specifico nel case:32 dove setto 5 secondi di attesa tra un salvataggio e l'lltro...

grazie

//V.1.08
// aumentati a 15 raccolta dati e integrato la gestione del display con il campionamento
// inserito timer che mostra il tempo che manca prima del campionamento
// aggiunto aggiornamento  Timeout_Campionamento_MP in funzione di incremento_tempo_campionamento



#include <Wire.h>
#include <OLED_I2C.h>
#include <SPI.h>
#include <EEPROM.h>
#define pulsante 9
int stato_pulsante = 0;
byte variabile_pulsante = 0;
byte variabile_pulsante_calibrazione = 0;
int Valore_umidita = 0;
int umiditaPianta = 0;
unsigned long pressione_pulsante = 0;
unsigned long TIMEOUT_pressione_pulsante = 500;
unsigned long durata_pressione_pulsante = 0;
bool cambio_stato_pulsante_calibrazione = false;
OLED  myOLED(SDA, SCL);

// font utilizzati
unsigned long t1 = 0;   // aggiorna display
unsigned long t2 = 0;   // aggiorna batteria
extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
char misurazione[3];
int val_bagnato = 0;
int val_asciutto = 0;
char stringa_val_bagnato[4];
char stringa_val_asciutto[4];
char stringa_OLD_bagnato[4];
char stringa_OLD_asciutto[4];
char stringa_misurazione[4];
char stringa_batteria[4];
int batteria = 0;
long result = 0;
char stringa_result[5];
long Valore_Carico = 5200;
long Valore_Scarico = 3500;
char stringa_Valore_Scarico[4];
char stringa_Valore_Carico[4];
int somma_batteria = 0;
byte nr = 0;
int media_batteria = 0;
long somma_result = 0;
long media_result = 0;
byte cella_eeprom_asciutto = 0;
byte cella_eeprom_bagnato = 0;
byte pianta_selezionata = 0;
char stringa_pianta_selezionata[2];
unsigned long tempo_campionamento = 0;
unsigned long incremento_tempo_campionamento = 1;
char stringa_tempo_campionamento[10];
const char* cursore[] = {"<"};
const char* Menu[] = {"Menu", "Cal.Sensore", "Cal.Batteria", "Monit.Pianta", "Seleziona Pianta", "Esci"};
const char* cal[] = {"Menu' calibrazione", "OLD_bagnato:", "OLD_asciutto:", "Misurazione:", "%:", "Annulla"};
const char* mis_umidita[] = {"Umidita' %:", "Pianta", "selezionata"};
const char* Bat[] = {"BAT%:"};
const char* cal_bat[] = {"menu' batteria", "batt %:", "Valore VCC:", "Valore Scarico:", "Valore Carico:", "Annulla"};
const char* sel_pianta[] = {"menu' sel.pianta", "!Pianta1", "Pianta 1", "!Pianta2", "Pianta 2", "!Pianta3", "Pianta 3", "!Pianta4", "Pianta 4", "!Pianta5", "Pianta 5", "!Pianta6", "Pianta 6", "!Pianta7", "Pianta 7", "!Pianta8", "Pianta 8", "Resetta", "Esci"};
const char* mon_pianta[] = {"Menu'monit.Pianta", "Minuti:", "Conferma", "Annulla", "Esci"};
bool cancella_display = false;
unsigned long START_Campionamento_MP = 0;
unsigned long Timeout_Campionamento_MP = 0;
int raccolta_dati[15];
byte punto_raccolta_dati = 1;
char misurazione_RD[10];
char stringa_timer_restante_campionamento[5];
const char* Timer[] = {"T:"};
const char* Lista_camp[] = {"1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "10:", "11:", "12:", "13:", "14:", "15:"};
const char* Stato_camp[] = {"Campionamento...", "Completato!!!!!",};
const char* firmware[] = {"V1.08"};
byte posizione_cursore_altezza = 0;
byte posizione_cursore_larghezza = 0;

void cancella_schermo() {
  myOLED.clrScr();
}

void cursore_furbo() {
  myOLED.print(cursore[0], posizione_cursore_larghezza, posizione_cursore_altezza);
}

void menu() {
  if ((stato_pulsante == LOW) && ((millis() - pressione_pulsante) > TIMEOUT_pressione_pulsante)) {
    variabile_pulsante++;
    pressione_pulsante = millis();
  }
  cancella_schermo();
  myOLED.print(Menu[0], CENTER, 1);
  myOLED.print(Menu[1], 0, 10);
  myOLED.print(Menu[2], 0, 20);
  myOLED.print(Menu[3], 0, 30);
  myOLED.print(Menu[4], 0, 40);
  myOLED.print(Menu[5], 0, 50);

  switch (variabile_pulsante) {
    case 2: //selezione calibrazione
      posizione_cursore_altezza = 10;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 2) && ((millis() - pressione_pulsante) > 2000)) {
        calibrazione();
        variabile_pulsante = 8;
      }
      break;
    case 3: //selezione batteria
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 3) && ((millis() - pressione_pulsante) > 2000)) {
        cal_batteria();
        variabile_pulsante = 13;
      }
      break;
    case 4: //selezione monitoraggio
      posizione_cursore_altezza = 30;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 4) && ((millis() - pressione_pulsante) > 2000)) {
        monitoraggio_pianta();
        variabile_pulsante = 30;
      }
      break;
    case 5: //seleziona pianta
      posizione_cursore_altezza = 40;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 5) && ((millis() - pressione_pulsante) > 2000)) {
        seleziona_pianta();
        variabile_pulsante = 18;
      }
      break;
    case 6: //esci
      posizione_cursore_altezza = 50;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 6) && ((millis() - pressione_pulsante) > 2000)) {
        variabile_pulsante = 0;
      }
      break;
    case 7:
      variabile_pulsante = 2;
      break;
  }
}


void monitoraggio_pianta() {
  if ((stato_pulsante == LOW) && ((millis() - pressione_pulsante) > TIMEOUT_pressione_pulsante)) {
    variabile_pulsante++;
    pressione_pulsante = millis();
  }
  if ((variabile_pulsante != 36) && (variabile_pulsante != 37) && (variabile_pulsante != 38)) {
    cancella_schermo();
    myOLED.print(mon_pianta[0], CENTER, 1);
    myOLED.print(mon_pianta[1], 0, 10);
    myOLED.print(mon_pianta[2], 0, 20);
    myOLED.print(mon_pianta[3], 0, 30);
    myOLED.print(mon_pianta[4], 0, 40);
    if (incremento_tempo_campionamento > 1) {
      myOLED.print(stringa_tempo_campionamento, 55, 10);
    }
  }
  switch (variabile_pulsante) {
    case 30: // attende interazione utente

      break;
    case 31: //seleziona tempo
      posizione_cursore_altezza = 10;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 31) && ((millis() - pressione_pulsante) > 2000)) {
        tempo_campionamento = 5 * incremento_tempo_campionamento;
        itoa(tempo_campionamento, stringa_tempo_campionamento, 10);
        incremento_tempo_campionamento++;
        variabile_pulsante = 30;
      }
      break;
    case 32: //conferma
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 32) && ((millis() - pressione_pulsante) > 4000)) {
        Timeout_Campionamento_MP = (tempo_campionamento * 1000UL);
        START_Campionamento_MP = millis();
        variabile_pulsante = 36;
      }
      break;
    case 33: //annulla
      posizione_cursore_altezza = 30;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 33) && ((millis() - pressione_pulsante) > 2000)) {
        incremento_tempo_campionamento = 1;
        variabile_pulsante = 30;
      }
      break;
    case 34: //Esci e Annulla
      posizione_cursore_altezza = 40;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 34) && ((millis() - pressione_pulsante) > 2000)) {
        incremento_tempo_campionamento = 1;
        variabile_pulsante = 0;
      }
      break;
    case 35: //ricomincia il giro nel menu
      variabile_pulsante = 31;
      break;
    case 36: //avvio campionamento dati
      if (cancella_display == false) {
        cancella_display = true;
        cancella_schermo();
        myOLED.print(Stato_camp[0], 0, 1);
      }
      if (punto_raccolta_dati <= 16) {
        if ((millis() - START_Campionamento_MP) < Timeout_Campionamento_MP) {
          itoa((((Timeout_Campionamento_MP) / 1000) - (millis() - START_Campionamento_MP) / 1000), stringa_timer_restante_campionamento, 10);
          myOLED.print(Timer[0], 100, 0);
          myOLED.print(stringa_timer_restante_campionamento, 115, 0);
        }
        if ((millis() - START_Campionamento_MP) >= Timeout_Campionamento_MP) {
          START_Campionamento_MP = millis();
          Valore_umidita = analogRead(0);
          umiditaPianta = map (Valore_umidita, val_bagnato, val_asciutto, 100, 0);
          raccolta_dati[punto_raccolta_dati] =  umiditaPianta;
          sprintf(misurazione_RD, "%i", raccolta_dati[punto_raccolta_dati]);
          punto_raccolta_dati++;
          if (punto_raccolta_dati < 7) {
            myOLED.print(Lista_camp[punto_raccolta_dati - 2], 0, (10 * punto_raccolta_dati - 10));
            myOLED.print(misurazione_RD, 15, (10 * punto_raccolta_dati - 10));
          }
          if ((punto_raccolta_dati >= 7) && (punto_raccolta_dati <= 11)) {
            myOLED.print(Lista_camp[punto_raccolta_dati - 2], 25, ((10 * punto_raccolta_dati) - 60));
            myOLED.print(misurazione_RD, 40, ((10 * punto_raccolta_dati) - 60));
          }
          if ((punto_raccolta_dati >= 12) && (punto_raccolta_dati <= 15)) {
            myOLED.print(Lista_camp[punto_raccolta_dati - 2], 55, ((10 * punto_raccolta_dati) - 110));
            myOLED.print(misurazione_RD, 70, ((10 * punto_raccolta_dati) - 110));
          }
        }
        if (punto_raccolta_dati > 15) {
          myOLED.print(Stato_camp[1], 0, 1);
          variabile_pulsante = 37;
        }
      }
      break;
    case 37:
      myOLED.print(Menu[6], 105, 50);
      break;
    case 38:
      myOLED.print(cursore[0], 115, 50);
      if ((variabile_pulsante == 38) && ((millis() - pressione_pulsante) > 4000)) {
        punto_raccolta_dati = 1;
        for (punto_raccolta_dati = 1; punto_raccolta_dati < 17; punto_raccolta_dati++) {
          raccolta_dati[punto_raccolta_dati] = 0;
          tempo_campionamento = 0;
          cancella_display = false;
          variabile_pulsante = 0;
        }
      }
      break;
  }
}



void setup() {
  myOLED.begin();   // avvia oled
  myOLED.setBrightness(255);  // setta luminosit  oled
  myOLED.setFont(SmallFont);
  pinMode(pulsante, INPUT);
  EEPROM.get(8, Valore_Scarico);  //8-9-10-11-12 occupati
  EEPROM.get(13, Valore_Carico);  //13-14-15-16-17 occupati
  EEPROM.get(250, pianta_selezionata);  //4-5-6-7 occupati
  if (pianta_selezionata == 1) {
    cella_eeprom_bagnato = 0;
    cella_eeprom_asciutto = 4;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 2) {
    cella_eeprom_bagnato = 18;
    cella_eeprom_asciutto = 23;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 3) {
    cella_eeprom_bagnato = 28;
    cella_eeprom_asciutto = 33;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 4) {
    cella_eeprom_bagnato = 38;
    cella_eeprom_asciutto = 43;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 5) {
    cella_eeprom_bagnato = 48;
    cella_eeprom_asciutto = 53;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 6) {
    cella_eeprom_bagnato = 58;
    cella_eeprom_asciutto = 63;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 7) {
    cella_eeprom_bagnato = 68;
    cella_eeprom_asciutto = 73;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  if (pianta_selezionata == 8) {
    cella_eeprom_bagnato = 78;
    cella_eeprom_asciutto = 83;
    EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
    EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
  }
  t1 = millis();
}

void loop() {
  stato_pulsante = digitalRead(pulsante);

  if (nr < 10) {
    batteria = map(readVcc(), Valore_Carico, Valore_Scarico, 100, 0);
    somma_batteria = somma_batteria + batteria;
    somma_result = somma_result  + result ;
    nr++;
  }
  if (nr == 10) {
    media_batteria = somma_batteria / nr;
    media_result = somma_result / nr;
    nr = 0;
    somma_batteria = 0;
    somma_result = 0;
  }


  if (variabile_pulsante < 1) { // in modalit  calibrazione
    if ((stato_pulsante == LOW) && ((millis() - pressione_pulsante) > TIMEOUT_pressione_pulsante)) {
      variabile_pulsante++;
      pressione_pulsante = millis();
      if (variabile_pulsante > 3) {
        variabile_pulsante = 0;
      }
    }
  }

  switch (variabile_pulsante) {
    case 0: //misurazione normale
      cancella_schermo();
      misurazione_umidita();
      stato_batteria();
      break;
    case 1: //menu'
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
      menu();
      break;
    case 8: //calibrazione
    case 9:
    case 10:
    case 11:
    case 12:
      calibrazione();
      break;
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
      cal_batteria();
      break;
    case 18:
    case 19:
    case 20:
    case 21:
    case 22:
    case 23:
    case 24:
    case 25:
    case 26:
    case 27:
    case 28:
    case 29:
      seleziona_pianta();
      break;
    case 30:
    case 31:
    case 32:
    case 33:
    case 34:
    case 35:
    case 36:
    case 37:
    case 38:
      monitoraggio_pianta();
      break;
  }
  //if ((millis() - t1) > 1000) {
  // t1 = millis;
  myOLED.update();
  //wdt_reset();
  //}
}






long readVcc() {
  uint8_t low;
  uint8_t high;

  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring
  low  = ADCL; // must read ADCL first - it then locks ADCH
  high = ADCH; // unlocks both
  result = (high << 8) | low;
  result = 1127346L / result; // Calculate Vcc (in mV); 1125300 = 1.102*1023*1000
  return result; // Vcc in millivolts
}


void calibrazione() {
  if ((stato_pulsante == LOW) && ((millis() - pressione_pulsante) > TIMEOUT_pressione_pulsante)) {
    variabile_pulsante++;
    pressione_pulsante = millis();
  }
  cancella_schermo();
  myOLED.print(cal[0], CENTER, 1);
  myOLED.print(cal[1], 0, 20);
  //valore bagnato memorizzato
  itoa(val_bagnato, stringa_OLD_bagnato, 10);
  myOLED.print(stringa_OLD_bagnato, 80, 20);
  //valore asciutto memorizzato
  myOLED.print(cal[2], 0, 30);
  itoa(val_asciutto, stringa_OLD_asciutto, 10);
  myOLED.print(stringa_OLD_asciutto, 80, 30);
  // valore analogico di misurazione per calibrare i valori asciutti e bagnati
  Valore_umidita = analogRead(0);
  myOLED.print(cal[3], 0, 40);
  itoa(Valore_umidita, stringa_misurazione, 10);
  myOLED.print(stringa_misurazione, 80, 40);
  umiditaPianta = map (Valore_umidita, val_bagnato, val_asciutto, 100, 0);
  sprintf(misurazione, "%i", umiditaPianta);
  myOLED.print(cal[4], 103, 40);
  myOLED.print(misurazione, 110, 40);
  myOLED.print(cal[5], 0, 50);
  switch (variabile_pulsante) {
    case 8: // attendi interazione utente

      break;
    case 9:  // selezione calibrazione valore umido
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 9) && ((millis() - pressione_pulsante) > 4000)) {
        val_bagnato = Valore_umidita;
        EEPROM.put(cella_eeprom_bagnato, val_bagnato);
        variabile_pulsante = 8;
      }
      break;
    case 10: // selezione calibrazione valore asciutto
      posizione_cursore_altezza = 30;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 10) && ((millis() - pressione_pulsante) > 4000)) {
        val_asciutto = Valore_umidita;
        EEPROM.put(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        variabile_pulsante = 8;
      }
      break;
    case 11: // annulla scelta
      posizione_cursore_altezza = 50;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 11) && ((millis() - pressione_pulsante) > 2000)) {
        variabile_pulsante = 0;
      }
      break;
    case 12: // annulla scelta
      variabile_pulsante = 9;
      break;
  }
}
void misurazione_umidita() {
  cancella_schermo();
  Valore_umidita = analogRead(0);
  umiditaPianta = map (Valore_umidita, val_bagnato, val_asciutto, 100, 0);
  myOLED.print(mis_umidita[0], 0, 5);
  sprintf(misurazione, "%i", umiditaPianta);
  myOLED.setFont(MediumNumbers);
  myOLED.print(misurazione, 75, 1);
  myOLED.setFont(SmallFont);
  myOLED.print(mis_umidita[1], LEFT, 30);
  sprintf(stringa_pianta_selezionata, "%i", pianta_selezionata);
  myOLED.print(stringa_pianta_selezionata, 40, 30);
  myOLED.print(mis_umidita[2], 50, 30);
  myOLED.print(firmware[0], RIGHT, 50);

}

void stato_batteria() {
  myOLED.print(Bat[0], 0, 50);
  itoa(media_batteria, stringa_batteria, 10);
  myOLED.print(stringa_batteria, 25, 50);
}

void cal_batteria() {
  if ((stato_pulsante == LOW) && ((millis() - pressione_pulsante) > TIMEOUT_pressione_pulsante)) {
    variabile_pulsante++;
    pressione_pulsante = millis();
  }
  cancella_schermo();
  myOLED.print(cal_bat[0], CENTER, 1);
  myOLED.print(cal_bat[1], 0, 10);
  itoa(media_batteria, stringa_batteria, 10);
  myOLED.print(stringa_batteria, 50, 10);
  myOLED.print(cal_bat[2], 0, 20);
  itoa(media_result, stringa_result, 10);
  myOLED.print(stringa_result, 70, 20);
  myOLED.print(cal_bat[3], 0, 30);
  itoa(Valore_Scarico, stringa_Valore_Scarico, 10);
  myOLED.print(stringa_Valore_Scarico, 90, 30);
  myOLED.print(cal_bat[4], 0, 40);
  itoa(Valore_Carico, stringa_Valore_Carico, 10);
  myOLED.print(stringa_Valore_Carico, 90, 40);
  myOLED.print(cal_bat[5], 0, 50);
  switch (variabile_pulsante) {
    case 13:

      break;
    case 14: //selezione calibrazione batteria
      posizione_cursore_altezza = 30;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 14) && ((millis() - pressione_pulsante) > 4000)) {
        Valore_Scarico = media_result;
        EEPROM.put(8, Valore_Scarico);
        variabile_pulsante = 13;
      }
      break;
    case 15: //aggiorna valore batterie cariche
      posizione_cursore_altezza = 40;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 15) && ((millis() - pressione_pulsante) > 4000)) {
        Valore_Carico = media_result;
        EEPROM.put(13, Valore_Carico);
        variabile_pulsante = 13;
      }
      break;
    case 16: //aggiorna valore batterie scariche
      posizione_cursore_altezza = 50;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 16) && ((millis() - pressione_pulsante) > 2000)) {
        variabile_pulsante = 0;
      }
      break;
    case 17: //aggiorna valore batterie scariche
      variabile_pulsante = 14;
      break;
  }
}

void seleziona_pianta() {
  if ((stato_pulsante == LOW) && ((millis() - pressione_pulsante) > TIMEOUT_pressione_pulsante)) {
    variabile_pulsante++;
    pressione_pulsante = millis();
  }
  cancella_schermo();
  myOLED.print(sel_pianta[0], CENTER, 1);
  if ((EEPROM.read(0) == 1) || (EEPROM.read(4) == 1)) {
    myOLED.print(sel_pianta[1], 0, 10);
  } else {
    myOLED.print(sel_pianta[2], 0, 10);
  }
  if ((EEPROM.read(18) == 1) || (EEPROM.read(23) == 1)) {
    myOLED.print(sel_pianta[3], 0, 20);
  } else {
    myOLED.print(sel_pianta[4], 0, 20);
  }
  if ((EEPROM.read(28) == 1) || (EEPROM.read(33) == 1)) {
    myOLED.print(sel_pianta[5], 0, 30);
  } else {
    myOLED.print(sel_pianta[6], 0, 30);
  }
  if ((EEPROM.read(38) == 1) || (EEPROM.read(43) == 1)) {
    myOLED.print(sel_pianta[7], 0, 40);
  } else {
    myOLED.print(sel_pianta[8], 0, 40);
  }
  if ((EEPROM.read(48) == 1) || (EEPROM.read(53) == 1)) {
    myOLED.print(sel_pianta[9], 0, 50);
  } else {
    myOLED.print(sel_pianta[10], 0, 50);
  }
  if ((EEPROM.read(58) == 1) || (EEPROM.read(63) == 1)) {
    myOLED.print(sel_pianta[11], 60, 10);
  } else {
    myOLED.print(sel_pianta[12], 60, 10);
  }
  if ((EEPROM.read(68) == 1) || (EEPROM.read(73) == 1)) {
    myOLED.print(sel_pianta[13], 60, 20);
  } else {
    myOLED.print(sel_pianta[14], 60, 20);
  }
  if ((EEPROM.read(78) == 1) || (EEPROM.read(83) == 1)) {
    myOLED.print(sel_pianta[15], 60, 30);
  } else {
    myOLED.print(sel_pianta[16], 60, 30);
  }
  myOLED.print(sel_pianta[17], 60, 40);
  myOLED.print(sel_pianta[18], 60, 50);
  switch (variabile_pulsante) {
    case 18: // attende interazione utente

      break;
    case 19: //pianta 1
      posizione_cursore_altezza = 10;
      posizione_cursore_larghezza = 52;
      cursore_furbo();
      if ((variabile_pulsante == 19) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 0;
        cella_eeprom_asciutto = 4;
        pianta_selezionata = 1;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(0) == 1) || (EEPROM.read(4) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 20: //pianta 2
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 52;
      cursore_furbo();
      if ((variabile_pulsante == 20) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 18;
        cella_eeprom_asciutto = 23;
        pianta_selezionata = 2;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(18) == 1) || (EEPROM.read(23) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 21: //pianta 3
      posizione_cursore_altezza = 30;
      posizione_cursore_larghezza = 52;
      cursore_furbo();
      if ((variabile_pulsante == 21) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 28;
        cella_eeprom_asciutto = 33;
        pianta_selezionata = 3;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(28) == 1) || (EEPROM.read(33) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 22: //pianta 4
      posizione_cursore_altezza = 40;
      posizione_cursore_larghezza = 52;
      cursore_furbo();
      if ((variabile_pulsante == 22) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 38;
        cella_eeprom_asciutto = 43;
        pianta_selezionata = 4;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(38) == 1) || (EEPROM.read(43) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 23: //pianta 5
      posizione_cursore_altezza = 50;
      posizione_cursore_larghezza = 52;
      cursore_furbo();
      if ((variabile_pulsante == 23) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 48;
        cella_eeprom_asciutto = 53;
        pianta_selezionata = 5;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(48) == 1) || (EEPROM.read(53) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 24: //pianta 6
      posizione_cursore_altezza = 10;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 24) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 58;
        cella_eeprom_asciutto = 63;
        pianta_selezionata = 6;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(58) == 1) || (EEPROM.read(63) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 25: //pianta 7
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 25) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 68;
        cella_eeprom_asciutto = 73;
        pianta_selezionata = 7;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(68) == 1) || (EEPROM.read(73) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 26: //pianta 8
      posizione_cursore_altezza = 30;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 26) && ((millis() - pressione_pulsante) > 4000)) {
        cella_eeprom_bagnato = 78;
        cella_eeprom_asciutto = 83;
        pianta_selezionata = 8;
        EEPROM.update(250, pianta_selezionata);
        EEPROM.get(cella_eeprom_bagnato, val_bagnato);  //0-1-2-3 occupati
        EEPROM.get(cella_eeprom_asciutto, val_asciutto);  //4-5-6-7 occupati
        if ((EEPROM.read(78) == 1) || (EEPROM.read(83) == 1)) {
          variabile_pulsante = 8;
        } else {
          variabile_pulsante = 0;
        }
      }
      break;
    case 27: //cancella memoria eeprom
      posizione_cursore_altezza = 40;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 27) && ((millis() - pressione_pulsante) > 4000)) {
        val_bagnato = 1;
        EEPROM.put(0, val_bagnato);
        EEPROM.put(18, val_bagnato);
        EEPROM.put(28, val_bagnato);
        EEPROM.put(38, val_bagnato);
        EEPROM.put(48, val_bagnato);
        EEPROM.put(58, val_bagnato);
        EEPROM.put(68, val_bagnato);
        EEPROM.put(78, val_bagnato);
        val_asciutto = 1;
        EEPROM.put(4, val_asciutto);
        EEPROM.put(23, val_asciutto);
        EEPROM.put(33, val_asciutto);
        EEPROM.put(43, val_asciutto);
        EEPROM.put(53, val_asciutto);
        EEPROM.put(63, val_asciutto);
        EEPROM.put(73, val_asciutto);
        EEPROM.put(83, val_asciutto);
        variabile_pulsante = 18;
      }
      break;
    case 28: // esci
      posizione_cursore_altezza = 50;
      posizione_cursore_larghezza = 115;
      cursore_furbo();
      if ((variabile_pulsante == 28) && ((millis() - pressione_pulsante) > 2000)) {
        variabile_pulsante = 0;
      }
      break;
    case 29: //ricomincia da pianta 1
      variabile_pulsante = 19;
      break;
  }
}

Prova a remmare questo pezzo, facendo in modo che non funziona, vedi se sparisce il problema.
Nell'attesa da 0 a 5 secondi di continuo fai quel pezzo di codice, che presumo sia pesante, visto che fa calcoli e soprattutto continuamente print al display. Solo una supposizione.

ci avevo pensato anche io e avevo messo le // al calcolo sotto ma nulla , sempre uguale...
itoa((((Timeout_Campionamento_MP) / 1000) - (millis() - START_Campionamento_MP) / 1000), stringa_timer_restante_campionamento, 10);

L'ho detto che farcire il loop di codice prima o poi non si capisce più nulla.
Io vedo solo (ma non sono sicuro) che dal case 32: cedi il controllo al case 36: dove vedo una sola condizione di uscita:

       if (punto_raccolta_dati > 15) {
          myOLED.print(Stato_camp[1], 0, 1);
          variabile_pulsante = 37;
        }

Al case 37: resta li e non va altrove. I punti di uscita dovrebbero risaltare alla vista come una mosca bianca tra mille nere. Puoi provare a metterli in risalto con un commento seguente:

       if (punto_raccolta_dati > 15) {
          myOLED.print(Stato_camp[1], 0, 1);
          // lasciando uno spazio
          // !!! CAMBIO STATO !!! 
          variabile_pulsante = 37;
        }

Non puoi andare avanti con questo schema, ti serve la programmazione modulare. Purtroppo non è facile ed intuitiva e ci vorrà parecchio tempo per riuscire a metterla a frutto. Un primo passo lo devi fare in questa direzione.

Ciao.

Ciao Mauro,
Indubbiamente il codice va sistemato e commentato meglio, nel caso specifico il case 37 è volutamente di attesa dopo aver finito la fase del campionamento(case 36)... quindi il case 37 serve a far rimanere la schermanta con i dati campionati fino a quando l'utente non interagisce premendo nuovamente il pulsante entrando nel case 38...

Nn so cosa sia la programmazione modulare e mi informerò sicuramente...

Ma nello specifico quale case 32: perché ne vedo almeno 2. Uno è vuoto e e arriva al cae 38: dove c'è la chiamata a funzione monitoraggio_pianta();

Dovè che manca la temporizzazione di 5 secondi?

Ciao.

Per me che ho provato a seguire il codice andando in confusione tutte le volte tanto che ci devo rinunciare. Il codice è pieno di "senza senso", prendi questo:

switch (variabile_pulsante) {
    case 2: //selezione calibrazione
      posizione_cursore_altezza = 10;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 2) && ((millis() - pressione_pulsante) > 2000)) {
        calibrazione();
        variabile_pulsante = 8;
      }
      break;

Se arduino sta eseguendo il case 2, vuole dire che la variabile variabile_pulsante ha valore 2. Che senso ha la if((variabile_pulsante == 2.. è ovvio che la condizione (variabile_pulsante == 2) è vera.
Tutto il codice è pieno di questi "senza senso" che mi impediscono di seguire il codice.

Vedo anche il case 37 che mi hai indicato e questo per me è un altro senza senso:

case 37:
      myOLED.print(Menu[6], 105, 50);
      break;

Che senso ha stampare su schermo sempre le stesse informazioni, stamparle una sola volta dovrebbe essere più che sufficiente. La stampa costa cicli CPU, che senso ha consumare cicli CPU per scrivere sullo schermo sempre la stessa cosa.

Non so proprio che pesci prendere e che consiglio darti. :confused:

Ciao.

perchè dici che ci sono due case 32 ? c'è solo questo sotto all'interno di void monitoraggio_pianta() ( escluso quello che nel loop() mi richiama proprio il void monitoraggio_pianta() )

    case 32: //conferma
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 32) && ((millis() - pressione_pulsante) > 4000)) {
        Timeout_Campionamento_MP = (tempo_campionamento * 1000UL);
        START_Campionamento_MP = millis();
        variabile_pulsante = 36;
      }
      break;

Per me che ho provato a seguire il codice andando in confusione tutte le volte tanto che ci devo rinunciare. Il codice è pieno di "senza senso", prendi questo:

concordo con te, il codice è nettamente da migliorare e ottimizzare, oltre che deve essere commentato come si deve... pensavo tuttavia che era cmq comprensibile...

Considera che è la prima volta che uso gli switch case e le manipolazioni delle stringhe e tutto sommato come prima volta mi ritengo molto soddisfatto... :slight_smile:

Se arduino sta eseguendo il case 2, vuole dire che la variabile variabile_pulsante ha valore 2. Che senso ha la if((variabile_pulsante == 2.. è ovvio che la condizione (variabile_pulsante == 2) è vera.
Tutto il codice è pieno di questi "senza senso" che mi impediscono di seguire il codice.

hai perfettamente ragione, e provvederò a sistemare, ma come è possibile che questa ovvietà non ti fa seguire il codice?

case 37:
      myOLED.print(Menu[6], 105, 50);
      break;

Che senso ha stampare su schermo sempre le stesse informazioni, stamparle una sola volta dovrebbe essere più che sufficiente. La stampa costa cicli CPU, che senso ha consumare cicli CPU per scrivere sullo schermo sempre la stessa cosa.

Non so proprio che pesci prendere e che consiglio darti. :confused:

Ciao.

anche qui sono d'accordo con te, ma non sono riuscito a trovare un'illuminazione su come far stampare una volta sola una stringa se mi ritrovo sempre all'interno di un case specifico fino a nuova interazione dell'utente... forse tramite una flag?...

[quote="simosere, post:1, topic:1163720"]

> if ((millis() - START_Campionamento_MP) < Timeout_Campionamento_MP) {
>           itoa((((Timeout_Campionamento_MP) / 1000) - (millis() - START_Campionamento_MP) / 1000), stringa_timer_restante_campionamento, 10);
>           myOLED.print(Timer[0], 100, 0);
>           myOLED.print(stringa_timer_restante_campionamento, 115, 0);
>         }
> ```
> [/quote]
> 
> Prova a remmare questo pezzo, facendo in modo che non funziona, vedi se sparisce il problema.
> Nell'attesa da 0 a 5 secondi di continuo fai quel pezzo di codice, che presumo sia pesante, visto che fa calcoli e soprattutto continuamente print al display. Solo una supposizione.

in attesa del WE per smanettare ancora e cominciare a mettere in pratica i consigli ricevuti... la cosa che mi fa riflettere è che questo ritardo lo ottengo solo quando sono all'interno del case 36, ma mai ll'interno degli altri case.... forse devo approfondire e fare ulteriori prive seguendo lo spunto di nid... che voi sappiate l'uso di itoa è cosi pesante?

sto pensando di modificare la parte sopra del case 36 con questa:

    if ((millis() - START_Campionamento_MP) < Timeout_Campionamento_MP) {
      if ((millis() - START_Campionamento_MP) > 1000) {
      Tempo_rimanente_MP_a_display = (((Timeout_Campionamento_MP) / 1000) - (millis() - 
       START_Campionamento_MP) / 1000); // uso int Tempo_rimanente_MP_a_display per semplificare la conversione di itoa
      itoa(Tempo_rimanente_MP_a_display, stringa_timer_restante_campionamento, 10);
      myOLED.print(stringa_timer_restante_campionamento, 115, 0);
    }
    }

NO, non solo al calcolo, poca roba, ma al continuo sparare dati al display, cosa moooolto lenta!!
Ti ho scritto "Prova a remmare questo pezzo," quindi TUTTO il pezzo

ok ci provo appena posso, ma come cavolo faccio a non aggiornare di continuo il display? è possibile un esempio?

anche qui sono d'accordo con te, ma non sono riuscito a trovare un'illuminazione su come far stampare una volta sola una stringa se mi ritrovo sempre all'interno di un case specifico fino a nuova interazione dell'utente... forse tramite una flag?...

Il codice non è semplice da comprendere (come già hanno detto), però a me sembra che se il problema di cui ti lamenti è legato al millis() ossia a "pressione_pulsante" ho l'impressione che dovresti verificare bene dov'è che la imposti, perché hai una sola variabile che rappresenta l'inizio di un evento, ma la verifichi e la reimposti in vari punti del codice, apparentemente per scopi totalmente diversi.
Non so se sia questo il problema, ma tu che conosci meglio di noi il tuo codice magari ti può aiutare.

ciao doc doc,
no, la parte con rallentamento di millis() è quella che che lavora nel case 32 e case 36:

   case 32: //conferma
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 32) && ((millis() - pressione_pulsante) > 4000)) {
        Timeout_Campionamento_MP = (tempo_campionamento * 1000UL);
        START_Campionamento_MP = millis();
        variabile_pulsante = 36;
      }
case 36: //avvio campionamento dati
      if (cancella_display == false) {
        cancella_display = true;
        cancella_schermo();
        myOLED.print(Stato_camp[0], 0, 1);
      }
      if (punto_raccolta_dati <= 16) {
        if ((millis() - START_Campionamento_MP) < Timeout_Campionamento_MP) {
          itoa((((Timeout_Campionamento_MP) / 1000) - (millis() - START_Campionamento_MP) / 1000), stringa_timer_restante_campionamento, 10);
          myOLED.print(Timer[0], 100, 0);
          myOLED.print(stringa_timer_restante_campionamento, 115, 0);
        }
        if ((millis() - START_Campionamento_MP) >= Timeout_Campionamento_MP) {
          START_Campionamento_MP = millis();
          Valore_umidita = analogRead(0);
          umiditaPianta = map (Valore_umidita, val_bagnato, val_asciutto, 100, 0);
          raccolta_dati[punto_raccolta_dati] =  umiditaPianta;
          sprintf(misurazione_RD, "%i", raccolta_dati[punto_raccolta_dati]);
          punto_raccolta_dati++;
          if (punto_raccolta_dati < 7) {
            myOLED.print(Lista_camp[punto_raccolta_dati - 2], 0, (10 * punto_raccolta_dati - 10));
            myOLED.print(misurazione_RD, 15, (10 * punto_raccolta_dati - 10));
          }
          if ((punto_raccolta_dati >= 7) && (punto_raccolta_dati <= 11)) {
            myOLED.print(Lista_camp[punto_raccolta_dati - 2], 40, ((10 * punto_raccolta_dati) - 60));
            myOLED.print(misurazione_RD, 60, ((10 * punto_raccolta_dati) - 60));
          }
          if ((punto_raccolta_dati >= 12) && (punto_raccolta_dati <= 16)) {
            myOLED.print(Lista_camp[punto_raccolta_dati - 2], 80, ((10 * punto_raccolta_dati) - 110));
            myOLED.print(misurazione_RD, 100, ((10 * punto_raccolta_dati) - 110));
          }
        }
        if (punto_raccolta_dati == 16) {
          punto_raccolta_dati = 17;
          myOLED.print(Stato_camp[1], 0, 1);
          variabile_pulsante = 37;
        }
      }
      break;

Si ma tu imposti la variabile in molti punti, prova a cercare "pressione_pulsante = millis()" nel codice e vedi ad esempio che la reimposti nel loop(), in calibrazione(), in cal_batteria(), eccetera!
Come dicevo, è difficile seguire il flusso logico e relativo percorso, ma secondo me basta che passi in (almeno) uno di quei punti, ed ecco che ti "salta" il calcolo dei 5 secondi che vorresti attendere, con "allungamenti" inattesi. Se hai tempi diversi da contare per scopi diversi, usa variabili diverse.
Fammi sapere.

Ciao Doc Doc,
ok ho capito il tuo ragionamento, ma i 5 sec li setto nel case 31 e poi lo setto come TIMEOUT nel case 32:

    case 31: //seleziona tempo
      posizione_cursore_altezza = 10;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 31) && ((millis() - pressione_pulsante) > 2000)) {
        tempo_campionamento = 5 * incremento_tempo_campionamento;
        itoa(tempo_campionamento, stringa_tempo_campionamento, 10);
        incremento_tempo_campionamento++;
        variabile_pulsante = 30;
      }
      break;
case 32: //conferma
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 32) && ((millis() - pressione_pulsante) > 4000)) {
        Timeout_Campionamento_MP = (tempo_campionamento * 1000UL);
        START_Campionamento_MP = millis();
        variabile_pulsante = 36;
      }

e poi procedo con il 36... in questo caso pressione_pulsante non viene più richiamato... no!?

Mah, ancora non mi hai convinto. :wink:

Tu quindi parli di "tempo_campionamento" che però non è direttamente gestito da millis() come invece accade per "pressione_pulsante" (che è quello che ti ho indicato), e di "START_Campionamento_MP". Ma proprio per questo, se "pressione_pulsante" lo setti in 6 posti differenti (quindi con 6 criteri differenti) ed in base a questo decidi se impostare o incrementare "tempo_campionamento" che a sua volta imposta "START_Campionamento_MP" (nei case 32 e 36) a me sembra che il problema sia in qualcosa o qualche evento che sfugge al tuo controllo.

Comprendo che il mio non sia un aiuto puntuale, ma temo che se queste indicazioni di massima non ti aiutano, l'unico modo sia di infarcire il codice di Serial.print() (non usi proprio la seriale...)
e cercare di capire dov'è che viene reimpostato/spostato uno start del conteggio che si basa su millis(), quindi o "pressione_pulsante" o "START_Campionamento_MP".

Ovviamente in futuro ti conviene cercare di scrivere codice un po' più strutturato, ad esempio dividendo il codice in moduli separati (*.h o *.ino, o perfino classi *.cpp) in base al loro ambito (es. uno che gestisce il display, uno per la lettura dei sensori, uno per i tasti e gestione dei menu, eccetera), oppure ancora se "variabile_pulsante" la consideriamo uno stato di una macchina a stati finiti, oltre a dargli un nome più parlante, sarebbe utile sostituire i valori numerici con delle costanti (#define o const byte) con nomi significativi. tutto questo perr rendere il tutto ben più leggibile e gestibile per te facilitandone anche il debug (la programmazione strutturata serve anche a tutto questo), ma anche per noi.. :wink:

PS: comunque dovresti sempre specificare di quale modello di Arduino si sta parlando, perché ci possono essere considerazioni legate alle specifiche versioni e piattaforme... Quale Arduino usi quindi?

Consiglio per migliorare leggibilità codice:
Per i valori della variabile "variabile_pulsante" crea delle costanti con nomi brevi ma che ricordano cosa devono fare. Esempio questo pezzo:

  case 3: //selezione batteria
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ((variabile_pulsante == 3) && ((millis() - pressione_pulsante) > 2000)) {
        cal_batteria();
        variabile_pulsante = 13;
      }

Se invece di 3 e 13 c'e' scritto K_qualcosa è più leggibile

#define K_SEL_BAT 3
#define K_CAL_BAT 13
....
  case K_SEL_BAT: //selezione batteria
      posizione_cursore_altezza = 20;
      posizione_cursore_larghezza = 105;
      cursore_furbo();
      if ( millis() - pressione_pulsante > 2000 ) {
        cal_batteria();
        variabile_pulsante = K_CAL_BAT;
      }

Ancora non ho capito che cosa significhi "posizione_cursore_larghezza"... Larghezza della posizione del cursore? Cioè? Forse è la posizione orizzontale del cursore?... pos_h_cursore...

pressione_pulsante, poi, mi fa pensare che indichi se è premuto, invece viene sottratta a millis(), perciò la chiamerei t_press_pulsante, uniformando tutte le variabili che memorizzano millis() facendole iniziare con t_.

Anche cursore_furbo() non si capisce bene che cosa faccia di tanto furbo...

variabile_pulsante: stato?

Con tante variabili, sarebbe utile una descrizione dell'uso di ciascuna accanto alla dichiarazione iniziale.

Forse, sempre se ho capito bene, c'è modo di evitare tutto quel codice che legge da eeprom per la pianta selezionata.
Per poterlo rendere più comprensibile, efficiente e anche modulare, dovrei sapere se per ogni pianta è possibile creare una struttura dati che la descrive.

Ad esempio, ipoteticamente la struttura pianta per esempio è:

struct PiantaDati {
     uint8_t id;
     uint32_t bagnato;
     uint32_t asciutto;
};     

Che occupa 4 + 4 + 1 byte = 9
Inizierei da qui a mettere un poco di ordine e contemporaneamente accorciare la dimensione del .ino e spostare la gestione del database (che salvi in eeprom) in un modulo .cpp separato. Questo dovrebbe ridurre il numero di variabili globali grazie al modulo separato.

Ciao.

Questa domanda è importante e quindi vista l'importanza e bene rispondere.

  1. Io, te, o qualunque altro programmatore non sono familiari con il codice. Tu per adesso puoi dire di avere una certa familiarità con il codice, ma se stai 2 mesi senza pensare e visionare questo sketch perdi familiarità. Questa affermazione deriva dalla pratica ma anche dallo studio, cioè è scritto nei libri di ingegneria del software. Brevemente c'è scritto che l'essere umano una capacità di memoria a breve termine molto limitata.

Ecco che la limitazione umana (la mia in particolare) mi porta in confusione. Scorro in alto per memorizzare alcune variabili che ipotizzo siano determinanti, scorro verso il basso e leggo qualcosa che non ha senso, ma mi dico che deve avere un senso, quindi sono io con le mie limitazioni che al momento non ci vedo il senso, quindi c'è lo devo trovare il motivo per cui c'è quel codice, nel frattempo la limitazione mi fa dimenticare le variabili di cui avevo preso nota nella mia memoria a breve termine. E quindi sono costretto a scorrere nuovamente su e ripetere la procedura, e proseguendo accade la stessa cosa. Questo porta via tantissimo tempo senza concludere nulla.

Se è pratica comune scrivere sul display delle informazioni ripetutamente vuole dire che i dati possono cambiare tra una esecuzione e l'altra, quindi deve capire quali dati cambiano ma sembra che non cambino, ma sono sicuro, no non lo sono non ho familiarità con il codice.

Cancellare lo schermo
Cancellare integralmente lo schermo ha senso solo quando il contenuto della schermata deve cambiare, cioè sto visionando la schermata dei dati della batteria i dati cambiano ma i nomi dei campi sono sempre quelli e non devo riscriverli devo solo aggiornare i dati che cambiano. Ok cambia schermata * selezione pianta* ora ha senso cancellare lo schermo integralmente per stampare una sola volta la maschera dei campi e periodicamente aggiornare i dati che sono cambiati.

Per il tuo sapere attuale ti sei spinto oltre il limite e i sintomi sono quelli tipici, funziona, ma qualcosa non torna e ti sta facendo perdere tanto tempo. Aggiungendo funzionalità alla attuale struttura le cose non possono certo migliorare.

Però non è tutto da buttare, serve prendere quello che funziona e confinarlo in funzioni che magari risiedono dentro un modulo .cpp.

Ciao.

Io da qui:

#define pulsante 9
int stato_pulsante = 0;
byte variabile_pulsante = 0;
byte variabile_pulsante_calibrazione = 0;
unsigned long pressione_pulsante = 0;
unsigned long TIMEOUT_pressione_pulsante = 500;
unsigned long durata_pressione_pulsante = 0;
bool cambio_stato_pulsante_calibrazione = false;

Capisco solo che il pulsante è collegato al pin 9. Non capisco a che livello si trova quando è premuto. Non capisco se gli viene applicato un debounce. Non capisco come deve essere usato, nel senso di quali/quante diverse cose debba fare. Non basta rilevare (all'inizio del loop) un click o un longpress, con due variabili da usare nel resto del programma, senza ripetere ogni poche righe tutti i controlli su LOW, millis ecc?