millis permette di gestire più liberamente e con miglior precisione i tempi, ma quello che conta alla fine è solo il design della logica. Se si vuole controllare che un valore rimanga stabile per un certo tempo, basta confrontarlo con il valore precedente per un certo numero di volte/tempo.
Con millis:
in = digitalRead(5);
if (in == inPrec)
{
t = millis;
}
else if (millis()-t > 5000)
{
inPrec = in;
if (0 == in) { ...pump on... }
else { ...pump off... }
}
Con delay da 50ms (contando i delay):
in = digitalRead(5);
if (in == inPrec) { t = 0; } else { t++; }
if (100 == t)
{
inPrec = in;
if (0 == in) { ...pump on... }
else { ...pump off... }
}
delay(50);
Hai sempre le soluzione più furbe, gli algoritmi migliori
Traducendo in parole il tuo primo algoritmo
1)Prima condizione, se in segnale non cambia continua a prendere il tempo
2)Se il segnale è cambiato, controlla che siano passati 5 secondi
3) Se il segnale è zero accendi, altrimenti spegni.
millis() è una semplice funzione che restituisce un valore corrispondente al numero di millisecondi trascorsi da quando è stato avviato il microcontrollore, c'è poco da studiare a dire il vero.
Quello che conta, come giustamente ha ricordato @Claudio_FF, è l'algoritmo ovvero come tu decidi di usare il set di istruzioni disponibili con Arduino/C++ e quello è tutta una questione di logica e fantasia volendo.
L'algoritmo illustrato da Claudio (che di base è lo stesso che ho usato io, forse complicandolo un po' troppo per il tuo livello attuale) è un classico esempio di utilizzo di millis().
Uso il valore restituito a millis() per "congelare" il momento in cui ho un evento specifico e poi controllo continuamente se è passato il tempo minimo che ho imposto prima di agire di conseguenza, il tutto senza bloccare inutilmente il micro che nel frattempo può continuare a fare altro se necessario.
Chiaro, quindi se utilizzassi un contatore al posto di millis() si bloccherebbe il microcontrollore? Nel senso: se volessi unire due codici, entrambi che prevedono un contatore non potrei?