Centralina controllo Temperatura/Umidità va in blocco

Ciao a tutti, ho realizzato una centralina di controllo, solamente che dopo qualche giorno di funzionamento, va in blocco.
Non riesco proprio a capire come mai, sono alle prime armi e quindi vi chiedo se qualcuno più esperto potesse darmi un occhio al programma.

Il programma è il seguente:

#include "DHT.h"
#define DHTPIN 14 // A0 sensor DHT11 digital pin
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x3F);// 0x27 indirizzo di trasmissione LCD

//inizializza sensore Co2
#include "MQ135.h" 
MQ135 gasSensor = MQ135(A2); //pin sensore Co2
//int sensorPin = A2;

#define T0 2
#define T1 3
#define U0 4
#define U1 5
#define C0 6
#define C1 7
#define Libero1 8
#define Libero2 9
#define gn 10
#define fv 11
int gn_state = 0;//notte==0 Giorno==1
int gn_Prev_state = 5;
int fv_state = 0;//Fioritura==0 Vegetativa==1
int fv_Prev_state = 5;
int ritardo = 200;


float TEMPERATURA;
float UMIDITA;
float CO2;
float Temp;
float Um;
float co2;
float co2_print;
//Parametri vegetativa
int TGV = 24;//24
int TNV = 21;//21
int UGV = 60;//60
int UNV = 40;//40
int CGV = 1500;
int CNV = 500;//500

//parametri fioritura
int TGF = 24;
int TNF = 21;
int UGF = 55;
int UNF = 40;
int CGF = 1500;
int CNF = 500;
//scostamenti
int Tx = 2;
int Ux = 5;
int Cx = 0;

String GN;
String FV;

unsigned long Tempo_letture;
unsigned long Intervallo_Tempo_letture = 2000;
unsigned long Tempo_lcd;
unsigned long Intervallo_Tempo_lcd = 1000;

boolean RetroLuce = 0;

void setup() {
dht.begin();//sensore DHT22


Wire.begin();
 
pinMode(T0, OUTPUT);
pinMode(T1, OUTPUT);
pinMode(U0, OUTPUT);
pinMode(U1, OUTPUT);
pinMode(C0, OUTPUT);
pinMode(C1, OUTPUT);
pinMode(Libero1, OUTPUT);
pinMode(Libero2, OUTPUT);
pinMode(gn, INPUT_PULLUP);
pinMode(fv, INPUT_PULLUP);


lcd.begin(16,2);//lcd
lcd.setBacklight(255);
lcd.noBlink();
lcd.noCursor();

Serial.begin(9600);

azzeramento();

}

void loop() {

gn_state = digitalRead(gn);
fv_state = digitalRead(fv);

 if((gn_state != gn_Prev_state) || (fv_state != fv_Prev_state)) {
    parametri();   
    gn_Prev_state = gn_state;
    fv_Prev_state = fv_state;

   }
   
if ((millis() - Tempo_letture) > Intervallo_Tempo_letture){
 letture_sensori();
 gestione_uscite();
 Tempo_letture = millis();
 }

   
if ((millis() - Tempo_lcd) > Intervallo_Tempo_lcd){
 trasmissione_lcd();
 Tempo_lcd=millis();
 }



}


void parametri(){  
   if(gn_state == LOW && fv_state==LOW){
      TEMPERATURA = (float)TNV ;
      UMIDITA = (float)UNV ;
      CO2 = (float)CNV ;
      GN="NOT";
      FV="Veg";
      } 
   if(gn_state == HIGH && fv_state==LOW){
      TEMPERATURA = (float)TGV ;
      UMIDITA = (float)UGV ;
      CO2 = (float)CGV ;
      GN="GIO";
      FV="Veg";
      }
  if(gn_state == LOW && fv_state==HIGH){
      TEMPERATURA = (float)TNV ;
      UMIDITA = (float)UNF ;
      CO2 = (float)CNF ;
      GN="NOT";
      FV="Fio";
      } 
   if(gn_state == HIGH && fv_state==HIGH){
      TEMPERATURA = (float)TGV ;
      UMIDITA = (float)UGF ;
      CO2 = (float)CGF ;
      GN="GIO";
      FV="Fio";
      } 
      Serial.println(TEMPERATURA);
      Serial.println(UMIDITA);
      Serial.println(CO2);
      Serial.println(GN);
      Serial.println(FV);
     }
     

void letture_sensori(){
 Temp = dht.readTemperature();
 Um = dht.readHumidity();
 co2 = gasSensor.getCorrectedPPM( Temp, Um);
 co2_print=co2/1000;
 }


void gestione_uscite(){
 if(Temp >= TEMPERATURA+5){
  digitalWrite(T1,LOW);
   }
if(Temp <= TEMPERATURA){
  digitalWrite(T1,HIGH);
  }

if(Temp <= TEMPERATURA-Tx){
  digitalWrite(T0,LOW);
 }
if(Temp >= TEMPERATURA){
  digitalWrite(T0,HIGH);
}

/////

if(Um >= UMIDITA + 20){
  digitalWrite(U1,LOW);
 }
if(Um <= UMIDITA){
  digitalWrite(U1,HIGH);
}

if(Um <= UMIDITA-Ux){
  digitalWrite(U0,LOW);
 }
if(Um >= UMIDITA){
  digitalWrite(U0,HIGH);
}
//////////
if(co2 >= (CO2 + Cx)){
  digitalWrite(C1,LOW);
 }
if(co2 <= CO2){
  digitalWrite(C1,HIGH);
}

if(co2 <= (CO2-Cx)){
  digitalWrite(C0,LOW);
 }
if(co2 >= CO2){
  digitalWrite(C0, HIGH);
} 
}

void trasmissione_lcd(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("T:"));
  lcd.print((int)Temp);
  lcd.print(F("/"));
  lcd.print((int)TEMPERATURA);
  lcd.setCursor(8,0);
  lcd.print(GN);
  lcd.print("/");
  lcd.print(FV);
  lcd.setCursor(0,1);
  lcd.print(F("U:"));
  lcd.print((int)Um); 
   lcd.print(F("/"));
  lcd.print((int)UMIDITA);
  lcd.setCursor(9,1);
  lcd.print(F("co2:"));
  lcd.print(co2_print,1);
//  
   
}

void azzeramento(){
  digitalWrite(T0,HIGH);
  delay(ritardo);
  digitalWrite(T1,HIGH);
  delay(ritardo);
  digitalWrite(U0,HIGH);
  delay(ritardo);
  digitalWrite(U1,HIGH);
  delay(ritardo);
  digitalWrite(C0,HIGH);
  delay(ritardo);
  digitalWrite(C1,HIGH);
  delay(ritardo);
  digitalWrite(Libero1,HIGH);
  delay(ritardo);
  digitalWrite(Libero2,HIGH);
  delay(ritardo);
}

I componenti sono:
Arduino uno rev.3.
Sensore DHT 22.
Sensore MQ135.
Monitor lcd 1602 con scheda IIC.

In teoria dovrebbe controllare i parametri letti dai sensori,
confrontarli con quelli impostati, chiudere i contatti dei relativi relay e inviare i dati al monitor.

Ci sono inoltre due selettori, che discriminano i parametri da utilizzare.

La centralina utilizza un alimentazione 24v che viene ridotta a 9v con uno Step Down, dal quale prelevo l’alimentazione per arduino al pin VIN facendo lavorare il regolatore interno, e successivamente viene stabilizzata con un 7805 a 5v per alimentare le restanti utenze.

Allego lo schema dei collegamenti e le librerie che utilizzo.

In pratica il programma sembra andare, ma dopo qualche giorno di funzionamento ininterrotto, al variare delle letture dei sensori le uscite dei relay non si aggiornano.

Mi scuso per lo schema, il monitor ha la denominazione dei piedi che non è corretta.
Io utilizzo un monitor con scheda IIC, ma non sono riuscito a trovare quello corretto da scaricare, e con fritzing non sono il massimo.

Il sensore MQ135 è montato sulla sua pcb. Quello dello schema è l’unico che sono riuscito a scaricare, quindi ha i collegamenti sulla resistenza di riscaldamento e il partitore per il segnale analogico, in realtà sulla pcb ci sono anche altri componenti che ho omesso.

Vi ringrazio anticipatamente per la pazienza e per l’aiuto.

CENTRALINACONTROLLO_schem.pdf (1.47 MB)

librerie utilizzate.zip (28.8 KB)

>Mariofoll83: il codice si DEVE racchiudere tra i tag CODE e non tra i tag QUOTE che hai usato tu. Per questa volta ho corretto io, la prossima volta ti prego di prestare più attenzione. Grazie :slight_smile:

Guglielmo

Problemi già conosciuti quando si connette una scheda relé (e quindi QUALCOSA che si accende e si spegne).
Se vuoi correggere "l'errore elettromagnetico" filtra i contatti (magari facci sapere cosa accendi/spegni) mentre se vuoi sbrigartela con poco (sempre se la cosa non è importante) lavora di watch dog in modo che quando Arduino si blocca venga poi resettato automaticamente.

>Mariofoll83: il codice si DEVE racchiudere tra i tag CODE e non tra i tag QUOTE che hai usato tu.  Per questa volta ho corretto io, la prossima volta ti prego di prestare più attenzione. Grazie :)

Mi scuso, devo aver letto male il regolamento.

Inoltre non sono molto esperto nell'utilizzo dei forum :frowning: , vi ringrazio per la pazienza.

Il codice, cioè il programma, va bene con i tag CODE.

Ma per QUOTARE una discussione precedente, come hai fatto sopra, non devi usare il CODE ma, appunto, il QUOTE.
:smiley: :smiley: :smiley: :smiley:

Tranquillo, vedrai che ce la fai!

>steve-cr: Ti ringrazio per la risposta.

Cercando su internet mi ero imbattuto in alcune risposte che erano appunto di filtrare i segnali.

Ho fatto delle ricerche ma non ci ho capito molto, sono finito a leggere documenti su filtri Passa alto e Passa Basso, ma mi pare di aver capito che interessano correnti alternate.

Ho trovato filtri per le alimentazioni con delle impedenze in serie sull’alimentazione e su GND e condensatori in parallelo.

Ho visto che se si azionano carichi induttivi va posto un diodo con il catodo rivolto verso il polo positivo.

Non sono però riuscito a trovare nulla sul filtrare i segnali o l’ho trovato ma non ho capito che fosse applicabile anche ai segnali. :confused:

Attualmente utilizzo una scheda 8 relay con i pin di comando optoisolati , (essendo quelli stagnati componenti smd non saprei se è presente il diodo, dovrei controllare meglio) e gnd non in comune anche se avendo un alimentatore solo non dovrebbe cambiare nulla.

All’inizio del progetto avevo anche provato a separare le alimentazioni, dedicando due alimentatori separati per arduino e per i relay, ma non avevo comunque risolto.

Potresti darmi una dritta, un collegamento o uno schema di come posso filtrare il segnale?

Credo che mi aiuteresti a risolvere anche altre problematiche che riscontro anche su un altro mio progetto, dove piloto i relay con un 74HC595 e degli optoisolatori per azionare le bobine.

Se vuoi correggere “l’errore elettromagnetico” filtra i contatti (magari facci sapere cosa accendi/spegni)

Attualmente i relay inviano un segnale pulito 24v ad un PLC che poi si occupa di eseguire le operazioni del caso in base al segnale rilevato.

Ne abbiamo parlato molte volte …
… il collegamento corretto di quelle schede relè con Arduino, prevede DUE alimentatori totalmente separati.

Lo schema di collegamento è il seguente (© Brunello):

Attenzione, in questo modo i relè lavoreranno a “logica inversa” … pin LOW → relè eccitato, pin HIGH → relè a riposo.

Questo schema di collegamento dovrebbe già eliminarti la maggior parte dei disturbi.

Guglielmo

Il codice, cioè il programma, va bene con i tag CODE.

Ma per QUOTARE una discussione precedente, come hai fatto sopra, non devi usare il CODE ma, appunto, il QUOTE.
:smiley: :smiley: :smiley: :smiley:

Tranquillo, vedrai che ce la fai!

Grazie. :o
Sono un imbranato.

>Guglielmo: Ti ringrazio, avevo letto infatti sul forum questa cosa, e mi sono documentato sui collegamenti, trovando esattamente quello che mi hai postato.

Però ho anche trovato qualche post che diceva che se stabilizzi la tensione con diversi 7805 è come se utilizzassi alimentazioni separate.

Purtroppo non so se questa cosa sia vera.

E' buona norma togliere i problemi ALLA RADICE.
Purtroppo non sempre ci si riesce e se oggi risolvi e non ti si blocca più UNO, domani passa di li un motorino (i cinquantini sono terribili) e sei ancora al punto di partenza.

Mia abitudine è usare il watch dog. Ma non è solo la mia abitudine dato che molti PLC (io uso Mitsubishi) lo prevedono senza nemmeno una riga di programma aggiunta: c'è e basta!

Quindi, sempre pensando a ampliare le tue conoscenze senza, però, abbandonare il discorso di filtrare le tue utenze, usa questa fantastica opzione che ti toglie quasi tutti i problemi (dato che NON PUOI togliere tutti i disturbi del mondo...)

Mariofoll83:
Purtroppo non so se questa cosa sia vera.

... purtroppo no ... hai sempre il GND in comune e quindi NON separi completamente i due mondi come nel caso sopra illustrato in cui le due alimentazioni sono completamente separate e non hanno alcunché in comune.

Guglielmo

steve-cr:
Mia abitudine è usare il watch dog. Ma non è solo la mia abitudine dato che molti PLC (io uso Mitsubishi) lo prevedono senza nemmeno una riga di programma aggiunta: c'è e basta!

... ancora mischi il mondo dei PLC con quello dei microcontrollori! >:( ... sono due mondi DIVERSI con problematiche diverse.

Il watchdog è sicuramnete cosa utile, ma NON è il "detour" a tutti i problemi! PRIMA si risolvono i problemi, poi si pensa all'imprevedibile e, nel suo caso, prima si deve cercare di risolvere il problema ... poi, per casi eccezionali, il watchdog lo si può anche aggiungere.

Guglielmo

Quindi, sempre pensando a ampliare le tue conoscenze senza, però, abbandonare il discorso di filtrare le tue utenze, usa questa fantastica opzione che ti toglie quasi tutti i problemi (dato che NON PUOI togliere tutti i disturbi del mondo...)

Ti ringrazio, lo sto comunque tenendo in considerazione e alla fine mi sa che lo userò, ho avuto modo di controllare con una specie di "oscilloscopio amatoriale" lo schermo di un cavo che portava un segnale analogico e ho potuto vedere che nonostante i cavi di potenza fossero distanti alcuni metri, lo schermo prendeva l'onda 50hz e il segnale pure, nonostante la messa a terra "probabolmente da bestie" dello schermo. Immagino che i disturbi siano tantissimi nonostante le precauzioni prese.

Anche perchè il problema sembra random, e non capisco cosa altro possa essere, e persisteva anche con alimentatori separati.

Il watchdog è sicuramnete cosa utile, ma NON è il "detour" a tutti i problemi! PRIMA si risolvono i problemi, poi si pensa all'imprevedibile e, nel suo caso, prima si deve cercare di risolvere il problema ... poi, per casi eccezionali, il watchdog lo si può anche aggiungere.

E' per questo non lo avevo ancora utilizzato, proprio perchè volevo sistemare prima le varie problematiche e così facendo imparare cose nuove.

steve-cr:
E' buona norma togliere i problemi ALLA RADICE.
Purtroppo non sempre ci si riesce ....

Come vedi mi quoto da solo...

gpb01:
... ancora mischi il mondo dei PLC con quello dei microcontrollori! >:( ... sono due mondi DIVERSI con problematiche diverse.

Perfettamente d'accordo con te, due mondi diversi.

I PLC DEVONO LAVORARE e non giocare, quindi abituandosi a questa disciplina ti abitui a NON transigere su certe cose, quali, in questo caso, la sicurezza che non ti si fermi un processo, che sia su un PLC o che sia su Arduino.

L'uso automatico del watchdog sui PLC da centinaia di migliaia di euro di marche ultra blasonate conferma, se ancora ce ne fosse bisogno, che ad oggi NON ESISTE una soluzione (che non sia militare) ai disturbi elettromagnetici.
Ciò non significa che un processore è un cesso perchè si inchioda. Significa che non è immune.
Ricordo che il watchdog è implementato anche sulle centraline auto ultra-mega-schermate, ma che non sono completamente esenti da disturbi o da blocchi, sprite, microinterruzioni ecc. ecc..

Con questo modus operandi, con questa disciplina, il buon programma deve prevedere anche l'imprevedibile, anche "l'uno su un milione", le variabili e le varianti che possono accadere (magari hai un keypad da dieci tasti e un idiota li schiaccia tutti insieme giusto per vedere cosa succede...).

Prevedere l'assurdo.

Però se vogliamo una generazione di programmatori superficiali non c'è problema...

steve-cr:
Quindi, sempre pensando a ampliare le tue conoscenze senza, però, abbandonare il discorso di filtrare le tue utenze, usa questa fantastica opzione che ti toglie quasi tutti i problemi (dato che NON PUOI togliere tutti i disturbi del mondo...)

... NO, mi spiace, ma è il tuo modo di suggerire le cose che crea dei superficiali !

Il watchdog è l'ULTIMO dei suggerimenti da dare, solo dopo che si sono dati tutti gli altri atti a ridurre i problemi.

Prima si cerca di risolve TUTTO il possibile, solo DOPO ci si assicura per l'imprevedibile e NON si parte dicendo, come fai tu, "metti il watchdog e risolvi", perché così non si insegna nulla a chi è nei guai.

Guglielmo

P.S.: ... per inciso, lavoro sia nel campo militare che in quello dell'automotive con norme piuttoso stringenti e severe.

Mariofoll83:
Anche perchè il problema sembra random, e non capisco cosa altro possa essere, e persisteva anche con alimentatori separati.

Alimentatori separati e collegati ai relè con lo schema indicato da Guglielmo?
Con anche i GND separati?

Sicuro sicuro che si blocchi e non che vada in qualche stato strano per cui continua a girare ma non entra più nelle condizioni che attivano i relè?
Ci sono potenziali cicli infiniti da cui con condizioni particolari si rischia di non uscirne più? Non ho analizzato bene il codice con calma per esserne certo, anche se a prima vista mi pare di no, sorry.
Nel loop, fuori da ogni altra condizione, potresti aggiungere una funzione di blink del led interno per vedere se continua a lampeggiare o si blocca proprio, giusto per esserne sicuri che non sia un errore software che porta a condizioni non previste. O anche che si impalli qualche sensore che inizia a rilevare dati sballati.

Dico la mia anche sul watch dog:
Deve funzionare tutto senza! poi quando si è sicuri che funzioni tutto alla perfezione, nella versione finale si aggiunge per ripartire in caso di meteorite imprevisto che cade a 1m di distanza generando un impulso elettromagnetico che spegne tutto nel raggio di chilometri :wink: o del cinquantino citato da steve :smiley: che fa gli stessi danni :wink:
In questo caso va pensato tutto per non avere problemi nel caso di interruzioni "a metà ciclo" con possibili stati incoerenti e potenzialmente pericolosi. Non è che aggiungendolo di prassi si è al sicuro da casini, è una cosa da aggiungere sempre con cognizione di causa, anche se si ha attivo sempre in automatico serve la giusta consapevolezza.
Pace :wink:

maubarzi:
... In questo caso va pensato tutto per non avere problemi nel caso di interruzioni "a metà ciclo" con possibili stati incoerenti e potenzialmente pericolosi. Non è che aggiungendolo di prassi si è al sicuro da casini, è una cosa da aggiungere sempre con cognizione di causa, anche se si ha attivo sempre in automatico serve la giusta consapevolezza.

Concordo al 100% !

La cosa è spesso non cosiderata ...
... il "disturbo" che blocca il programma può avvenire nel momento più impensato e, un riavvio da parte del watchdog, va considerato in fase di start del programma (c'è difatti modo di sapere il "motivo" per cui il mio programma è ripartito) per cui, se non è un cold-start, bisogna sapere "come" resettare cicli che potrebbero essere stati interrotti a metà, pena ... fare ingenti danni a ciò che si controlla.

Guglielmo

Probabilmente mi sono spiegato male, ma ho scritto:

  • ...è buona norma togliere i problemi alla RADICE...

Poi, ancora, ho scritto:

  • ...senza abbandonare il discorso di filtrare tutte le utenze...

E ancora ho scritto:

steve-cr:
...
Se vuoi correggere "l'errore elettromagnetico" filtra i contatti (magari facci sapere cosa accendi/spegni) mentre se vuoi sbrigartela con poco (sempre se la cosa non è importante) lavora di watch dog in modo che quando Arduino si blocca venga poi resettato automaticamente.

Quindi l'ho proprio dato come ULTIMO dei suggerimenti, da fare solo dopo il resto di ciò che è già stato scritto su qualche centinaio di post relativo alle schede relè eccetera... (mentre di watchdog si parla sicuramente di meno).

gpb01:
Il watchdog è l'ULTIMO dei suggerimenti da dare, solo dopo che si sono dati tutti gli altri atti a ridurre i problemi...

Ho sicuramente spiegato male il discorso della ridondanza e cioè di un controllo aggiuntivo da mettere anche se si pensa che la "causa" non potrebbe succedere mai.

Il discorso dei programmatori superficiali, poi, esiste fintantochè lo stesso programmatore va avanti e indietro da un cliente (magari in Cina) a mettere delle "pezze" ad un programma che non ha previsto delle variabili anche "imprevedibili" ma possibili. Allora in quel caso impara a sue spese e non farà più gli stessi errori.

Quindi l' OP oggi impara che ad ogni relé va messo un filtro, ANCHE SE SEMBRA CHE NON SERVA, perché ciò che non succede oggi succederà sicuramente domani (Murpy insegna).
E quando, solo alla fine, vedrà che il suo circuito funziona alla perfezione, non deve fidarsi ed è preferibile che metta anche un watchdog proprio perché non si sa mai.

Spero di essermi spiegato meglio e comunque non ritornero sull'argomento.

steve-cr:
Spero di essermi spiegato meglio e comunque non ritornero sull'argomento.

Si, ora è più chiaro. :slight_smile:

Ribadisco, per il watchdog, quando scritto da maubarzi al post #16 (alla fine), da me ripreso nel post #17, perché, anche il watchdog, va messo con "criterio", valutandone le conseguenze. :wink:

Guglielmo