Progetto Serra Automatica

Quelli sono i millisecondi, gli hai detto tu di stamparli con: Serial.print(millis());

Effettivamente hai ragione non ci riflettevo che potevano essere i mills()... Usando lo sketch sulla ricevente di quel sito mi sembra funzioni, ho messo le letture ad ogni ciclo del motore e mi stampa sempre la logicaMotore().. vedi tu stesso

cicciozuc_serra_trasmittente.ino (8.86 KB)

Ho un problema:

Nella logicaMotore() situazione == 5 dopo che fcS si è chiuso e il motore è fermo vorrei che gli igrometri segnalando ancora comando == 1 non attende i 10sec della pompa ma invece la pompa rimane accesa e attende 3sec ricominciando il ciclo motore situazione == 2, ho provato con la seguente modifica :

else if (s == 5  &&  fcS_Chiuso) {
    fermaMotore();
    HC12.println("Motore Fermo")
    if (comandoMotore == 1 &&  millis() - t >= 3000) {
      t = millis();
      s = 2;
    }
    else {
     comandoMotore = 0;
      s = 2;
    }
  }
}

La pompa rimane accesa ma quando il motoreIndietro() si ferma inizia subito motoreavanti() senza aspettare i 3sec... Sbaglio nel momento che inizia a contare i mills ma non riesco a correggerlo

Risolto :

  else if (s == 5  &&  fcS_Chiuso) {
    t = millis();
    fermaMotore();
    HC12.println("Motore Fermo");
    s = 6;
  }
    else if (s == 6 && millis() - t >= 3000) {
    if (lettura >= 775  &&  lettura1 >= 775){
     motoreAvanti();
      s = 3;
    }
    else {
     comandoMotore = 0; 
     s = 2;
    }
  }
}

la pompa rimane sempre accesa e il motore si avvia dopo 3sec... Se comandoMotore == 0 la pompa si spegne 3sec dopo che si è fermato il motore... Mi sta bene

@(Claudio_FF) vorrei una tua opinione dove sbaglio in queste situazioni di guasto..

Ho dichiarato una variabile errore = 0 nella logica motore() e logicaPompa() mentre se viene verificato un guasto ho dichiarato errore = 1, in teoria se errore è = 1 le logiche Motore e Pompa non dovrebbero eseguirsi...

void lettura_Guasti() {
  static unsigned long t = 0;  // tempo processo
  static byte          s = 0;

  boolean fcS_Chiuso = (digitalRead(fcS) == FC_PRESS_LEVEL);
  boolean fcD_Chiuso = (digitalRead(fcD) == FC_PRESS_LEVEL);
  boolean MotoreAvanti = (digitalRead(MotoreAV) == RELE_ON_LEVEL);
  boolean MotoreIndietro = (digitalRead(MotoreIN) == RELE_ON_LEVEL);
  boolean fcS_Aperto = (digitalRead(fcS) == FC_APERTO);
 boolean fcD_Aperto = (digitalRead(fcD) == FC_APERTO);
 
// Se comandoMotore = 1 passa a s = 1
 
if (s == 0 && comandoMotore == 1) {
t = millis();
s = 1;
}
// Se dopo comandoMotore il fcS dopo 3sec rimane ancora chiuso errore = 1
 
else if (s == 1 && fcS_Chiuso && millis() - t >= 3000) {
if (fcS_Chiuso) {
errore = 1;
HC12.print(" Guasto: "); 
HC12.println("Errore Fine Corsa Sinistro");
} else {
errore = 0;
t = millis();
s = 2;
 }
}
// Se comandoMotore è attivo e dopo "tot secondi" fcD è ancora Aperto
 
else if (s == 2 && comandoMotore == 1 && fcD_Aperto && millis() - t >= 60000){
if (fcD_Aperto) {
errore = 1;
HC12.print(" Guasto: ");
HC12.println("Errore Fine Corsa Destro");
} else {
errore = 0;
s = 3;
  }
}
 // Se fcS e fcD sono in posizione chiusa stampo il guasto errore 1
 
else if (s == 3 && fcS_Chiuso && fcD_Chiuso) {
errore = 1;
HC12.print(" Guasto: ");
HC12.println("Errore Fine Corsa");
    s = 4 ;
  }
  // Se MotoreAvanti e MotoreIndietro si accendono insieme stampo il guasto

  else if (s == 1 && MotoreAvanti && MotoreIndietro) {
  errore = 1;
HC12.print(" Guasto: ");
HC12.println("Errore Motore");
    s = 0 ;
 
  }
}

Logica Motore

void logicaMotore() {
  static unsigned long t = 0;  // tempo processo
  static byte          s = 0;  // stato processo

  boolean fcS_Chiuso = (digitalRead(fcS) == FC_PRESS_LEVEL);
  boolean fcD_Chiuso = (digitalRead(fcD) == FC_PRESS_LEVEL);

  if (s == 0) {
    fermaMotore();
    s = 1;
  }

  else if (s == 1  &&  errore == 0  &&  millis() - t >= 3000) {
    if (fcS_Chiuso)  s = 2;
    else {
      motoreIndietro();
      HC12.println("Motore Indietro Pos. Iniziale");
      s = 5;
    }
  }

  else if (s == 2  &&  comandoMotore == 1  &&  errore == 0) {
    motoreAvanti();
    HC12.println("Motore Avanti");
    s = 3;
  }

  else if (s == 3  &&  fcD_Chiuso  &&  errore == 0) {
    fermaMotore();
 HC12.println("Motore Fermo FcD");
    t = millis();
    s = 4;
  }

  else if (s == 4  &&  errore == 0  &&  millis() - t >= 3000) {
    motoreIndietro();
    HC12.println("Motore Indietro");
    s = 5;
  }

  else if (s == 5  &&  fcS_Chiuso) {
    t = millis();
    fermaMotore();
    HC12.println("Motore Fermo fcS");
    s = 6;
  }
    else if (s == 6 &&  errore == 0  && millis() - t >= 3000) {
    if (lettura >= 775  &&  lettura1 >= 775){
     motoreAvanti();
HC12.println("Motore Secondo Ciclo");
      s = 3;
    }
    else {
     comandoMotore = 0; 
     s = 2;
    }
  }
}

cicciozuc:
in teoria se errore è = 1 le logiche Motore e Pompa non dovrebbero eseguirsi...

Bloccare le logiche impedendo l'esecuzione degli stati fa si che le logiche non funzionino più e le uscite comandate rimangano bloccate.

L'operazione giusta è, nelle logiche, verificare se la variabile errore diventa 1 e transitare in un apposito stato di guasto dove si spegne tutto.

In teoria nella logica Motore all'inizio delle situazioni dovrei fare così :

if (errore == 0)  s = 0;
else {
If (errore == 1)  blocco_Guasti()  // Nuova funzione dove viene bloccato tutto
}

Si può fare in modo che ogni stato diventi sensibile alla variabile errore, ma bisogna toccare tutti gli stati, oppure appena dopo aver letto i finecorsa aggiungere:

if(errore == 1) s = 0;

In questo modo quando errore vale 1 viene eseguito sempre e solo lo stato 0. Appena errore torna a 0 la logica motore riprende come alla prima accensione.

Scusami tu intendi così giusto??

if (s == 0) {
    fermaMotore();
    s = 1;
  }

  else if (s == 1  &&  millis() - t >= 3000) {
    if (fcS_Chiuso)  s = 2;
				
    else {
      motoreIndietro();
      HC12.println("Motore Indietro Pos. Iniziale");
      s = 5;
    }
  }

  else if (s == 2  &&  comandoMotore == 1) {
    motoreAvanti();
    HC12.println("Motore Avanti");
    s = 3;
  }

  else if (s == 3  &&  fcD_Chiuso) {
if(errore == 1) s = 0;
    fermaMotore();
HC12.println("Motore Fermo FcD");
    t = millis();
    s = 4;
  }

  else if (s == 4  &&  millis() - t >= 3000) {
    motoreIndietro();
    HC12.println("Motore Indietro");
    s = 5;
  }

  else if (s == 5  &&  fcS_Chiuso) {
if(errore == 1) s = 0;
    t = millis();
    fermaMotore();
    HC12.println("Motore Fermo");
    s = 6;
  }
    else if (s == 6  &&  millis() - t >= 3000) {
    if (lettura >= 775  &&  lettura1 >= 775){
     motoreAvanti();
HC12.println("Motore Secondo Ciclo");
      s = 3;
    }
    else {
     comandoMotore = 0; 
     s = 2;
    }
  }
}

In questo modo quando motore è indietro e fcS è chiuso mi segnala " errore fcS Sinistro"

Se c'è un errore di indentazione è perché uso ArduinoDroid come IDE dal mio telefono e non c'è una formattazione automatica

cicciozuc:
Scusami tu intendi così giusto??

NO, intendevo solo qui:

boolean fcS_Chiuso = (digitalRead(fcS) == FC_PRESS_LEVEL);
boolean fcD_Chiuso = (digitalRead(fcD) == FC_PRESS_LEVEL);
if(errore == 1) s = 0;

Dove li hai messi non svolgono nessuna funzione, primo perché quelle righe vengono eseguite solo alla chiusura dei finecorsa e solo se si è in quegli stati, secondo perché impostare s=0 e poche righe dopo impostare di nuovo s=4 o s=6 vanifica la prima impostazione.

Per rendere ogni stato sensibile alla variabile errore si dovrebbero aggiungere altre righe di controllo evento, come:

else if (s == 1  &&  errore == 1) s = 0;
else if (s == 2  &&  errore == 1) s = 0;
else if (s == 3  &&  errore == 1) s = 0;
else if (s == 4  &&  errore == 1)  s = 0;
else if (s == 5  &&  errore == 1)  s = 0;
else if (s == 6  &&  errore == 1)  s = 0;

Ma quell'unica messa all'inizio svolge da sola il compito.

Grazie sempre per i consigli, ora il mio problema sta come sono impostati i guasti finecorsa perché così non vanno....
Mi metterò con calma per trovare la soluzione giusta.... :roll_eyes:

Le condizioni di base che identificano un guasto mi sembrano solo tre, ne basta una qualsiasi per segnalare guasto:

  • Due finecorsa chiusi contemporaneamente
  • Un finecorsa qualsiasi chiuso dopo tre secondi dalla partenza
  • Nessun finecorsa chiuso dopo 60 secondi dalla partenza

Poi, in base alla direzione del motore, si può perfezionare cercando di capire anche quale finecorsa da problemi.

Claudio_FF:
Le condizioni di base che identificano un guasto mi sembrano solo tre, ne basta una qualsiasi per segnalare guasto:

  • Due finecorsa chiusi contemporaneamente

Questo lo già fatto

if (s == 0 && fcS_Chiuso && fcD_Chiuso) {
    errore = 1;
HC12.print("Guasto: ");
HC12.println("Errore Fine Corsa");
    s = 1;
}
  • Un finecorsa qualsiasi chiuso dopo tre secondi dalla partenza

Questo ancora non riesco ad eseguirlo

if ( s == 1  &&  MotoreAvanti()  &&  fcS_Chiuso) {
t = millis();
s = 2;
else if (s == 2  &&  millis() - t >= 3000) {
if (fcS_Chiuso) errore = 1;  s = 3;
}
  • Nessun finecorsa chiuso dopo 60 secondi dalla partenza

Per questo dovrei calcolare quanto impiega il motore da inizio partenza e arrivo a fcD o viceversa, o forse intendevi nessun finecorsa aperto dopo 60 sec..però ipotizzo quello che hai detto e che impiega 60 sec.

if ( s == 3  &&  MotoreAvanti()  &&  fcS_Aperto) {
t = millis();
else if (millis() - t >= 60000) {
if (fcD_Chiuso) errore = 1;
s = 4;
  }
}
else if ( s == 4  &&  MotoreIndietro()  &&  fcD_Chiuso)  t = millis();
If (millis() - t >= 60000) {
If(fcS_Chiuso) errore = 1  s = 5;
}

Avevo aggiunto un'altra situazione di guasto se motore Avanti e Indietro si accendono insieme

else if (s == 5  &&  MotoreAvanti  && MotoreIndietro) {
 errore = 1;
HC12.print("Guasto: ");
HC12.println("Errore Motore");
    s = 0 ;
  }

Poi, in base alla direzione del motore, si può perfezionare cercando di capire anche quale finecorsa da problemi.

Questo forse già lo scritto qui sopra... Cmq ci saranno errori ma lo scritto qui in reply dopo che ho letto il tuo messaggio..

Niente da fare, provo e riprovo ma non riesco a leggere un finecorsa chiuso dopo 3 secondi che il motore è in funzione... Ho fatto così tante prove che già ho il cervello in stato di fusione....
L'ultima che ho scritto ma non funziona è questa :

else if ( s == 3  &&  MotoreAvanti) {
t = millis();
s = 4;
 }
else if (s == 4  &&  millis() - t >= 3000) {
 s = 5;
 }
else if (s == 5  &&  fcS_Chiuso){
HC12.println("guasto fcS");
errore = 1;
s = 0;
 }

Scusa, ma MotoreAvanti e MotoreIndietro sono funzioni, mica variabili

Detto questo dove sbaglio, devo mettere le funzioni all'interno di else if chiuse tra () ??

brunello22:
Scusa, ma MotoreAvanti e MotoreIndietro sono funzioni, mica variabili

Post #64, sono due variabili booleane ottenute dalla lettura dei pin di comando dei relé del motore.

Detto questo dove sbaglio,

Forse domani sera trovo un po' di tempo per guardare qualcosa.

@Claudio_FF un tuo aiuto per me è sempre gradito, ma a parte questo vorrei capire se qualcuno ha la gentilezza di dirmi dove e perché sbaglio, giusto per imparare e comprendere meglio cosa succede dentro un blocco if....
Ho scritto questa istruzione :

else if (s == 3  &&  MotoreAvanti){
t = millis();
s = 4;
  }
else if (s == 4  &&  millis() - t >= 3000) {
if (fcS_Aperto)  errore = 0;
 else {
 errore = 1;
HC12.println("guasto fcS");
errore = 1;
s = 0;
    }
  }
}

ho creato una variabile booleana fcS_Aperto

boolean fcS_Aperto = (digitalRead(fcS) == FC_OPEN_LEVEL);

e ho definito il finecorsa quando è aperto come HIGH

#define FC_OPEN_LEVEL   HIGH  //  livello a finecorsa aperto

Quindi quello che cerco di fare sarebbe :

  1. MotoreAvanti
  2. Comincio a contare il tempo
  3. Passati 3 secondi
  4. Se finecorsa Sinistro è aperto. errore = 0
    Altrimenti errore = 1

Considerando che quando Arduino aziona MotoreAvanti il finecorsa sinistro è chiuso...

Io penso che sbaglio nel dichiarare MotoreAvanti dentro else if perché questa è scritta come funzione "" MotoreAvanti() ""... Anche se Claudio_FF dice

Claudio_FF:
Post #64, sono due variabili booleane ottenute dalla lettura dei pin di comando dei relé del motore.

ma nel programma è scritta come

void MotoreAvanti()

C'è nessuno che può darmi una sua opinione ????

se la funzione MotoreAvanti() è una funzione void non restituisce nulla e quindi
if (s == 3 && MotoreAvanti) non vuol dire nulla

però se nel tuo programma c'è anche una variabile di tipo bool che si chiama MotoreAvanti allora la cosa ha senso....

Si c'è una variabile

boolean MotoreAvanti = (digitalRead(MotoreAV) == RELE_ON_LEVEL);

e anche una #definizione

#define RELE_ON_LEVEL   LOW   // livello che accende rele'