DHT11 and humidty, whats the extent of the problem?

Three DHT's all in a row, requesting the temperature, but humidity no!

As what seems to be a problem many other people have had, my R/H readings are wildly inaccurate. Temperature readings come in fine, but the humidity readings have a range of 30% between them. In hope of re-calibrating them, they are in my dehydrator at 55*C for 2hrs, after I will wrap them in damp towels and keep them at room temp for 5 hours.

In hindsight, I wasn't delaying between the temp request and humidity request, not sure if that would cause the problem though. Surely given the popularity of these sensors they can't have such significant issues!

I have read that after a few days they may just go back to giving wild readings again. Anyone else had problems?

I have had one sitting out in room air for weeks, along with a DS18B20 and while both produce temperatures that compare favorably with my expensive wireless thermostat running the heating/AC system (that is not in the same room), I have 52% RH inside on the thermostat, outside 42% (both believable) but ONLY 36% on the DHT11. There is no way the DHT11 is reading accurately.

Temps: Inside 80F and outside 75F.

I just took another one out of the plastic bag it came sealed in, and it reads 39%. I am in a room with the windows wide open to the outdoors. It should be a bit higher indoors than outdoors, I would think. Just by the way it feels it HAS to be higher than that. It’s rather muggy, to be honest.

I am running the sketch by Rob Tillaart by way of yourduino.com

/* YourDuino.com Example Software Sketch
   DHT11 Humidity and Temperature Sensor test
   Credits: Rob Tillaart
   http://arduino-direct.com/sunshop/index.php?l=product_detail&p=162
   terry@yourduino.com */
   
/*-----( Import needed libraries )-----*/
#include <dht11.h>

/*-----( Declare objects )-----*/
dht11 DHT11;

/*-----( Declare Constants, Pin Numbers )-----*/
#define DHT11PIN A3

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
}/*--(end setup )---*/

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  Serial.println("\n");

  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case 0: Serial.println("OK"); break;
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    default: Serial.println("Unknown error"); break;
  }

  Serial.print("Humidity (%): ");
  Serial.println((float)DHT11.humidity, 2);

  Serial.print("Temperature (oC): ");
  Serial.println((float)DHT11.temperature, 2);

  Serial.print("Temperature (oF): ");
  Serial.println(Fahrenheit(DHT11.temperature), 2);

  Serial.print("Temperature (K): ");
  Serial.println(Kelvin(DHT11.temperature), 2);

  Serial.print("Dew Point (oF): ");
  Serial.println(Fahrenheit(dewPoint(DHT11.temperature, DHT11.humidity)));

  Serial.print("Dew PointFast (oF): ");
  Serial.println(Fahrenheit(dewPoint Fast(DHT11.temperature, DHT11.humidity)));

  delay(5000);
}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/
//
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
        return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
        return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
        double A0= 373.15/(273.15 + celsius);
        double SUM = -7.90298 * (A0-1);
        SUM += 5.02808 * log10(A0);
        SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
        SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM-3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
        double a = 17.271;
        double b = 237.7;
        double temp = (a * celsius) / (b + celsius) + log(humidity/100);
        double Td = (b * temp) / (a - temp);
        return Td;
}

/* ( THE END ) */

As an experiment (and because we're returned to hot and humid weather) I turned the air conditioner back on. The DHT11 now reads 36% humidity. I conclude the device is worthless junk that cannot be relied upon.

I plan to get a DHT21 (AKA AMS2301) or DHT22 for around $5 and see if I get any better readings.

The DHT22 has wider sensing ranges, too: 0-100% humidity and -40 to +125 degrees C. Physically, it is maybe 20% slightly larger.

I saw you might buy the DHT21, if you do so would you please be so kind to test my DHTLib if the DHT21 implementation works as I do not have such sensor.

The library can be found at - http://playground.arduino.cc/Main/DHTLib - Code for the DHT21 based upon - http://www.electrodragon.com/w/images/6/6f/DHT21.pdf -

robtillaart: I saw you might buy the DHT21, if you do so would you please be so kind to test my DHTLib if the DHT21 implementation works as I do not have such sensor.

The library can be found at - http://playground.arduino.cc/Main/DHTLib - Code for the DHT21 based upon - http://www.electrodragon.com/w/images/6/6f/DHT21.pdf -

Will be happy to. I have both the DHT21 and DHT22 coming my way.

I have the same problem with my DHT11. The DHT22 is better, the readings are only half as wrong as the DHT11. But it is still very inaccurate. Compared to my mechanical hair-hygrometer, the DHT11 and DHT22 are ridiculous.

I bought the sensors on Ebay. I read that some chemicals (used in plastic) can greatly influence the accuracy. Or the sensors are not factory calibrated at all.

I have everything for reconditioning the sensors, but have not done that yet.

Erdin: I have the same problem with my DHT11. The DHT22 is better, the readings are only half as wrong as the DHT11. But it is still very inaccurate. Compared to my mechanical hair-hygrometer, the DHT11 and DHT22 are ridiculous.

I bought the sensors on Ebay. I read that some chemicals (used in plastic) can greatly influence the accuracy. Or the sensors are not factory calibrated at all.

I have everything for reconditioning the sensors, but have not done that yet.

Groan

I had such high hopes.

So what do we use instead?

Nothing.

The temperature with a DS18B20 is very accurate for temperature. The BMP085 is very accurate for the baromic pressure. Such an absolute accuracy does not exist for humidity. I wish there was a humidity sensor that was accurate out of the box, but there is no such thing.

There are accurate humidity sensors. Here is one. http://www.sensirion.com/en/products/humidity-temperature/humidity-sensor-sht25/ They are not cheap though, $50+.

Also the DHT11 and DHT22 are fully calibrated and very precise. Until you actually have one, and it is completely off. Now the SHT25 promises again that is fully calibrated..... I don't know. The SHT25 can get inaccurate with certain chemicals, just like the DHT11 and the DHT22.

I'm in the process of building a weather station. I just started working on this problem, and I think I've found a way to get good results with the DHT11.

I purchased a set of 4. When I started using them I observed that the RH values were wildly off. Other devices were measuring 60% or 70% RH, while all four of the DHT11s I purchased were measuring in the 40% range.

After a series of experiments, I wound up doing the following:

I connected the Vcc to a digital output pin, which I kept low. Every approximately 120s, I bring the digital output high. I delay 1s. I start the DHT library. I wait 15s for the readings to stabilize. I read the temp and humidity. I bring the digital output pin back low.

Using this process, my RH readings are in line with the readings I have from other devices. The device is inside the house, but in a room with a bunch of open windows. The temp is higher than outside so I can't compare the RH reading directly with nearby weather stations. However, I implemented a dew point calculation, and the dew point from the DHT11 is within a degree C of the dew point reported by nearby weather stations.

I'm comfortable that my error is within a 5 percentage points, rather than the 20 percentage points or more I experienced when I left the DHT11 continuously powered.

Hi Revmike,

That sounds interesting, can you share the code or better, create a demo sketch? It might be useful in combination with the - http://playground.arduino.cc/Main/DHTLib - (at least I will make a reference to your post on the playground - done)

#include <Dht11.h> //The Andy Dalton 2013-09-13 version

#define DHT11_POWER_PIN 6
#define DHT11_DATA_PIN 7

int dht11Temp = 0;
int dht11RH = 0;
char* dht11Error = "Not Ready Yet";

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  pinMode(DHT11_POWER_PIN, OUTPUT);
  digitalWrite(DHT11_POWER_PIN, LOW);
}

void loop() {
  /*
  This block of code will call the runTasks function once a second.
  If a second is missed, then the runTasks function will be notified
  of the number of missed seconds.
  
  I wanted to use a timer for this, but the timer code interfered
  with my Ethernet shield.
  */
  static unsigned long secondMark;
  unsigned long now = millis();
  if ((now - secondMark) >= 1000){
    unsigned long missed_ticks = (now - secondMark)/1000;
    secondMark = now;
    runTasks(missed_ticks);
  }
  else if (now < secondMark) {
    unsigned long missed_ticks = (now + (0xFFFFFFFF - secondMark))/1000;
    secondMark = now;
    runTasks(missed_ticks);
  }
  
  // The normal body of the loop() function would be here.
  if (dht11Error == (char*)0) {
    Serial.print("DHT11 Temp: ");
    Serial.print(dht11Temp);
    Serial.print(" deg C\n");
    Serial.print("DHT11 Humidity: ");
    Serial.print(dht11RH);
    Serial.print(" %\n");
  }
  else {
    Serial.print("DHT11 Error: ");
    Serial.print(dht11Error);
    Serial.print("\n");
  }
  delay(10000);
}

void runTasks(unsigned long missed_ticks) {
  static unsigned long ticks;
  
  boolean doHumidity = true;
  
  Serial.print("ticks: ");
  Serial.println(ticks + missed_ticks);
  
  /*
  This loop is iterated once for each tick. If the Arduino was relatively
  idle then it probably only gets run once, but if the Arduino was
  busy doing something and missed a bunch of seconds, this loop will be
  run for each second missed.
  */
  while (missed_ticks--) {
    /*
    For each task that you want to run occassionally, add an
    if statement with an expression. In this case, the readDht11()
    function will only get run once every 120 seconds.
    
    The doHumidity boolean is for an extreme case. Imagine the Arduino
    fell behind 1200 seconds. When this routine runs to catch up it would
    run readDht11() 10 times in a row. That isn't needed. The doHumidity
    boolean is set so that it only runs once when 'catching up'.
    */
    if ((ticks%120 == 0) && doHumidity) {
      doHumidity = false;
      Serial.println("120 ticks have passed (or we just started up). Try to get humidity");
      readDht11();
    }

    ticks++;
  }
  
}


void readDht11() {
  Serial.println("Power up the DHT11 and wait 1 second");
  digitalWrite(DHT11_POWER_PIN, HIGH);
  delay(1000);
  
  Serial.println("Initialize the DHT11 and wait 15 seconds");
  Dht11 humidity(DHT11_DATA_PIN);
  delay(15000);

  Serial.println("Read the DHT11");
  switch (humidity.read()) {
    case Dht11::OK:
        dht11RH = humidity.getHumidity();
        dht11Temp = humidity.getTemperature();
        dht11Error = (char*)0;
        break;

    case Dht11::ERROR_CHECKSUM:
        dht11Error = "Checksum error";
        break;

    case Dht11::ERROR_TIMEOUT:
        dht11Error = "Timeout error";
        break;

    default:
        dht11Error = "Unknown error";
        break;
  }

  Serial.println("Power down the DHT11");
  digitalWrite(DHT11_POWER_PIN, LOW);
}

thanks

Thanks revmike for your code!

I try understand your code but I found that secondMark is not initialized

I used the code as supplied in this topic and the .h file mentioned. When I try to compile I get an error:

undefined reference to `Dht11::read()'

Can you please help

Thanks

Which platform? Which version of the IDE? Which version of the library?

Better use the DHTstable lib found here - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable

Thanks for the response.

Windows 7 and an Uno IDE 1.6.7 I used the code and library exactly as detailed in post 13

Thanks