Précision du DHT22

Suite à des problèmes avec ma chaudière, j’ai voulu vérifier la température dans la pièce où se trouve le thermostat. La chaudière est réglée pour maintenir une certaine température dans cette pièce (salle de bain) mais un thermomètre digital montre des variations parfois assez fortes.

J’ai donc voulu vérifier et faire un “datalogger” pour voir les variations de température sur plusieurs jours.

Matos :

  • ESP32 TTGo T-Display
  • DHT22
  • un chargeur 2.5A

J’ai écrit un sketch qui fait une mesure toutes les 3 secondes (car le DHT 22 ne peut pas faire plus d’une mesure toutes les 2 secondes) et stocke les valeurs horodatées (via NTP) dans un fichier dans le SPIFFS (toutes les minutes).
L’écran affiche la température courante, les températures min et max relevées depuis que le fichier est créé, et l’humidité.

Problème : les valeurs affichées de température sont en net désaccord avec celles de l’autre thermomètre, ainsi que celles du thermostat. 2 contre 1 : j’ai l’impression que le DHT ne donne pas les bonnes valeurs. Elles sont systématiquement près de 2 degrés au dessus de celles des autres. Or le DHT22 est censé être précis à 0.1°C près, non ?

D’où peut venir le problème ?

Voici mon code, au cas où ça vient de lui (mais j’en doute) :

 //#include <Arduino.h>
#include <SPI.h>
#include "FS.h"
#include "SPIFFS.h"
#define FORMAT_SPIFFS_IF_FAILED true
#include <TFT_eSPI.h>

#include "DHT.h"
#define DHTPIN 21
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

#include <WiFi.h>
#include "time.h"

const char* ssid       = "Tell My Wi-Fi Love Her";
const char* password   = "****";
const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

//Display parameters
#ifndef TFT_DISPOFF
#define TFT_DISPOFF 0x28
#endif

#ifndef TFT_SLPIN
#define TFT_SLPIN   0x10
#endif

#define TFT_MOSI            19
#define TFT_SCLK            18
#define TFT_CS              5
#define TFT_DC              16
#define TFT_RST             23

#define TFT_BL              4   // Display backlight control pin
#define ADC_EN              14  // ADC_EN is the ADC detection enable port
#define ADC_PIN             34
#define BUTTON_1            35
#define BUTTON_2            0

TFT_eSPI display = TFT_eSPI(135, 240); // Invoke custom library

float Tmin = 100;
float Tmax = -100;

void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_1, INPUT_PULLUP);
  pinMode(BUTTON_2, INPUT_PULLUP);
  display.init();
  display.fillScreen(TFT_BLACK);
  display.setRotation(1);
  display.setTextColor(TFT_BLUE);
  display.setTextSize(2);

  dht.begin();

  if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    while (1);
  }

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTED");
  display.fillScreen(TFT_BLACK);
  display.drawString("WiFi", 30, 20, 4);
  display.drawString("connected", 0, 65, 4);
  delay(700);
  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  // look for min and max values in the file
  File file = SPIFFS.open("/tempdata");
  char buf[5];
  while (file.available()) {
    for (int j = 0; j < 20; j++) char c = file.read();
    for (int j = 0; j < 4; j++) buf[j] = file.read();
    for (int j = 0; j < 4; j++) char c = file.read();
    buf[4] = NULL;
    float Temp = atof(buf);
    if (Temp < Tmin) Tmin = Temp;
    if (Temp > Tmax) Tmax = Temp;
  }
  file.close();
}

#define seconds 3 // Period of measurement

void loop() {
  static unsigned long chrono = millis();
  if (!digitalRead(BUTTON_1)) { // Press button to erase file
    SPIFFS.remove("/tempdata");
    Serial.println("Fichier efface !");
    display.fillScreen(TFT_BLACK);
    display.drawString("File", 80, 20, 4);
    display.drawString("erased", 40, 65, 4);
    Tmin = 90;
    Tmax = 0;
    delay(700);
  }

  if (millis() - chrono > 1000ul * seconds) { // Wait 3 seconds between each measurement
    chrono = millis();

    struct tm timeinfo;
    getLocalTime(&timeinfo);
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");

    float Hum = dht.readHumidity();
    float Temp = dht.readTemperature();
    // Check if any reads failed and exit early (to try again).
    if (isnan(Hum) || isnan(Temp)) {
      Serial.println(F("Failed to read from DHT sensor!"));
      return;
    }

    Serial.print("Temperature = ");
    Serial.print(Temp);
    if (Temp < Tmin) Tmin = Temp;
    if (Temp > Tmax) Tmax = Temp;
    Serial.print(" *C\tHumidity = ");
    Serial.print(Hum);
    Serial.println(" %");
    Serial.println();

    display.fillScreen(TFT_BLACK);
    char buffer[10];
    sprintf (buffer, "%4.1f C", Temp);
    display.drawString(buffer, 50, 25, 4);
    sprintf (buffer, "%4.1f %%", Hum);
    display.drawString(buffer, 50, 80, 4);
    display.setTextSize(1);
    display.setTextColor(TFT_RED);
    sprintf (buffer, "Min %4.1f C", Tmin);
    display.drawString(buffer, 0, 0, 2);
    sprintf (buffer, "Max %4.1f C", Tmax);
    display.drawString(buffer, 160, 0, 2);
    display.setTextSize(2);
    display.setTextColor(TFT_BLUE);


    if (timeinfo.tm_sec < seconds) { // Save temperature each minute
      Serial.print("Ecriture fichier -> ");
      File file = SPIFFS.open("/tempdata", "a");
      char buffer[30];
      sprintf (buffer, "%02d/%02d/%04d %02d:%02d:%02d %4.1f C",
               timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900,
               timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, Temp);
      file.println (buffer);
      Serial.println(buffer);
      file.close();
    }
  }
}

Bonsoir lesept

Or le DHT22 est censé être précis à 0.1°C près, non ?

Non.
Résolution 0,1°C peut être , pas précision.
d'après cette doc la précision serait de +-0,5°C.... c'est peut être optimiste

rares sont les capteurs de températures de précision 0,1°C
il me semble que hbachetti a fait un tableau comparatif :

rayon d'1km..... je dois pouvoir te prêter en lever de doute un MCP9808 précis au quart de degré pour la plage de température qui t'intéresse

lesept:
Problème : les valeurs affichées de température sont en net désaccord avec celles de l'autre thermomètre, ainsi que celles du thermostat. 2 contre 1 : j'ai l'impression que le DHT ne donne pas les bonnes valeurs. Elles sont systématiquement près de 2 degrés au dessus de celles des autres. Or le DHT22 est censé être précis à 0.1°C près, non ?

D'où peut venir le problème ?

Bonjour le sept
Probleme dû à l'Implantation du DHT22 ? trop proche d'un compo/environnement "qui chauffe/rayonne"

J'ai eu un cas identique avec un DS18B20 lors d'une manip pendant la canicule de 2003 , j'avais des aberrations inexpliquées entre un DS18B20 et 2 autres, jusqu'à ce ce que je rende compte ce c'etait dû à une carafe d'eau glacée que je posait pourtant à plus de 80cm du capteur incriminé: le froid de la carafe refroidissait le DS18B20 par convection sur la pailasse.

Merci Artouste et Al1
Le capteur est posé sur la tablette du miroir, donc près du mur et d'une fenêtre fermée, mais pas de source de chaleur à proximité immédiate.

J'ai essayé d'alimenter le DHT depuis la pin 5V de l'ESP32, pensant que le 3.3V pouvait être trop bas, ça ne change rien.
Peut-être un capteur de mauvais qualité ? Il indique régulièrement entre 1.5 et 2°C de plus que le thermomètre à l'autre bout de la pièce (maximum 3m à vol d'oiseau).

l'autre thermomètre est il 'de confiance' ?

maximum 3m à vol d'oiseau

salle de bains ou volière ?

T"as pas un autre DHT22 sous la main ?

al1fch:
l'autre thermomètre est il 'de confiance' ?
salle de bains ou volière ?

Ah ah !
Je ne sais pas si l'autre est de confiance, mais il donne des valeurs proches de celles du thermostat.
Après, j'ai essayé un BME280 que j'avais sous la main (pas d'autre DHT22, Biggil) et lui aussi donnait des valeurs plus élevées que le couples thermomètre - thermostat.
Je ne sais plus quoi penser. Al1 : je passerai peut-être t'emprunter ton MCP9808, il est facile à implémenter avec un ESP32 ?

La valeur absolue n’est pas importante en soi.
Ce qui est important c’est :

  • la fidélité. C’est à dire que dans des conditions identiques le capteur donne toujours le même résultat
  • la sensibilité qui est le plus petit écart que le capteur peut discriminer.
  • la linéarité

La sensibilité est bonne a ce que j’ai compris.
La fidélité c’est un peu délicat à tester mais si tu donnes un léger coup de sèche cheveux sur le capteur est-ce que quelques minutes après il redonne la valeur qu’il avait avant ?

Si tout est bon il suffit de faire un étalonnage avec un thermomètre de confiance.
J’ai récemment acheté un kit thermomètre de salon avec le thermomètre central + affichage + 3 sondes mobiles.
Avec les 4 modules placés les uns à coté de autre dans une niche à l’abri des courants d’air j’ai 4 températures différentes qui tiennent dans 2°C.
Je pense que le capteur est une thermistance.

C’est aussi le cas du DHT22 (autre nom AM2302 → c’est sous ce nom que l’on trouve une datasheet)

Plus d’info :
https://sigrok.org/wiki/Protocol_decoder:Am230x

MCP9808 : je l’ai sous forme de ‘breakout’ d’Adafruit , une librairie est disponible.

Les capteurs bien qu'eloignés sont à la même "altitude" :smiley: ?
Ya de sacrés gradients dans l'air ambiant, 2 °C d'écart avec la précision de chacun c'est pas forcément déconnant..