Input che aziona 5 relay in sequenza e si interrompe al rilascio improvviso

Ciao tutti!
Vorrei sapere come posso scrivere un funzione, che in presenza di un segnale in ingresso sul pin 12, attivi 5 relay in sequenza, con un intervallo di 1 secondo l’uno dall’altro, ma che in mancanza del segnale in ingresso, smetta di proseguire l’accensione dei relay, tornando alla situazione di partenza, cioè a relay spenti.

Ho provato con il ciclo While, ma al rilascio del pulsante (usato per simulare l’ingresso) il cilco non si ferma e continua all’infinito e non so come fare.

ci sono altri modi per farlo?

grazie! :slight_smile:

Buongiorno, essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti QUI ([u]spiegando bene quali conoscenze hai di elettronica e di programmazione[/u] ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, [u]NON[/u] necessariamente inerenti alla tua domanda: - serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections - pinout delle varie schede by xxxPighi: Pinout - link [u]generali[/u] utili: Link Utili

... dopo che avrai fatto quanto su richiesto, prova a guardare l'istruzione "break" che ... probabilmente risolve il tuo problema ;)

Guglielmo

O anche, volendo, metti un ciclo for in un ciclo if ... il for sequenzia i rele', il ritardo lo fai con un confronto millis, ed il ciclo if viene eseguito solo se il pulsante e' sempre premuto e se il for non ha gia superato il conteggio, "ELSE" spegni tutti i rele' ... ;)

EDIT: a proposito, i rele' devono fare un solo ciclo, o continuare ciclicamente finche' rimane l'ingresso ?

AlPinkish: Ho provato con il ciclo While, ma al rilascio del pulsante (usato per simulare l'ingresso) il cilco non si ferma e continua all'infinito e non so come fare.

Se non posti il TUO codice non possiamo aiutarti molto se non dandoti indicazioni generiche. E nella programmazione ogni persona potrebbe ragionare in modo diverso (ad esempio io l'implementerei come una "macchina a stati finiti", tempo fa realizzai anche una libreriola per gestirle).

Tutto ok regolamento lettoPresentazione fatta!

Ho già provato con la funzione break, ma non so come utilizzarla affinché i relè si spengano al rilascio.

Non ho postato il codice, perchè sono indeciso su quale sia la migliore soluzione, se creare una variabile che venga richiamata nella condizione es:

while (input12== HIGH && controllo == 1)

:grinning:

oppure usare, proprio come avete suggerito altri cilcli. il mio intento è fare qualcosa di stabile che non dia problemi.

comunque vi scrivo quello che ho provato:

  digitalWrite(relay1, LOW); //spengo tutti i relay prima del ciclo while
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW); 
  digitalWrite(relay4, LOW);
  digitalWrite(relay5, LOW);

while (input12== HIGH) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay1, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo
   digitalWrite(relay2, HIGH); //accendo il 2° relay
   delay(1000); // aspetto 1 secondo
   digitalWrite(relay3, HIGH); //accendo il 3° relay
   delay(1000); // aspetto 1 secondo
   digitalWrite(relay4, HIGH); //accendo il 4° relay
   delay(1000); // aspetto 1 secondo
   digitalWrite(relay5, HIGH); //accendo il 5° relay
   delay(1000); // aspetto 1 secondo
break;
 }

quello che succede quando rilascio il pulsante: la sequenza di accensione dei relay continua fino al 5°, e con break termina il ciclo.
quello che vorrei accadesse quando rilascio il pulsante: la sequanza di accensione si interrompe ed uscita dal ciclo, restando in attesa che venga ripremuto il pulsante “input12”. Per poi ripartire dal primo relay alla nuova pressione del pulsante.

EDIT: a proposito, i rele’ devono fare un solo ciclo, o continuare ciclicamente finche’ rimane l’ingresso ?

I relay, devono fare un solo ciclo, o meglio se resto con il pulsante premuto, accende tutti i relay ed una volta acceso il 5°, non deve accadere più nulla. Questo perchè nel programma definitivo aggiungerò una variabile globale di controllo da restituire ad un altro costrutto if, per fare altro.

Potreti fare una cosa simile, fuori dal loop:

byte arrRel[5] = {relay1, relay2, relay3, relay4, relay5};
void azzera()
{
  for (byte idxRelAzz = 0; idxRelAzz < 5; idxRelAzz++)
  {
    digitalWrite(arrRel[idxRelAzz], LOW);
  }
}

nel loop:

azzera();
if (input12 == HIGH)
  {
    for (byte idxRel = 0; idxRel < 5; idxRel++)
    {
      if (input12 == HIGH) {
        digitalWrite(arrRel[idxRel], HIGH);
        delay(1000);
      }
      else
      {
        azzera();
        break;
      }
    }
  }

ho tralasciato la parte di debounce perché se il segnale reale non ne può soffrire sarebbe superflua.
Ho lasciato il delay perché è più semplice da capire, ma se è imperativo che appena il segnale cessa sul pin 12 i relay debbano essere spenti allora occorre rivedere il codice.
Il codice non ho potuto provarlo

AlPinkish: Non ho postato il codice, perchè sono indeciso su quale sia la migliore soluzione

Non fa niente, metti un codice INTERO della versione che preferisci, almeno possiamo anche provare noi non ti pare?

Tra l'altro perché non usi un emulatore web nel quale potresti anche fare debug più rapidamente? Io uso Tinkercad (una volta era Autodesk 123circuits), ti registri ed hai il tuo laboratorio virtuale online per provare tante cose (non tutte ovviamente ma queste sicuramente si)!!

Mentre attendevo la vostra risposta ho fatto altri tentavivi ed ho scritto questo versione che funziona:

  digitalWrite(relay1, LOW); //spengo tutti i relay prima del ciclo while
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW); 
  digitalWrite(relay4, LOW);
  digitalWrite(relay5, LOW);



   int controllo=0; //creo una variabile di controllo


   while (input12== HIGH) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay1, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=10; //associo 10 alla variabile perchè è ancora il pulsante premuto
   break;
   }

  while (input12== HIGH && controllo == 10) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay2, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=20; //associo 20 alla variabile perchè è ancora il pulsante premuto
   break;
   }
  while (input12== HIGH && controllo == 20) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay3, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=30; //associo 30 alla variabile perchè è ancora il pulsante premuto
   break;
   }
  while (input12== HIGH && controllo == 30) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay4, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=40; //associo 40 alla variabile perchè è ancora il pulsante premuto
   break;
   }
  while (input12== HIGH && controllo == 40) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay5, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto

   break;
   }

credo che i cicli sono separati, ma propedeutici.
Cosa ne pensate? è affidabile o è troppo macchinoso?

byte arrRel[5] = {relay1, relay2, relay3, relay4, relay5};
void azzera()
{
for (byte idxRelAzz = 0; idxRelAzz < 5; idxRelAzz++)
{
digitalWrite(arrRel[idxRelAzz], LOW);
}
}

Il ciclo for con l’array di sicuro è meglio in termini di byte e lo userò per spegnerli, ma non l’ho ancora provato per lo scopo.
quali differenze ci sono tra un metodo ed un altro, in questo caso tra il for che mi hai proposto ed il while che ho postato? Potrebbero esserci problemi nel modo in cui l’ho scritto io?

Tra l’altro perché non usi un emulatore web nel quale potresti anche fare debug più rapidamente?
Io uso Tinkercad (una volta era Autodesk 123circuits), ti registri ed hai il tuo laboratorio virtuale online per provare tante cose (non tutte ovviamente ma queste sicuramente si)!!

Si lo conosco, ma avendo già tutto montato fisicamente, sto testando direttamente. Poi è più divertente sentire il ticchettio dei relay :smiley:

Scusate le troppe domande, ma piuttosto che accontentarmi di un codice funzionante, preferisco capire bene anche il “come” delle possibili alternative.

AlPinkish: Si lo conosco, ma avendo già tutto montato fisicamente, sto testando direttamente. Poi è più divertente sentire il ticchettio dei relay :D

Si lo so, ma è che su quell'emulatore puoi fare DEBUG, mettere breakpoint, vedere il valore delle variabili... Dopo aver creato il circuito con ARduino ed i relè (per semplicità anche simulati con LED) ci copiaincolli il tuo sketch e te lo debugghi (!!) lì.

Per tornare al tuo codice:

   while (input12== HIGH) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay1, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=10; //associo 10 alla variabile perchè è ancora il pulsante premuto
   break;
   }

Ma scusa, se metti un while() e dentro fa sempre break, di fatto è come un if(), a che ti serve messo così?)

Per tornare al tuo codice:

   while (input12== HIGH) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay1, HIGH); //accendo il 1° relay
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=10; //associo 10 alla variabile perchè è ancora il pulsante premuto
   break;
   }

Ma scusa, se metti un while() e dentro fa sempre break, di fatto è come un if(), a che ti serve messo così?)

in effetti ho messo il while perchè teoricamente credevo fosse corretto, proprio per il significato letterale: "mentre".

ma adesso che me lo fai notare, posso sostituire if al while ed eliminare il break a tutti, giusto?

AlPinkish: Il ciclo for con l'array di sicuro è meglio in termini di byte e lo userò per spegnerli, ma non l'ho ancora provato per lo scopo. quali differenze ci sono tra un metodo ed un altro, in questo caso tra il for che mi hai proposto ed il while che ho postato? Potrebbero esserci problemi nel modo in cui l'ho scritto io?

Ti ha già risposto docdoc un while con un break senza condizioni è innutile sono una serie di if di fatto. Se vuoi la soluzione con il while se ben codificata ti permette di gestire le attese con millis() per fare ciò cui dicevo prima ovvero stai dento al while finché il 5 relé non è stato acceso oppure se non hai perso il segnale, dentro al while con la millis() contolli il tempo trascorso e attivi il relativo relé con il vantaggio che ad ogni ciclo senza attese appena manca il segnale spegni tutti i relé ed esci

Si, se metti if() al posto di while() e togli i break funziona allo stesso modo. Ma quel codice DOVE lo hai messo, nel loop()?

E ripeto, o metti tutto il codice o è inutile andare avanti magari proponendoti soluzioni migliori o più eleganti o più efficienti.

fabpolli: stai dento al while finché il 5 relé non è stato acceso oppure se non hai perso il segnale, dentro al while con la millis() contolli il tempo trascorso e attivi il relativo relé con il vantaggio che ad ogni ciclo senza attese appena manca il segnale spegni tutti i relé ed esci

Esatto, ma se non posta tutto il SUO codice, e visto che ha appreso ora la differenza tra while() e if(), ti pare che -senza offesa- possa capire quello che gli stai suggerendo? 8) Io quando vedo il suo codice intero possiamo magari provare a fargli qualche esempio di modifica, fino a quel momento è inutile proseguire, secondo me.

fabpolli grazie per i chiarimenti.

docdoc: Si, se metti if() al posto di while() e togli i break funziona allo stesso modo. Ma quel codice DOVE lo hai messo, nel loop()?

E ripeto, o metti tutto il codice o è inutile andare avanti magari proponendoti soluzioni migliori o più eleganti o più efficienti.

hai ragione non l'ho specificato, ho messo tutto nel loop() e naturalemnte i vari settaggi dei pin nel setup(). ecco lo sketch completo:

const int relay1= 3;
const int relay2= 4;
const int relay3= 5;
const int relay4= 6;
const int relay5= 7;
int input12=12;

int controllo; //creo una variabile di controllo
int restituzione=0; // valore restituito per l'azionamento di una funzione


void setup() {

 Serial.begin(115200); //attivo comunicazione seriale

  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  pinMode(relay5, OUTPUT);
  pinMode(input12, INPUT);


}


void loop() {
  Serial.println("inizio del programma");

   int controllo=0; //azzero la variabile

  digitalWrite(relay1, LOW); //spengo tutti i relay prima del ciclo while
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW); 
  digitalWrite(relay4, LOW);
  digitalWrite(relay5, LOW);



   if(input12== HIGH) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay1, HIGH); //accendo il 1° relay
   Serial.println("1_acceso");
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=10; //associo 10 alla variabile perchè è ancora il pulsante premuto
   }


   if(input12== HIGH && controllo == 10) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay2, HIGH); //accendo il 1° relay
   Serial.println("2_acceso");
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=20; //associo 20 alla variabile perchè è ancora il pulsante premuto

   }
   if(input12== HIGH && controllo == 20) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay3, HIGH); //accendo il 1° relay
   Serial.println("3_acceso");
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=30; //associo 30 alla variabile perchè è ancora il pulsante premuto

   }
   if(input12== HIGH && controllo == 30) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay4, HIGH); //accendo il 1° relay
   Serial.println("4_acceso");
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   controllo=40; //associo 40 alla variabile perchè è ancora il pulsante premuto

   }
   if(input12== HIGH && controllo == 40) {   //mentre il pulsante è premuto eseguo:
   digitalWrite(relay5, HIGH); //accendo il 1° relay
   Serial.println("5_acceso");
   delay(1000); // aspetto 1 secondo 
   input12=digitalRead(12); //ricontrollo se il pulsante è ancora premuto
   Serial.println("restituisco 1");
   restituzione= 1;

   }

funzione_esterna();

}// fine loop


void funzione_esterna(){
if(restituzione == 1){
Serial.println(" tutti i relay sono stati accesi e la nuova funzione è stata richiamata correttamente");
//nuova funzione da preparare
}
}

ecco :D

Come posso migliorare il tutto? implementare la funzione millis è comodo per spegnere i relay immediatamente, perchè con il delay arduino resta occupato, giusto, ma come?

AlPinkish: ... quello che vorrei accadesse quando rilascio il pulsante: la sequanza di accensione si interrompe ed uscita dal ciclo, restando in attesa che venga ripremuto il pulsante "input12". Per poi ripartire dal primo relay alla nuova pressione del pulsante.

Quindi, presumo, quando il pulsante lo rilasci i rele' si devono spegnere tutti ... inoltre, da come scrivi, i rele' si devono accendere in sequenza ma rimanere accesi tutti finche' il pulsante e' premuto, non accendo 1, aspetto un secondo, spengo1 ed accendo 2, eccetera ... giusto ?

[/quote] ... una volta acceso il 5°, non deve accadere più nulla.[/quote]

Nel senso che non si devono spegnere piu neppure se poi rilasci il pulsante, o solo nel senso che c'e' una sola sequenza di accensione, pero' se il pulsante viene rilasciato tutto deve ripartire da capo ?

Il funzionamento è il seguente:

permo il pulsante, accendo relay1 per 1 secondo, (e non lo spengo), proseguendo senza mai staccare il dito dal pulsante, accendo il relay2 per 1 secondo, e cosi via fino al 5. durante il processo se il pulsante resta premuto, nessuno dei relay si deve spegnere.

Implementare la funzione millis è comodo per spegnere i relay immediatamente, perchè con il delay arduino resta occupato, invece con millis, se manca il segnale input12 i relay si spengono senza attendere il secondo intero, giusto, ma come?

AlPinkish:
Il funzionamento è il seguente:
permo il pulsante, accendo relay1 per 1 secondo, (e non lo spengo), proseguendo senza mai staccare il dito dal pulsante, accendo il relay2 per 1 secondo, e cosi via fino al 5. durante il processo se il pulsante resta premuto, nessuno dei relay si deve spegnere.

Allora, una cosa per volta. Per ora prova questo codice come te l’ho modificato “al volo” (quindi non è detto sia 100% funzionante, a dovrebbe esserlo), ma dove troverai penso/spero delle cosette interessanti come consiglio di stile di programmazione.

Una volta che questo ti funziona, puoi eventualmente pensare ad usare millis() al posto dei delay().

// numero di relè
#define NUMRELE 5
// Pin di ogni relè
int pin[5] = { 3,4,5,6,7 };
// Relè attualmente attivo (-1 indica "nessun relè")
int releON = -1; 
// Flag fine ciclo relè
bool fineCiclo = false;
// Pin del pulsante
#define PULSANTE 12

void setup() {
  Serial.begin(115200); //attivo comunicazione seriale
  // Inizializzazione pin dei relè e li spengo
  for (int i=0; i<NUMRELE; i++) {
    pinMode(pin[i], OUTPUT);
	digitalWrite(pin[i], LOW);
  }
  // Inizializzazione pin pulsante
  pinMode(PULSANTE, INPUT);

  }

void loop() {
  // Vedo se il tasto è stato premuto
  if ( digitalRead(PULSANTE) == HIGH ) {
    if ( !fineCiclo ) {
      // Passo al successivo rele?
      // (all'inizio poiché parto da -1, il primo sarà 0)
      releON++;
      if ( releON < NUMRELE ) { // Se non ho ancora finito
        digitalWrite(pin[releON], HIGH); //accendo
        Serial.print("Relè ");
        Serial.print(releON);
        Serial.println(" acceso");
        delay(1000); // aspetto 1 secondo 
      }
      else
      { // Ho finito!
        fineCiclo = true; // Segnalo che ho finito
      }
    }
  }
  else
  { // Tasto non premuto o rilasciato, resetto le variabili
    spengo();
    resetto();
  }

  funzione_esterna();

} // fine loop

void spengo() {
  for (int i=0; i<NUMRELE; i++) {
    digitalWrite(pin[i], LOW);
  }
  releON = -1;
}

void resetto() {
  fineCiclo = false;
  releON = -1;
}

void funzione_esterna(){
  if ( fineCiclo ) {
    Serial.println(" tutti i relay sono stati accesi e la nuova funzione è stata richiamata correttamente");
    //nuova funzione da preparare
  }
}

Potresti anche usare una cosa del genere, senza while e senza delay … (pseudocodice parziale da completare, perche’ se posto il programma completo, poi Guglielmo mi bacchetta :D)

definisci i pin dei rele' come 1, 2, 3, 4, 5, per comodita'
byte tempo = 0; // per sapere se il secondo e' passato
byte rele = 1; //per il ciclo for ed accendere le uscite
byte nociclo = 0; //per non ripetere inutilmente il ciclo
unsigned long prevmil = millis(); //per controllo tempo
...

setup()
...

void loop()
   {
   ...
   ... il tuo programma
   ...

   ... leggi pulsante
   if ((pulsante premuto) //se pulsante premuto controlla tempo 
   {
      if ((tempo == 1) && (rele < 5)) //se tempo = 1 e rele non tutti accesi fai ciclo for
      {
         for (rele = 1; rele = 5; rele++) //ciclo variabile rele da 1 a 5
         {
            digitalWrite(rele, HIGH); //uso il valore di rele per accendere il corrispondente pin
            tempo = 0; //azzero tempo per ricontrollare quando passato un'altro secondo
            prevmil = millis(); //e resetto prevmil per lo stesso motivo
         }
      }
   }
   else //pulsante non premuto
   {
      for (rele = 1; rele = 5; rele++) digitalWrite(rele, LOW); //spengo tutti i rele
   }
   if (prevmil - millis() >= 1000) tempo = 1; //cambia valore tempo dopo un secondo
   ...
   ... resto del programma
   ...
}

Intendiamoci, e’ buttato li al volo, non posso provarlo qui, non e’ completo e non e’ certo ottimizzato (ad esempio se il pulsante non e’ premuto il ciclo che spegne i rele’ continua a ripetersi, male non fa ma “spreca tempo”, e si puo ottimizzare anche questo), consideralo solo come l’esempio di un possibile modo per fare la sequenza che vorresti (sempre che funzioni)

docdoc:
Allora, una cosa per volta. Per ora prova questo codice come te l’ho modificato “al volo” (quindi non è detto sia 100% funzionante, a dovrebbe esserlo), ma dove troverai penso/spero delle cosette interessanti come consiglio di stile di programmazione.

Una volta che questo ti funziona, puoi eventualmente pensare ad usare millis() al posto dei delay().

// numero di relè

#define NUMRELE 5
// Pin di ogni relè
int pin[5] = { 3,4,5,6,7 };
// Relè attualmente attivo (-1 indica “nessun relè”)
int releON = -1;
// Flag fine ciclo relè
bool fineCiclo = false;
// Pin del pulsante
#define PULSANTE 12

void setup() {
  Serial.begin(115200); //attivo comunicazione seriale
  // Inizializzazione pin dei relè e li spengo
  for (int i=0; i<NUMRELE; i++) {
    pinMode(pin[i], OUTPUT);
digitalWrite(pin[i], LOW);
  }
  // Inizializzazione pin pulsante
  pinMode(PULSANTE, INPUT);

}

void loop() {
  // Vedo se il tasto è stato premuto
  if ( digitalRead(PULSANTE) == HIGH ) {
    if ( !fineCiclo ) {
      // Passo al successivo rele?
      // (all’inizio poiché parto da -1, il primo sarà 0)
      releON++;
      if ( releON < NUMRELE ) { // Se non ho ancora finito
        digitalWrite(pin[releON], HIGH); //accendo
        Serial.print(“Relè “);
        Serial.print(releON);
        Serial.println(” acceso”);
        delay(1000); // aspetto 1 secondo
      }
      else
      { // Ho finito!
        fineCiclo = true; // Segnalo che ho finito
      }
    }
  }
  else
  { // Tasto non premuto o rilasciato, resetto le variabili
    spengo();
    resetto();
  }

funzione_esterna();

} // fine loop

void spengo() {
  for (int i=0; i<NUMRELE; i++) {
    digitalWrite(pin[i], LOW);
  }
  releON = -1;
}

void resetto() {
  fineCiclo = false;
  releON = -1;
}

void funzione_esterna(){
  if ( fineCiclo ) {
    Serial.println(" tutti i relay sono stati accesi e la nuova funzione è stata richiamata correttamente");
    //nuova funzione da preparare
  }
}

Ottimo, ho capito molte migliorie, i cicli for semplificano davvero tanto.

Ho testato e funziona bene, la cosa che ho notato è che se lascio il pulsante e poi lo ripremo subito, il ciclo non si interrompe e prosegue, secondo me è proprio a causa del delay.

Ho dato un occhiata all’esempio di Etemenanki, ho capito il senso, ma per integrarlo in questo codice ho bisogno di capire bene come funziona.

una domanda mi sorge spontanea, avendo fatto tutto con il ciclo for, se in futuro volessi aggiungere un effetto accendi-spegni per 3 volte, solo al relay 4, questo ciclo for non va più bene, giusto?