Sensori DHT22

Ho un arduino nano con cui comando una caldaia ed a cui sono collegati due sensori DHT22, uno sui tubi della caldaia, uno all'esterno.
Provati "in laboratorio" non ho notato grandi errori nella misurazione della temperatura (sull'umidità invece si, ma non è un parametro che m'interessa).
La stranezza che ho notato "in campo" è che sembra che ad ogni lettura i sensori memorizzino la lettura precedente e devo forzargli una seconda lettura per avere i dati reali.
Faccio un esempio:
verifica temperatura prima dell'accensione della caldaia (es. 22:00): valori 5,7° esterno, 8,2° caldaia
verifica temperatura dopo un'ora (es. 23:00): valori 5,5° esterno, 8,1° caldaia
verifica temperatura dopo un minuto (es. 23:01): valori 7° esterno, 37,1° caldaia che dovrebbero essere quelli corretti; in ogni caso non è possibile che ci siano 30° di differenza in un minuto!!!
Ho anche sostituito un sensore, ma non è cambiato niente.
I sensori li attivo ad ogni lettura (dht.begin) e poi eseguo anche un dht.read. Come leggete resetto le variabili prima di valorizzarle.

grazie

  dht1.begin();
  dht2.begin();
  delay(3000); // aspetta che i sensori siano attivi
  float TempEST = 200.00; float TempCAL = 200.00;
  float UmidEST = 0;
  char buf[7] = "";
  bool dht1OK = true;
  bool dht2OK = true;
  if (dht1.read(DHTPIN1) == 1) {
    UmidEST = dht1.readHumidity();
    TempEST = dht1.readTemperature();
    if (isnan(TempEST) || isnan(UmidEST))
    { dht1OK = false;
      Serial.println("[leggiT] Errore lettura DHT1 (Esterno)");
    }
  }
  else dht1OK = false;
  if (!dht1OK) InviaSMS ("Errore lettura DHT1 (Esterno)");

  if (dht2.read(DHTPIN2) == 1) {
    TempCAL = dht2.readTemperature();
    if (isnan(TempCAL))
    { dht2OK = false;
      Serial.println("[leggiT] Errore lettura DHT2 (Caldaia)");
    }
  }
  else dht2OK = false;
  if (!dht2OK) InviaSMS ("Errore lettura DHT2 (Caldaia)");

Ma tu quale versione di libreria DHT esattamente usi?
Hai provato già a spostare i begin() dentro al solo setup()?

la libreria è DHT.h.
Prima avevo i due begin() nel setup, ho provato a spostarli ma senza risultato.
ciao

Ma scusa, ti pare che dire solo "Uso la DHT.h" sia specificare esattamente libreria usata e versione?

Ci sono svariate librerie in giro, quella Adafruit (ed anche per questa, varie versioni, 1.3.0, 1.2.3, 1.2.2 ecc.) e la DHTLib. Ad esempio vedi QUI una lista di quelle su GitHub..

Se non sai quale possiedi, cerca nella cartella della libreria il file "library.properties", aprilo come testo, e dentro trovi tutto.

A quel punto si può iniziare a vedere se per caso usi una libreria sbagliata, o vecchia/bacata, o che richiede qualcosa che non sai.

ecco le informazioni sulla libreria utilizzata:
name=DHT sensor library
version=1.3.0
author=Adafruit

Però come ho scritto non è che non funziona, è che sembra avere un "effetto memoria" sui sensori.

Mah... Nel momento che leggo una temperatura so che è corretta. Il DHT22 non sbaglia.

Però tu mi dici che è una caldaia, quindi i trenta gradi di differenza tra spenta e accesa non li vedo una cosa strana.

Verifica DOVE hai messo i sensori ! Ti ricordo che anche un soffio di aria calda sul dht22 viene letto regolarmente, e anche bene. E anche l'umidità ti do per certo che è quasi perfetta.

Se invece vuoi delle sonde di temperatura da contatto ti consiglio di usare delle NTC che sono più lente e più stabili e vanno meglio per ciò che devi fare.

la cosa è strana perchè la caldaia era accesa da un'ora (alle 22:00), ma alle 23:00 i sensori davano la stessa temperatura di un'ora prima, mentre alle 23:01 invece hanno dato la lettura corretta di 30° in più.
Quindi la lettura delle 23 è sbagliata perchè non può essere che non scaldi niente in un'ora e 30° in un minuto.

La libreria dovrebbe essere quella "buona" ed anche ultima versione per cui ok.
Per ora a parte un "workaround" (che quando viene fatto come "pezza" chiamiamo "porkaround" :slight_smile: ) di fare una lettura fittizia 1 minuto prima dell'orario prefissato, non mi viene in mente nulla, mi spiace.

guardano il datasheet ho visto che i DHT22 hanno un ritardo di 2 secondi: può essere che avendo inserito due istruzioni (dht.read e dht.readTemperature) di seguito gli crei problemi?

  if (dht2.read(DHTPIN2) == 1) {
    TempCAL = dht2.readTemperature();
    if (isnan(TempCAL))
    { dht2OK = false;
      Serial.println("[leggiT] Errore lettura DHT2 (Caldaia)");
    }
  }

Ci sono cose che uno da per scontato.
Vedo che continuate a girare intorno alla libreria, ma una prova della dht22 è mai stata fatta?
Mi spiego, io leggo ogni due secondi e basta che tocco la sonda per vedere la temperatura e la umidità alzarsi.
Quindi questa è la prima prova.
La libreria che uso io è la DHT22.h e non ho mai avuto problemi.
Poi una cosa è farla leggere continuamente ogni due secondi, un'altra è memorizzare dei dati ogni ora...

qualcuno a provato ad usare il sensore dht22 con arduino yun?
io non riesco a mettere insieme uno sketc semplice per vedere con monitor seriale se funziona ??

Ciao, io avevo lo stesso problema con i sensori dallas ds18, praticamente mi davano sempre la temperatura della lettura precedente, poi ho scoperto l'importanza di un delay nella funzione che leggeva la temperatura, ti allego lo sketch che non ha molto a che vedere con i tuoi dht ma forse può aiutarti. In pratica (chi ne sa di più mi perdonerà per la spiegazione) il sensore ha bisogno di tempo per leggere la temperatura attuale, se non ne ha abbastanza lo farà nella lettura successiva. Per il ds18 sono 750ms, il dht22 purtroppo non l'ho mai usato.

float getTemp(){
  //returns the temperature from one DS18B20 in DEG Celsius
 
  byte data[12];
  byte addr[8];
 
  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }
 
  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }
 
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }
 
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  
  delay(850); //IMPORTANT TO READ UPDATED TEMP!!!
  
  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad
 
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
 
  ds.reset_search();
 
  byte MSB = data[1];
  byte LSB = data[0];
 
  float tempRead = ((MSB << 8) | LSB);
  float TemperatureSum = tempRead / 16;
 Serial.println(TemperatureSum);
  return TemperatureSum;
 
}

Infatti temevo una cosa del genere, aggiungerò un delay prima della lettura.
grazie!

Adafruit non vende solo, ma ha anche degli ottimi tutorial (e da anche le librerie):

Tra le caratteristiche riportate dal datasheet: No more than 0.5 Hz sampling rate (once every 2 seconds)

Inoltre tra gli Examples della libreria: DHTtester.ino
E che si legge nella loop() come prima cosa ?

void loop() {

Diciamo che il mio sketch fa altre azioni e normalmente le temperature le legge ogni giorno. In ogni caso passa almeno un minuto tra una lettura e l'altra.
La prima versione era questa: dht.begin nel setup e poi lettura della temperatura:

void setup ()
{
  Serial.begin(9600);
  Serial.println("Setup");
  dht1.begin();
  dht2.begin();
  delay(2000); // aspetta che i sensori siano attivi
}

...

void leggiT ()
  {
    Serial.println ("[leggiT]");
    float TempEST = 200.00; float TempCAL = 200.00;
    float UmidEST = 0;
    char smstext[50] = "";
    UmidEST = dht1.readHumidity();
    TempEST = dht1.readTemperature();
    TempCAL = dht2.readTemperature();
    if (isnan(TempEST) || isnan(UmidEST))
...

l'invio giornaliero però a volte tirava fuori valori senza senso.
Allora ho spostato il dht.begin nella funzione di lettura, pensando che i sensori non attivati per 24 ore si "addormentassero".

void leggiT ()
{
  dht1.begin();
  dht2.begin();
  delay(3000); // aspetta che i sensori siano attivi
  float TempEST = 200.00; float TempCAL = 200.00;
  float UmidEST = 0;
  char buf[7] = "";
  bool dht1OK = true;
  bool dht2OK = true;
  if (dht1.read(DHTPIN1) == 1) {
    UmidEST = dht1.readHumidity();
    TempEST = dht1.readTemperature();
    if (isnan(TempEST) || isnan(UmidEST))
    { dht1OK = false;
      Serial.println("[leggiT] Errore lettura DHT1 (Esterno)");
    }
  }
  else dht1OK = false;
  if (!dht1OK) InviaSMS ("Errore lettura DHT1 (Esterno)");

  if (dht2.read(DHTPIN2) == 1) {
    TempCAL = dht2.readTemperature();
    if (isnan(TempCAL))
    { dht2OK = false;
      Serial.println("[leggiT] Errore lettura DHT2 (Caldaia)");
    }
  }
  else dht2OK = false;
  if (!dht2OK) InviaSMS ("Errore lettura DHT2 (Caldaia)");

ma non va ancora: la lettura giornaliera da valori simili al giorno precedente, mentre se gliela forzo subito dopo restituisce valori di solito complemente diversi (e io penso corretti).
Il dubbio quindi è se aggiungere dei delay tra una lettura e l'altra (vedi codice sotto) e di quanti ms impostarli: i 2 secondi valgono anche per il dht.read?

if (dht1.read(DHTPIN1) == 1) {
    delay(2000);
    UmidEST = dht1.readHumidity();
    delay(2000);
    TempEST = dht1.readTemperature();

Ciao linoa, non so se hai già risolto ma ti volevo segnalare una cosa che ho scoperto leggendo il DS che mi ha fatto scervellare anche me.
Appena la CPU legge la temperatura dal DHT, quest'ultimo fa subito un'ulteriore lettura, la converte e tiene il dato pronto sul buffer poi va in standby
Nel momento che la CPU effettua un'altra lettura, viene passato il dato già nel buffer.
Quindi se tu alle 12:00 fai una lettura e poi la seconda lettura la fai alle 13:00, la temperatura letta alle 13:00 è quella delle 12:00 + 2".
Io per ovviare a ciò faccio una doppia lettura a distanza di 2" e tengo valido il secondo dato letto.