Temporizzazione if

Buon pomeriggio a tutti.
Quest'oggi ho una domanda forse banale per molti di voi ma che mi sta facendo scaldare la capoccia...

In uno sketch che sto sviluppando ho uno switch con vari case e vorrei temporizzare ogni case... mi spiego meglio.

      case 3:   // Modo = 3 -> Manuale con valvola 1 accesa
        {
          wdt_reset();
          resetta_EV();
          lcd.setCursor(10, 1);
          lcd.print(Modo - 2);
          digitalWrite(uscite[0], tempStato);
          if (masterpump == 0)
            digitalWrite(PUMP, LOW);
          else
            digitalWrite(PUMP, tempStato);
          statoEV[0] = 1;
          lcd.setCursor(6, 3);
          lcd.print(AR1);
          if (FlagAllarme == 0)
          {
            lcd.setCursor(19, 0);
            if (second() % 2 == 0) lcd.print(" "); else lcd.write((uint8_t)1);
          }
          else
          {
            lcd.setCursor(19, 0);
            lcd.print(" ");
          }
        }
        break;

Vorrei che il codice contenuto in questo case 3 venisse eseguito una sola volta per tot tempo per poi non essere rieseguito fino a che non si riverifica il caso, a prescindere dal tempo in cui rimane vero il caso in questione, ovvero:

  • Accendo manualmente la valvola 1;
  • Dopo 15 minuti si spegne in automatico la valvola SE non cambio uscita (diverso case);
  • Se cambio case si resetta il conteggio;

Come posso fare?

Con i millis().
Salvi il valore in una variabile ed esegui un controllo all'interno del relativo case.
Se scegli un altro case basta riassegnare il valore alla variabile annullando il tempo trascorso.

Guarda l'esempio del blink without delay.

  1. Salvi il valore di millis() la prima volta che entri nel case.
  2. Quando entri nel case fai la differenza tra il millis() attuale e il valore salvato, che ti dirà quanti ms sono passati dalla volta precedente. Verifica se tale valore è superiore a quello desiderato e solo in tal caso fai quel che devi e, solo in tal caso, aggiorna il millis() salvato.
  3. Ogni volta che vuoi resettare aggiorna il millis() salvato.

Occhio solo ai possibili overflow.

SukkoPera:
Occhio solo ai possibili overflow.

Problema risolto nel lontano 2012. :grin:
--> http://www.leonardomiliani.com/2012/come-gestire-loverflow-di-millis/

Beh, è proprio quel che intendevo! :slight_smile: Le soluzioni all'overflow esistono ma bisogna implementarle! 8)

Se però io dovessi eseguire il ciclo fintanto che il tempo è minore della soglia che ho impostato?

Beh, hai a disposizione una funzione che ogni volta che la chiami ti ritorna i millisecondi passati dall'accensione. Con quella e un po' di fantasia puoi fare tutto quel che vuoi! 8)

Ok.. nei prossimi giorni provo!

Grazie a tutti per l'aiuto!

SukkoPera:
Beh, è proprio quel che intendevo! :slight_smile: Le soluzioni all'overflow esistono ma bisogna implementarle! 8)

Non c'é problema di overflow se non hai bisogno di ritardi maggiori di ca 49,5 giorni.

Ciao Uwe

Vero, ma preferisco mettere sul "chi va là" chiunque si accinga a smanettare con gli intervalli di tempo: ad esempio, se vedi un altro thread attivo in questo momento, si sta salvando il valore di ritorno di millis() in un int, il che riduce di molto gli intervalli memorizzabili.

Ho risolto andando ad effettuare dei confronti sull'UTC (Unix Time o Universal Time) dell'RTC, così posso inserire il ritardo che voglio in secondi senza avere problemi di cifre positive e negative.

Grazie a tutti per l'aiuto!