Go Down

Topic: termostato arduino problema soglie (Read 427 times) previous topic - next topic

ikebanat

Jul 19, 2018, 05:00 pm Last Edit: Jul 19, 2018, 05:09 pm by ikebanat
buongiorno a tutti sto costruendo un termostato avanzato che controlla temperatura e umidità, in base al superamento delle soglie di minima attiva dei relè e fin qui ci siamo, a volte però capita una cosa sconveniente che una volta superato la soglia il relè impazzisce analizzando da seriale la sonda bme280 quando si trova fra esempio 40,99% di umidità e 41,00% con la soglia impostata a 41 ci sono quei 5 10 secondi in cui il relè impazzisce dato da fatto chè oscilla di quel 0,01 che basta a passare da 40 a 41.
Code: [Select]
  {
    {
      if ((bme.readHumidity() + setisteum) <= setpointum)
      {
      digitalWrite(A1, LOW);
      lcd.setCursor(13, 0);
      lcd.write(byte(0));
      }
      if ((bme.readHumidity() + setisteum) >= setpointum)
      {
      digitalWrite(A1, HIGH);
      lcd.setCursor(13, 0);
      lcd.print(" ");
      }
    }


ora l'idea mia era una volta superata la soglia minima o massima che sia "aspetta" 30 secondi e ricontrolla, oppure parti comunque ma prima di 30 secondi non ti fermare. ho dato una lettura al timing con mills ma la funzione deve essere attivata dopo un determinato tempo non per un determiato tempo, la funzione delay mi blocca l'esecuzione di tutte le altre funzioni. vi chiedo se voi avete qualche idea o consiglio. Avevo anche pensato di utilizzare una souzione hardware ad esempio un elletrolitico che ci metta un po' di tempo a caricarsi ma francamente non mi piace molto l'idea.

gpb01

#1
Jul 19, 2018, 05:14 pm Last Edit: Jul 19, 2018, 05:14 pm by gpb01
Devi creare un'isteresi ... esempio 1% ... se inferiore a 39.5% fa una cosa, se superiore a 40.5% fa l'altra, ma hai in mezzo un tempo di un 1% in cui non avviene nulla ...

Quindi, dato il setPoint, il primo if sarà per umidità <= (setPoint - 0.5) , mentre il secondo if sarà per umidità >= (setPoint + 0.5).

Guglielmo
Search is Your friend ... or I am Your enemy !

docdoc

#2
Jul 19, 2018, 05:17 pm Last Edit: Jul 19, 2018, 05:30 pm by docdoc
Beh intanto tu fai due if() confrontando i valori con <= e >= per cui quando è esattamente "setpointum" (ma che programmi, in latino? :D) eseguirai ENTRAMBI i codici, e non credo che sia quello che volevi.. Inoltre facendo negli if() due letture, per eventuali fluttuazioni del dato potresti avere la prima che dà 40 e l'altra 41 o viceversa, portando al "tremolio".

Secondo, nel primo if() vedo un digitalWrite a LOW  ma nell'altro non lo vedo a HIGH (magari anche qui, postare l'intero codice sarebbe stato di aiuto per capire cosa fai...). Devo supporre che digitalWrite(A1, LOW) del primo if() spenga qualcosa che deumidifica, mentre l'altro dovrebbe accenderlo se l'umidità è superiore ad un certo valore.

Per finire, tu fai una lettura ad ogni if, ma è meglio farne una e poi usare quel valore per fare confronti. Tar l'altro "setisteum" che dovrebbe fare? Se è una isteresi, come pare di capire dal nome, mi pare implementata non proprio come me la immagino, dovresti sommarla in un caso e sottrarla nell'altro, ma in ogni caso se ci mostri il resto del codice capiamo...

Quindi una cosa del genere:

Code: [Select]
{
    {
      int h = bme.readHumidity();
      if (h - setisteum < setpointum)
      {
      digitalWrite(A1, LOW);
      lcd.setCursor(13, 0);
      lcd.write(byte(0));
      }
      if (h + setisteum >= setpointum)
      {
      lcd.setCursor(13, 0);
      lcd.print(" ");
      }
    }
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

ikebanat

Anche aggiungendo una ulteriore isteresi il problema della soglia allo 0,01 non cambia
 
Code: [Select]

#include <Wire.h>
#include <BME280.h>

BME280 bme;
byte setisteum = 5;
byte setpointum = 40;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(A1, OUTPUT);    //Relay connected to A1 umidificatore
  bme.begin();

}

void loop()

{


  {
    if ((bme.readHumidity() + setisteum) <= setpointum)
    {
      digitalWrite(A1, LOW);
 
    }
    if ((bme.readHumidity() + setisteum) >= setpointum)
    {
      digitalWrite(A1, HIGH);
 
    }
  }

}



il codice nel void loop alla fine è questo niente di più niente di meno vorrei solo che una volta superata la soglia dovrebbe aspettare 30 secondi e poi continuare oppure che almeno per 30 secondi il pin A3 mantiene lo stato HIGH o LOW indipendemente dalla condizione if, in quel tempo la temperatura si assesta se è 41 si stabilizzera sui 41 se scende a 40 sarà scesa a 40 in questa maniera elimino il tremolio o almeno credo non so se rendo l'idea

nid69ita

@docdoc ti ha trovato tre errori e ti ha dato le soluzioni.
Tu posti un codice dove si sono di nuovo gli stessi 3 errori 
my name is IGOR, not AIGOR

ikebanat

@docdoc ti ha trovato tre errori e ti ha dato le soluzioni.
Tu posti un codice dove si sono di nuovo gli stessi 3 errori
Ho solo pubblicato il codice come mi è stato chiesto non appena posso testo la soluzione di docdoc

Patrick_M

il punto di scambio non deve essere lo stesso sia per l'accensione che per lo spegnimento, altrimenti appunto anche aumentando la quantità da sommare il risultato non cambia :)

se il valore centrale è 30 tu devi accendere quando superi 31 e spegnere quando va al di sotto di 29 in questo modo  una volta acceso deve scendere di 2 unità prima di potersi spegnere e viceversa...
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

nid69ita

Ho solo pubblicato il codice come mi è stato chiesto non appena posso testo la soluzione di docdoc
@docdoc ti ha chiesto di pubblicare tutto il codice.  Prima hai postato un solo pezzo con dentro anche la gestione del lcd, poi pubblichi un codice che sembra completo ma mancante della gestione lcd ??
my name is IGOR, not AIGOR

ikebanat

@docdoc ti ha chiesto di pubblicare tutto il codice.  Prima hai postato un solo pezzo con dentro anche la gestione del lcd, poi pubblichi un codice che sembra completo ma mancante della gestione lcd ??
infatti l'lcd credo che centri poco con la gestione dei pin analogici, detto ciò risolverò attraverso NE555 cosi quando lo stato è LOW faccio partire quell oche mi serve per almeno 10 secondi. Grazie comunque a tutti

acuplush

scusate se mi intrometto, ma io avevo lo stesso problema con la temperatura, ho risolto "facendo leggere" la temperatura ogni 30 secondi. tempo che non influisce nulla sul mio funzionamento e permette di distanziarsi dal limbo.
potrebbe essere una soluzione anche qui?

Silente

Perdono, ma non capisco cosa centri l'NE555. Un problema di soglie non si risolve con un componente, si risolve con una isteresi in temperature.
DUE define, una bassa e una alta
Se la temperatura é minore di bassa accende il riscaldatore
Else if la temperatura é maggiore di alta accenxe il raffreddamento
Else spegne entrambi.

Vicino alla soglia farà rogne, ma sono errori di lettura, Questi si possono risolvere con una isteresi di tempo, ma credo dell'ordine dei minuti
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pochi capiscono l'importanza di formattare, sii tra di essi

fabpolli

DUE define, una bassa e una alta
Se la temperatura é minore di bassa accende il riscaldatore
Else if la temperatura é maggiore di alta accenxe il raffreddamento
Else spegne entrambi.

Vicino alla soglia farà rogne, ma sono errori di lettura, Questi si possono risolvere con una isteresi di tempo, ma credo dell'ordine dei minuti
Quello che dici tu non è l'isteresi ma le soglie d'intervento, oltre le due define che dici tu occorre definire anche un margine (isteresi) su cui tollerare le variazioni di lettura (che non sono errori come li hai definiti tu) e non li risolvi con un "isteresi" di tempo, la soluzione (o almeno una delle molte) è quella postata da docdoc alcuni post fa.

Go Up