Controllo apertura/chiusura cancello tramite Arduino

Buonasera a tutti ragazzi.
Dopo che la scheda di controllo del cancello si è bruciata a causa di una lumaca che ha fatto fare cortocircuito, ho pensato di sostituirla con Arduino.

Lo sketch che ho creato è il seguente:

#define comando 2 // pin comando azioni motore (con interrupt)
#define apri 4 // pin che comanda il relè 1 per l'apertura del cancello
#define chiudi 3 // pin che comanda il relè 2 per la chiusura del cancello
#define lampada 13 // pin che comanda la lampada di segnalazione

int ciclo = 0; // ciclo operazioni 
unsigned long ultimoMillis = 0; // tempo trascorso in alternativa al delay
int statoLamp  = LOW; // gestione del lampeggio della lampada nel ciclo 1
unsigned long t = 0; // soluzione per il problema del debouncing
long debounce_delay = 500; // tempo di riconoscimento della pressione del tasto
int i = 0; // conteggio secondi apertura e chiusura del cacello


void setup() {
  pinMode(comando, INPUT);
  pinMode(chiudi, OUTPUT);
  pinMode(apri, OUTPUT);
  pinMode(lampada, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(comando), azione, FALLING);
  digitalWrite(apri, HIGH); // relè 1 diseccitato
  digitalWrite(chiudi, HIGH); // relè 2 diseccitato
  delay(5000);
}


void loop() {
  
if(ciclo == 0) { // diseccita entrambi i relè e spegne la lampada
  digitalWrite(apri, HIGH);  
  digitalWrite(chiudi, HIGH);
  digitalWrite(lampada, LOW);
  statoLamp = LOW;
}
  
if(ciclo == 1) { // apertura cancello, intermittenza lampada ogni 1 sec.
  while(i < 26) { // esegue l'operazione finché "i" è minore di 26
  if(ciclo > 1) break; // se ciclo è maggiore di 1, ferma l'operazione
    if((millis() - ultimoMillis) >= 1000) { // verif. sia trascorso 1 sec. prima di proseguire
    i++; // "i" aumenta di 1
    statoLamp = !statoLamp; // statoLamp passa da LOW ad HIGH e viceversa
    digitalWrite(lampada, statoLamp); // lampada comandata da statoLamp
    digitalWrite(chiudi, HIGH); // precauzione, relè 2 chiusura diseccitato
    digitalWrite(apri, LOW); // relè 1 apertura eccitato 
    ultimoMillis = millis(); // riporta al tempo trascorso
    if(i = 25) ciclo++; // quando "i" sarà arrivato a 25, aumenta ciclo di 1
    }
  }
}
  
if(ciclo == 2) { // diseccita entrambi i relè e spegne la lampada
  digitalWrite(apri, HIGH);  
  digitalWrite(chiudi, HIGH);
  digitalWrite(lampada, LOW);
}
  
if(ciclo == 3) { // chiusura cancello, intermittenza lampada ogni 0.5 sec.
  while(i >= 0) { // esegue l'operazione finché i non diventa 0
    if(ciclo > 3) break; // se ciclo è maggiore di 3, ferma l'operazione
      if((millis() - ultimoMillis) >= 500) { // verif. sia trascorso 0.5 sec. prima di procedere
      digitalWrite(lampada, HIGH); // accende la lampada
        if((millis() - ultimoMillis) >= 1000) { // verif. sia trascorso 1 sec. prima di proseguire
        i--; // diminuisce "i" di 1
        digitalWrite(lampada, LOW); // spegne la lampada
        digitalWrite(apri, HIGH); // precauzione, relè 1 apertura diseccitato
        digitalWrite(chiudi, LOW); // relè 2 chiusura, eccitato
        ultimoMillis = millis(); // riporta al tempo trascorso
        if(i = 0) ciclo++; // quando "i" sarà 0, aumenta ciclo di 1
        }
      }
  }
}
  
if(ciclo > 3) ciclo = 0; // quando ciclo 3 aumenterà di uno, tornerà subito a ciclo 0
if(i < 0) i = 0; // precauzione, se "i" dovesse scendere sotto lo zero, allora torna a 0
if(i > 25) i = 25; // precauzione, se "i" dovesse salire sopra 25, allora torna a 25
  
}

void azione() { // operazione da svolgere quando viene mandato il comando
  if((millis() - t) > debounce_delay) { // deve trascorrere min. 0.5 sec. tra un comando e l'altro
  ultimoMillis = millis(); // reporta al tempo trascorso
  ciclo++; // aumenta il ciclo di 1
  t = millis(); // riporta al tempo trascorso
  }
}

Tutto funziona secondo i miei piani, vi illustro la sequenza di operazione.
Come si può notare dallo sketch ho creato un ciclo composto da quattro operazioni. Il ciclo 0 ferma il cancello e spegne la lampada, il ciclo 1 apre il cancello e la lampada ha un’intermittenza di 1 secondo, il ciclo 2 ferma il cancello e spegne la lampada, il ciclo 3 chiude il cancello e la lampada ha un’intermittenza di 0.5 secondi ed in fine si ritorna al ciclo 0 dove il cancello è fermo.

Il motore non ha finecorsa, quindi partiamo sempre dal presupposto che il cancello sia chiuso. Il tempo di apertura completa del cancello è di circa 23 secondi. In allegato c’è la foto del motore, si tratta di un motore oleodinamico interrato per cancelli ad ante battenti a 220V. Come si può intravedere, mi sembra di leggere che la potenza è di 157W e l’assorbimento è di 0.76A. Ho trovato la scheda tecnica che allego.

Gestisco il motore tramite un relè a 2 canali optoisolati (ved. immagine) alimentato da un alimentatore 5V esterno e non direttamente dal MCU. Piccola precisazione sul comando del relè nello sketch, questo modulo relè legge il comando HIGH per diseccitare la bobina e LOW per eccitarla.

Vi starete chiedendo, quindi se funziona tutto cosa vuoi da noi… :sweat_smile:
Il problema è che tutto funziona correttamente finché non collego il motore al relè.
Utilizzando il Serial, controllavo i cicli dello sketch che andavano per cavoli suoi, ovvero, alla pressione del tasto si passava dal ciclo 0 al ciclo 2, dal ciclo 2 al ciclo 1 e addirittura accendendo la luce del garage il cancello si è aperto da solo.

Per prima cosa vorrei chiedervi se nel mio sketch ci sono degli errori o degli accorgimenti da prendere.

Secondo se posso fare qualcosa a livello elettronico per ovviare a questi problemi.
In rete ho trovato l’utilizzo dello snubber, dell’optoisolatore per la gestione del relè e stessa cosa per quanto riguarda l’ingresso del comando, applicando dei filtri con resistori, condensatori e diodi di protezione.
Ha senso utilizzare optoisolatori se di fatto il MCU è già isolato dei relè?

In questi giorni vorrei fare alcune prove, quali, l’inserimento dello snubber al relè e per togliermi un dubbio, provare a prendere l’alimentazione 220v dal vicino per alimentare il trasformatore 5V che gestisce il relè ed alimentare il MCU dal PC con batteria. Credo che l’impianto di casa sia il problema delle interferenze.

Voi cosa mi consigliate? Avete qualche idea?
Spero di avervi dato tutti gli elementi per provare a risolvere il problema insieme, altrimenti chiedete pure.

Grazie mille.
Simone

A parte la parte a tensione di rete, che non capisco

Ma tutta la gestione delle sicurezze manca

Come si comporta l attuatore se provi a chiudere un cancella già chiuso?
O aprire uno aperto? Magari solo a metà?

Il thread è in violazione del REGOLAMENTO, punto 15 e suoi sottopunti per cui debbo chiuderlo.

Inoltre quello che stai facendo è illegale e rischi grosso ... prima leggi QUESTO post dopo leggi QUI.

Guglielmo