termostato arduino problema soglie

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.

  {
    {
      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.

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

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:

 {
    {
      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(" ");
      }
    }

Anche aggiungendo una ulteriore isteresi il problema della soglia allo 0,01 non cambia

#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

@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

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

Ho solo pubblicato il codice come mi è stato chiesto non appena posso testo la soluzione di docdoc

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 :slight_smile:

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...

ikebanat:
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 ??

nid69ita:
@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

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?

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

Silente:
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.