Buongiono,
premetto che è da poco che sono entrato nel mondo di arduino e sto avendo delle difficoltà che magari risultino banali alla maggior parte dei membri di questa community.
Detto questo...sto costruendo una centralina di irrigazione automatizzata.
La difficoltà che sto riscontrando è l'attivazione di tre pin(elettrovalvole) in successione.
mi spiego meglio:
facendo così ovviamente durante il ciclo di irrigazione arduino si ferma e non mi porta avanti le altre funzioni (orario, lettura umidità, ecc...ecc...).
Ho pensato di utilizzare la funzione millis() ma non riesco a impostare nulla di funzionate.
Spero di essermi spiegato e che possiate darmi delucidazioni/soluzioni.
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato.
Grazie.
... cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO della sezione Italiana del forum, (... e, per evitare future possibili discussioni/incomprensioni, prestando sempre molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazioneNELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Grazie,
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto.
P.P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...
Intanto benvenuto e dovrebbe esserti di conforto sapere che non sei il primo ne l'ultimo ad avere difficoltà con millis(). Stai usando la parola stato, quindi deduco che sei orientato verso una macchina a stati finiti (FSM). Trovandoci con l'architettura superloop abbiamo la necessità di eseguire del codice solo una volta, ad esempio la funzione annaffia() una volta eseguità non deve essere eseguita al prossimo ciclo di loop, occorre pertanto una variabile di stato su cui salvare se la funzione di annaffiare è già in esecuzione, se lo è già non la eseguo.
L'unione di millis() e la/le FSM ci permette di scrivere codice in cui il superloop gira eseguendo migliaia (o più) di cicli ogni secondo. I cicli for e while se durano 1 secondo sono considerati "bloccanti" al pari di delay(1000). In genere c'è già un loop per cui basta una variabile contatore che si incrementa ad ogni ciclo e delle if per evitare il contatore superi valori di soglia. Ok penso che possa esserti di aiuto vedere una applicazione di esempio dove c'è una FSM e l'uso di millis().
La funzione 'annaffia' va ripensata come processo da eseguire in innumerevoli passaggi:
void loop(){
if (umidita < sogliaUmidita){
statoIrrigazione = 1;
}
annaffia();
}
void annaffia(){
// se fermo e condizione di avvio
if (0 == pin && 1 == statoIrrigazione){
t = millis(); // salva tempo inizio
pin = 3; // prima uscita da attivare
digitalWrite(pin, HIGH); // ATTIVA
}
// se in funzione e timeout
if ((pin > 0) && (millis()-t >= TempoIrrigazione)){
digitalWrite(pin, LOW); // spegne uscita
pin++; // successiva uscita
if (6 == pin){ // se finite stop
pin = 0;
statoIrrigazione = 0;
}else{ // altrimenti
t = millis(); // ricarica tempo
digitalWrite(pin, HIGH); // attiva successiva
}
}
}
La funzione ha due stati (fermo e in funzione) e in ciascuno stato si controlla un evento ('statoIrrigazione' a 1 nel primo, oppure un timeout nel secondo). Quando l'evento viene rilevato si eseguono delle azioni ed eventualmente si cambia stato. In questo caso specifico e semplificato, come informazione di stato si usa il valore di 'pin': 0 quando processo fermo, e 3 4 o 5 quando in funzione.
In altri casi (o più in generale) la variabile di stato deve essere più esplicita, e anche gli stati devono essere ben distinti tra loro come codice, e allora si parla della FSM indicata da Maurotec.
Buongiorno,
in primis vorrei ringraziarvi per il tempo che mi avete dedicato.
Grazie @Maurotec, un metodo che sicuramente mi tornerà utile anche in futuro e che mi devo studiare. @Claudio_FF la tua soluzione è sicuramente quella più vicina alle mie esigenze. L'ho inserita nel mio sketch ma rimane ferma nel primo stato.
if (0 == pin && 1 == statoIrrigazione){
t = millis(); // salva tempo inizio
pin = 3; // prima uscita da attivare
digitalWrite(pin, HIGH); // ATTIVA
}
if ((pin > 0) && (millis()-t >= TempoIrrigazione)){
digitalWrite(pin, LOW); // spegne uscita
pin++; // successiva uscita
if (6 == pin){ // se finite stop
pin = 0;
statoIrrigazione = 0;
}else{ // altrimenti
t = millis(); // ricarica tempo
digitalWrite(pin, HIGH); // attiva successiva
}
}
Forse il continuo aggiornare la variabile "t" rende vano il secondo if ?
Non c'è niente da fare sul "millis()" mi si suicidano i pochi neuroni che mi sono rimasti!
Questo sopra non è codice funzionante. Il codice serve al programmatore per analizzare il funzionamento. Accanto al nome di variabile ci ho messo tra parentesi il valore. Chiaramente 0 < 50 è vero, per cui entra nella if(... e la variabile statoIrrigazione ha valore 1..
La funzione annaffia() è eseguita in loop senza condizione, cioè sempre.
Il valore di umidita deve essere aggiornato leggendo il sensore. La lettura del sensore dovrebbe avvenire ad intervallo costante per cui temporizzata con condizione basata su millis().
Nel link seguente c'è una vecchia discussione sull'irrigazione:
Non c'è nessun aggiornamento continuo. L'assegnamento avviene solo la prima volta che la condizione viene valutata vera, poi il valore di 'pin' diventa 3 (o comunque diverso da zero) e la condizione è "disabilitata" (si riabilita solo quando nel secondo if 'pin' viene rimesso a zero).
Più probabile una o più delle seguenti:
Effetti collaterali per variabili modificate in altri punti
Variabili di tipo errato
Errato uso di quella parte di codice per come è inserito nel resto
Rieccomi, oggi ho potuto verificare con calme il codice e ho trovato l'errore. @Claudio_FF avevi ragione, il problema era che la funzione innaffia veniva chiamata una sola volta per un errore di parentesi graffe . comunque funziona benissimo! Ringrazio te e tutti quelli che mi hanno dedicato parte del loro tempo.
Buon lavoro.
P.s.: se volete pubblicherò il codice quando sarà completo
Volentieri. E' sempre utile per la comunity avere esempi funzionanti di codice.
Oltre al codice è utile anche una piccola spiegazione in generale del circuito che hai fatto, quali pin usi e quali sensori/attuatori. La spiegazione nel tuo primo post è più una domanda per il problema che una spiegazione di quel che fa il tuo sistema.