Delay ma con notifiche

Ciao a tutti, sto facendo un semplice programma che fondamentalmente accende e spegne una ventola.
Diciamo che devo creare dei cicli di accensione e spegnimento che durano svariati secondi.
Per farlo ho usato il delay(ms) però questo ovviamente blocca l'esecuzione del codice per tutta la durata
del delay che può variare da 15 a 60 secondi ma potrebbe anche servirmi di più tempo di pausa, lo scoprirò in fase di test "sul campo".
Mi servirebbe non bloccare l'esecuzione per permettere notifiche in tempo reale sulla seriale (un domani su un display) del tempo trascorso , percentuale dell'avanzamento del ciclo e cose così.
Avevo pensato di definire una funzione di pausa che accettasse in ingresso il numero di secondi e che all'interno facesse dei tot cicli quanti sono i secondi e alla fine di ogni ciclo/secondo restituisse la notifica.
Mi sembra poco elegante come sistema anche in prospettiva di usare display e forse sensori in futuro.
In genere come si gestiscono queste cose? Potete darmi qualche indicazione? Grazie.

Ottimo, ti ringrazio! Proprio quello che stavo cercando.

Nel frattempo grazie all’aiuto del forum ho aggiunto alcune cose al mio progetto, un paio di led di controllo e un sensore di temperatura.
Vi chiedo se cortesemente di darmi una controllata al codice che funziona, l’ho già testato, solo per ottimizzarlo un attimo e renderlo più semplice da riprendere per mano.
Mi sembra un po’ “incasinato”.

Opinioni, commenti e modifiche sono graditi.

note:
Le parti commentate in inglese sono copia incolla di codice che devo approfondire.
I tempi nei #define sono accorciati per permettere il controllo delle funzionalità.

/*
  Ventola

  Esegue l'acensione e lo spegnimento di una ventola per ravvivare braciere affumicatore.
  Il warmup iniziale accende correttamente il bracere.
  pausa tiene spenta la ventola per non surriscaldare e consumare eccessivamente la brace.
  funzion da il colpetto di ventola di pochi secondi per ravvivare la brace che non si spenga.
  t_max è la durata del programma quindi del processo di affumicatura.
  Aggiunto controllo temperatura con sensore di temperatura digitale DS18B20

  Creato nel 2018
  da Gianluca Frare
  sulla base di Blink without Delay

*/
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2  // Data wire is conntec to the Arduino digital pin 2

#define fanPin 9
#define MIN 0
#define MAX 255
#define warmup 10     //secondi avvio della brace
#define pausa 15       //secondi di pausa 
#define funzion 10    //secondi di funzionamento per ravvivare brace
#define t_max 120      //secondi totali ciclo di affumicatura

OneWire oneWire(ONE_WIRE_BUS);        // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature sensor
char temperatura;                    //variabile 8bit per la temperatura -128 +127 (niente virgola)

const int led_rosso =  3;       // pin del led rosso
const int led_verde =  5;       // pin del led verde

unsigned int   t_trascorso;   //attenzione non superare 65000sec (18 ore)
unsigned int   t_stato_prec = 0;
byte  fase = 0;      //fase 0 warmup, fase 1 pausa, fase 2 ravvivamento, fase 3 STOP, fase 4 TEMPERATURA ALTA

void setup()  {
  pinMode(fanPin, OUTPUT);
  pinMode(led_rosso, OUTPUT);
  pinMode(led_verde, OUTPUT);

  Serial.begin(9600);
  sensors.begin();
  Serial.println("Ready!");
}

void loop()  {
  t_trascorso = millis() / 1000;                    // tempo trascorso in secondi dall'inizio del programma
  
  if (temperatura < 35) {                           //se la temperatura è bassa e 
    if (t_trascorso > warmup && fase == 0) {        //se il tempo di warmup è passato e non è scaduto il tempo massimo passa al mantenimento (fase 1)
      fase = 1;
    }
    if (t_trascorso >= t_max) {
      fase = 3;
    }
  } else
    fase = 4;

  delay(1000);

  sensors.requestTemperatures();                // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
  temperatura = sensors.getTempCByIndex(0);     // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire

/*
    Serial.print(t_trascorso / 60);
    Serial.print(" minuti su ");
    Serial.println(t_max / 60);


  Serial.print("Temperatura: ");
  Serial.print(temperatura);
  Serial.println("°C");
*/
  switch (fase)
  {
    case 0:
      analogWrite(fanPin, MAX);                   // acensione iniziale: avvio per il tempo di warmup
      analogWrite(led_verde, 50);

      if (t_trascorso - t_stato_prec >= warmup) {
        t_stato_prec = t_trascorso;
        fase = 1;
      } else {
        fase = 0;
      }
      break;

    case 1:
      analogWrite(fanPin, MIN);                   // mantenimento, spegne ventola per il tempo della pausa
      analogWrite(led_verde, 2);
      if (t_trascorso - t_stato_prec >= pausa) {  //senza usare delay() aspetto che trascorra il tempo della pausa
        t_stato_prec = t_trascorso;               //quando è trascorso resetto t_trascorso
        fase = 2;                                 //e passo alla fase successiva
      } else {
        fase = 1;                                 //altrimenti continuo ad aspettare
      }
      break;

    case 2:
      analogWrite(fanPin, MAX);                   // mantenimento, accende ventola per il tempo di funzion (ravviva leggermente la fiamma)
      analogWrite(led_verde, 50);
      if (t_trascorso - t_stato_prec >= funzion) {
        t_stato_prec = t_trascorso;
        fase = 1;
      } else {
        fase = 2;
      }
      break;

    case 3:
      analogWrite(fanPin, MIN);         // programma concluso, spegne definitivamente ventola
      analogWrite(led_rosso, 50);
      analogWrite(led_verde, 0);
      break;

    case 4:
      analogWrite(fanPin, MIN);         // spegne ventola per raffreddare
      analogWrite(led_rosso, 50);
      analogWrite(led_verde, 50);
      delay(150);                       //fa lampeggiare entrambi i led per segnalare temperatura troppo alta
      analogWrite(led_rosso, 0);
      analogWrite(led_verde, 0);
      fase = 1;                         // resetta la fase per non rimanere bloccato in caso la temperatura torni a valori normali
      break;
  }

}

Qui lo schema:

Ventola_v2.2.ino (4.55 KB)