Codice per attivazione/spegnimento elettrovalvola

Salve a tutti e buona domenica lavoratori,operai ,mastri ed imprenditori.
Ultimamente dato che ho più tempo libero mia mamma mi ha proposto se riesco a creargli un semplice sistema di irrigazione per le piante che abbiamo nel terrazzo, allora ho pensato subito ad Arduino che collegato ad un'elettrovalvola collegata al tubo del rubinetto faccia partire tramite un tubo l'acqua per X secondi, X per ora è ipotetico ma con diverse prove empiriche dovrei riuscire a trovare il valore ideale per soddisfare il fabbisogno di acqua delle piante. Ora io ho scritto questo codice, cosa ne pensate ?

long attivita = 10000; //tempo attività di flusso dell'acqua (10secondi per esempio )
int t = 0;

void setup() {
  pinMode(2, INPUT); // pulsante
  pinMode(3, OUTPUT); // elettrovalvola
  
}

void loop() {
  
  if ((millis() - t) > attivita){  //acqua scorre fino a che il tempo indicato nella variabile indicato in attivita non viene superato
    digitalWrite(3, LOW);
  }else{ digitalWrite(3, HIGH);
  }
  
  if (digitalRead(2) == HIGH){ //nel caso in cui l'acqua inizialmente data non fosse bastata basta tenere premuto il pulsante per continuare ad attivare la elettrovalvola
    digitalWrite(3, HIGH);
  }
}

Praticamente il codice appena acceso Arduino porta l'elettrovalvola in HIGH (dunque accesa?) per X secondi modificabili tramite la variabile attività passato questo tempo l'elettrovalvola si spegne e viene riattivata solo se si tiene premuto il pulsante e rimane attiva per i secondi in cui il pulsante è premuto per poi spegnersi di nuovo.
La struttura del codice implica che ogni volta che si è finito di dare da bere alle piante si spenga Arduino togliendoli la corrente questo non dovrebbe essere un problema ne per Arduino ne per l'elettrovalvola giusto?

PS: il codice l'ho provato su Thinkercad simulando l'elettrovalvola con un led che si comporta come pensavo, il dubbio è se il codice è adatto per essere affiancato ad un elettrovalvola, guardando un pò in giro in questo forum varie discussioni a riguardo ho visto che le elettrovalvole sono forte oggetto di discussione e scontri tra idee, ad esempio quello che ho capito io è che per essere attivata un'elettrovalvola abbia bisogno di un breve spunto e lo stesso per essere spenta dunque il codice da me scritto in questo caso è sbagliato poichè durante il tempo di attività io la tengo sempre HIGH quindi accesa questo và bene o dà problemi allo strumento?

Rankstrait:
appena acceso Arduino porta l'elettrovalvola in HIGH (dunque accesa?)

HIGH porta sicuramente il pin di uscita a +5V (o +3,3V sulle board alimentate a 3,3V), se questo vuol dire accesa o spenta dipende da cosa c'è dopo. Nelle comuni schedine relé tipo queste i relé si attivano con un LOW sugli ingressi, quindi un'uscita Arduino HIGH significa relé spento.

Per questo motivo è importantissimo specificare nei commenti iniziali i livelli di attivazione e quelli letti, e magari impostare subito i livelli delle uscite che si vogliono avere all'accensione:

void setup() {
  pinMode(2, INPUT);  // pulsante, quando premuto si legge ....
  pinMode(3, OUTPUT); // elettrovalvola, si accende con ....
  digitalWrite(3, ...livello iniziale spento o acceso a seconda di cosa si vuole...);
}

per X secondi modificabili tramite la variabile attività

Le variabili temporali da usare nei confronti con millis devono essere di tipo senza segno, quindi unsigned long (o abbreviato uint32_t). In questo caso comunque non ci sono problemi perché il valore contenuto è basso. La variabile 't0' che hai scritto nel codice, di fatto non è usata per alcuna operazione

La struttura del codice implica che ogni volta che si è finito di dare da bere alle piante si spenga Arduino togliendoli la corrente questo non dovrebbe essere un problema ne per Arduino ne per l'elettrovalvola giusto?

Non ci sono problemi a spegnere ogni volta. Anzi, è anche indispensabile perché il controllo sul tempo realizzato così andrebbe in errore dopo circa 1190 ore (2 alla 32esima millisecondi) riaccendendo la valvola.

un'elettrovalvola abbia bisogno di un breve spunto e lo stesso per essere spenta

Dipende dalla valvola, se è ad azionamento continuo allora basta un'uscita da mandare alta o bassa (più un adeguato driver esterno come può essere una scheda relé o un mosfet di potenza), se è una bistabile richiede due impulsi (e due driver) da uscite differenti.

Claudio_FF:
HIGH porta sicuramente il pin di uscita a +5V (o +3,3V sulle board alimentate a 3,3V), se questo vuol dire accesa o spenta dipende da cosa c'è dopo. Nelle comuni schedine relé tipo queste i relé si attivano con un LOW sugli ingressi, quindi un'uscita Arduino HIGH significa relé spento.

Quindi se volessi far funzionare il mio sketch usando un relè come da quello da te linkato basta che inverta il codice dunque nelle parti in cui è HIGH mettere LOW e viceversa?
Ma tutti i relè hanno questo apparente comportamento anomalo ossia vanno HIGH quando impostati LOW e viceversa?

Non è un comportamento anomalo ma una scelta progettuale. Non c'è una legge che dica che HIGH debba singificare acceso. Nel circuito seguente con HIGH è acceso il LED in basso, con LOW quello in alto:

biled.png

Lo stadio di ingresso di quelle schede relé è progettato come il LED in alto, ma per altre vale il contrario.

Per cui nel programma invece di scrivere HIGH/LOW dappertutto, che poi è facile confondersi e non ricordare più cosa vuole dire, preferisco crearmi una costante all'inizio del tipo:

const byte ACCESO = LOW;

oppure una definizione:

#define  ACCESO  LOW

e poi nel codice scrivere ad esempio:

digitalWrite(LUCE1, ACCESO);

così non c'è dubbio su cosa sto comandando di fare, e se poi voglio spegnere:

digitalWrite(LUCE1, !ACCESO);

biled.png

Ti ringrazio delle delucidazioni, allora modificando il codice di @Rankstrait (che ringrazio) secondo i tuoi consigli dovrebbe venire fuori una cosa così:

long attivita = 10000; //tempo attività di flusso dell'acqua (10secondi per esempio )
const byte ACCESO = LOW;

void setup() {
  pinMode(2, INPUT); // pulsante
  pinMode(3, OUTPUT); // elettrovalvola
 
}

void loop() {
 
  if (millis() > attivita){  //acqua scorre fino a che il tempo indicato nella variabile indicato in attivita non viene superato
    digitalWrite(3, !ACCESO);
  }else{ digitalWrite(3, ACCESO);
  }
 
  if (digitalRead(2) == HIGH){ //nel caso in cui l'acqua inizialmente data non fosse bastata basta tenere premuto il pulsante per continuare ad attivare la elettrovalvola
    digitalWrite(3, ACCESO);
  }
}

mentre per i collegamenti vorrei usare un elettrovalvola da 12v con alimentatore ovviamente tramite l'utilizzo di un relè che supporta tale tensione nello specifico pensavo a questa

mentre come rele pensavo a questo

Quì in allegato una foto in cui ho disegnato i collegamenti, quà sono molto dubbioso e avrei bisogno di una mano

foto elettrovalvola-convertito-compresso.pdf (37.6 KB)

Ma LOL non mi ero neanche accorto del cambio persona.

Nello schema ci sono un po' di cose che mancano, e non so se è perché sono solo sottointese.

  1. Il positivo dell'alimentatore della valvola deve raggiungere il comune dello scambio del relé.

  2. Lato comando, al modulo relé manca il collegamento alla GND di Arduino.

  3. Come è alimentato Arduino?
    3b) Prendere i 5V per il relé da Arduino rischia di surriscaldarne il regolatore e, forse, causare reset o malfunzionamenti. Va bene se si usa un alimentatore 5V e si porta l'alimentazione con due coppie di fili separatamente verso +5V/GND di Arduino e verso +5V/GND del modulo relé.

  4. Il programma contiene un secondo errore (oltre a quello della verifica del tempo che però si manifesterebbe solo dopo 1190 ore di funzionamento continuo). Quando l'irrigazione è finita il primo if continua a spegnere l'uscita. Ma se si preme il pulsante, il secondo if la riaccende, e quindi invece di un livello di comando stabile si genera un'onda quadra acceso/spento in continuazione. Il modo corretto è scrivere un solo if: se tempo non scaduto oppure pulsante premuto allora accendi, altrimenti spegni.

  5. La valvola motorizzata impiega dai 6 ai 15 secondi per aprirsi, e altrettanti per chiudersi, vanno calcolati bene i tempi.

Claudio_FF:
3b) Prendere i 5V per il relé da Arduino rischia di surriscaldarne il regolatore e, forse, causare reset o malfunzionamenti.

Ciao,
Quei moduli relè mi sembrano opto isolati, e anche se non lo sono hanno una R di 70 Ohm che implica una I di 71mA che il pin di 5V riesce a gestire.

Alan

Metti che alimenti a 12V, abbiamo 7V di salto che per 0,07A fanno 0,49W da dissipare, a cui si aggiungono i circa 0,1W di base. Con 0,6W quel piccolo regolatore si porta verso i 100 gradi :frowning:

Ti ringrazio per le delucidazioni sullo schema elettrico molto utili.

Claudio_FF:
3) Come è alimentato Arduino?
3b) Prendere i 5V per il relé da Arduino rischia di surriscaldarne il regolatore e, forse, causare reset o malfunzionamenti. Va bene se si usa un alimentatore 5V e si porta l'alimentazione con due coppie di fili separatamente verso +5V/GND di Arduino e verso +5V/GND del modulo relé.

Arduino sarà alimentato da un alimentatore tipo quelli usati per ricaricare i telefoni per intenderci, a questo punto seguendo il tuo consiglio pensavo di usare uno di quei caricatori a doppia uscita, una uscita con cui alimentare arduino e 1 per alimentare il relè i 2 collegati a 2 masse diverse giusto?

Claudio_FF:
4) Il programma contiene un secondo errore (oltre a quello della verifica del tempo che però si manifesterebbe solo dopo 1190 ore di funzionamento continuo). Quando l'irrigazione è finita il primo if continua a spegnere l'uscita. Ma se si preme il pulsante, il secondo if la riaccende, e quindi invece di un livello di comando stabile si genera un'onda quadra acceso/spento in continuazione. Il modo corretto è scrivere un solo if: se tempo non scaduto oppure pulsante premuto allora accendi, altrimenti spegni.

Effettivamente lo sketch risulta un poco fluido così come dici tu dovrebbe andare meglio

long attivita = 10000; //tempo attività di flusso dell'acqua (10secondi per esempio )
const byte ACCESO = LOW;

void setup() {
  pinMode(2, INPUT); // pulsante
  pinMode(3, OUTPUT); // elettrovalvola
 
}

void loop() {
 
  if (millis() < attivita or digitalRead(2) == HIGH){  //acqua scorre fino a che il tempo indicato nella variabile indicato in attivita non viene superato oppure viene premuto il pulsante 
    digitalWrite(3, ACCESO);
  }else{ digitalWrite(3, !ACCESO);
  }
}

per quanto riguarda il punto 5 effettivamente c'è da considerare anche quello, in ogni caso grazie per le dritte :wink:

Uh, non mi sono mai posto la questione delle masse in comune tra due uscite USB di un caricatore. Perché per funzionare, le masse di quel modulo relé e di Arduino devono essere collegate.

Vedo che siete già andati avanti xD riagganciandomi agli ultimi messaggi se dovessi alimentare il relè con un alimentazione dipendente dovrei acquistare un ulteriore alimentatore da 5v tipo questo, ok allora dovrei esserci seguendo lo schema e il codice implementati dovrebbe funzionare come desidero! Grazie :)!!

Ok allora qui in allegato c'è il collegamento definitivo con un alimentatore da 5v che alimenta sia Arduino che il rele (in caso si possono alimentare il relè e arduino con 2 diversi alimentatori se mi dite) poi al posto di un alimentatore da 12 v ho messo un trasformatore della corrente 220v a 12v come questo 12W dovrebbero bastare e avanzare per una piccola elettrovalvola anche se non è specificato il consumo, i collegamenti a terra saranno tutti verso il cavo di terra del cavo della 220v della casa (quello collegato al trasformatore per intederci). Spero di essere stato abbastanza chiaro, se mi date conferma provo a creare uno schema fatto al pc magari fatto un pò meglio per le future persone che avranno una necessità simile alla mia e guardando sul forum ho visto diversa gente che doveva risolvere un problema più o meno simile al mio.