DHT11 and DHT22: not working

Hello everyone.

After three days trying in many ways how to use correctly the DHT11 with no luck, I open a new post. I would like help from this forum.

Tests: all the combination from the below:

I own (and I have tested all of them):

  • 3 DHT11 sensors.
  • 2 Am2302 (DHT22) sensors.
  • Multiple wires.
  • 1 breadboard (I tried with and without breadboard).
  • 2 official Arduino UNO r3 + 1 Funduino Uno.

And I have tried 6 different libraries:

  • DHT-sensor-library-1.3.0 + Adafruit_Sensor-1.0.2: by Adafruit Industries, using DHT and DHT_U.
  • arduino-DHT-master: by Mark Ruys (2013), using DHT.
  • SimpleDHT: by winlin (2016), using SimpleDHT. (DHT11 only).
  • dht11: by George Hadjikyriacou (0.4.1). (DHT11 only)
  • DHTstable: by Rob Tillaart (0.2.4)
  • DHTlib: by Rob Tillaart (0.1.28)

I am tired of trying every possible combination. It does not matter the board, the component, the model (11 or 22), the pin connected (I even tried to change the V-Data pins), changing the max timeout, the library... it always fails.

Even my "own" library as a experiment, modifying times, delays, quering methods (more polling), different advices found on the Web, reading issues in the GitHub libraries, etc. With zero results.

Of course, those devices work in the basic Blink example, can use the Serial, led+resistor in breadboard, etc. It is everything related with the DHT11 or 22.

Example of output from one of this libraries:

Max clock cycles: 16000
DHTxx Unified Sensor Example
------------------------------------
Temperature
Sensor:       DHT11
Driver Ver:   1
Unique ID:    -1
Max Value:    50.00 *C
Min Value:    0.00 *C
Resolution:   2.00 *C
------------------------------------
------------------------------------
Humidity
Sensor:       DHT11
Driver Ver:   1
Unique ID:    -1
Max Value:    80.00%
Min Value:    20.00%
Resolution:   5.00%
------------------------------------
Timeout waiting for start signal low pulse.
Error reading temperature!
Error reading humidity!
Error reading temperature!
Error reading humidity!
Timeout waiting for start signal low pulse.
...

What could be wrong?

My own test If I connect the data pin from the DHT11 with 2 wires to pin 7 and 8 of Arduino:

#include <Arduino.h>

const int DHTLIB_OK = 0;
const int DHTLIB_ERROR_CHECKSUM = -1;
const int DHTLIB_ERROR_TIMEOUT = -2;
const int DHTLIB_INVALID_VALUE = -999;

const int DHTLIB_TIMEOUT = 30000;

class dht {
public:
  int test11(uint8_t pin, uint8_t pinWr); // DHT11 & DHT12
  float humidity;
  float temperature;

  bool getDisableIRQ() { return _disableIRQ; };
  void setDisableIRQ(bool b) { _disableIRQ = b; };

private:
  uint8_t bits[5]; // buffer to receive data
  int _readSensor(uint8_t pin, uint8_t wakeupDelay);
  int _querySensor(uint8_t pin, uint8_t pinWr);
  bool _disableIRQ = false;
};

int dht::test11(uint8_t pin, uint8_t pinWr) {
  // READ VALUES
  if (_disableIRQ)
    noInterrupts();
  int rv = _querySensor(pin, pinWr);
  if (_disableIRQ)
    interrupts();
  if (rv != DHTLIB_OK) {
    humidity = DHTLIB_INVALID_VALUE;    // invalid value, or is NaN prefered?
    temperature = DHTLIB_INVALID_VALUE; // invalid value
    return rv;
  }

  // CONVERT AND STORE
  humidity = bits[0] + bits[1] * 0.1;
  temperature = (bits[2] & 0x7F) + bits[3] * 0.1;
  if (bits[2] & 0x80) // negative temperature
    {
      temperature = -temperature;
    }

  // TEST CHECKSUM
  uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
  if (bits[4] != sum) {
    return DHTLIB_ERROR_CHECKSUM;
  }
  return DHTLIB_OK;
}

int dht::_querySensor(uint8_t pin, uint8_t pinWr) {
  int ret = 0;

  // uint8_t pinWr = 8;
  // uint8_t pin = 7;
  pinWr = 8;
  pin = 7;

  // EMPTY BUFFER
  for (uint8_t i = 0; i < 5; i++)
    bits[i] = 0;

  // noInterrupts();
  delay(2000);

  pinMode(pin, INPUT);

  pinMode(pinWr, OUTPUT);
  digitalWrite(pinWr, HIGH);
  delay(1000);

  // pinMode(pin, INPUT);
  // Serial.print(digitalRead(pin));
  // delay(5);
  // Serial.print(digitalRead(pin));

  // REQUEST SAMPLE
  pinMode(pinWr, OUTPUT);
  digitalWrite(pinWr, LOW);
  delay(18);
  digitalWrite(pinWr, HIGH);
  // pinMode(pin, INPUT_PULLUP);
  // pinMode(pin, INPUT);
  // delayMicroseconds(30);

  // Serial.print(digitalRead(pin));
  // delayMicroseconds(40);
  // Serial.print(digitalRead(pin));


  uint32_t loopCnt;

  uint32_t t1, t2;

  loopCnt = DHTLIB_TIMEOUT;
  t1 = micros();
  while (digitalRead(pin) == HIGH) {
    if (--loopCnt == 0) {
      ret = DHTLIB_ERROR_TIMEOUT;
      break;
    }
  }

  t2 = micros();
  Serial.print(t2 - t1);
  Serial.print("us ");

  if (ret != 0) {
    Serial.print("Time L1 ");
    return ret;
  }

  loopCnt = DHTLIB_TIMEOUT;
  t1 = micros();
  while (digitalRead(pin) == LOW) {
    if (--loopCnt == 0) {
      ret = DHTLIB_ERROR_TIMEOUT;
      break;
    }
  }
  t2 = micros();
  Serial.print(t2 - t1);
  Serial.print("us ");
  Serial.print(DHTLIB_TIMEOUT - loopCnt);
  Serial.print(" ");
  if (ret != 0) {
    Serial.print("Time H1 ");
    return ret;
  }

  t2 = micros();

  loopCnt = DHTLIB_TIMEOUT;
  t1 = micros();
  while (digitalRead(pin) == HIGH) {
    if (--loopCnt == 0) {
      ret = DHTLIB_ERROR_TIMEOUT;
      break;
    }
    delayMicroseconds(5);
  }
  t2 = micros();
  Serial.print(t2 - t1);
  Serial.print("us ");
  Serial.print(DHTLIB_TIMEOUT - loopCnt);
  Serial.print(" ");
  if (ret != 0) {
    Serial.print("Time L2 ");
    return ret;
  }

  Serial.println();
  // READ THE OUTPUT - 40 BITS => 5 BYTES
  for (uint8_t i = 40; i != 0; i--) {

    Serial.print(i);
    Serial.print(" L ");
    loopCnt = DHTLIB_TIMEOUT;
    t1 = t2;
    while (digitalRead(pin) == LOW) {
      if (--loopCnt == 0) {
        ret = DHTLIB_ERROR_TIMEOUT;
        break;
      }
    }
    t2 = micros();
    Serial.print(t2 - t1);
    Serial.print("us ");
    Serial.print(" ");
    Serial.print(DHTLIB_TIMEOUT - loopCnt);
    Serial.print(" ");
    if (ret != 0) {
      Serial.print("Time Hx ");
      return ret;
    }

    uint8_t mask = 128;
    uint8_t idx = 0;

    uint32_t t = micros();

    Serial.print("H ");
    loopCnt = DHTLIB_TIMEOUT;
    t1 = t2;
    while (digitalRead(pin) == HIGH) {

      if (--loopCnt == 0) {
        ret = DHTLIB_ERROR_TIMEOUT;
        break;
      }
    }
    t2 = micros();
    Serial.print(t2 - t1);
    Serial.print("us ");
    Serial.print(" ");
    Serial.print(DHTLIB_TIMEOUT - loopCnt);
    Serial.print(" ");
    if (ret != 0) {
      Serial.print("Time Lx ");
      return ret;
    }

    if ((micros() - t) > 40) {
      Serial.print("|");
      bits[idx] |= mask;
    }
    mask >>= 1;
    if (mask == 0) // next byte?
    {
      mask = 128;
      idx++;
    }
    Serial.println();
  }

  return DHTLIB_OK;
}


void setup(){
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
  delay(1000);
}
void loop(){
  Serial.print("<");
  Serial.print(DHTLIB_TIMEOUT);
  Serial.print(">");
  int chk = DHT.test11(DHT11_PIN, DHT11_PINWR);
  switch (chk) {
  case DHTLIB_OK:
    Serial.print("OK,\t");
    break;
  case DHTLIB_ERROR_CHECKSUM:
    Serial.print("Checksum error,\t");
    break;
  case DHTLIB_ERROR_TIMEOUT:
    Serial.print("Time out error,\t");
    break;
  default:
    Serial.print("Unknown error,\t");
    Serial.print(chk);
    break;
  }
  // DISPLAY DATA
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t");
  Serial.println(DHT.temperature, 1);

  delay(2000);
}

Serial output:

<30000>DHT11,   8us 124524us 30000 Time H1 Time out error,  -999.0, -999.0
<30000>DHT11,   4us 124528us 30000 Time H1 Time out error,  -999.0, -999.0

8 or 4us could be sort of OK for the protocol, because the DHT11 should put it LOW in between 20-40us.

Then, it fails to put it HIGH (Time H1, reaches 124ms, 30000 loops), when it was expected to be done in 80us.

It didn't allow me to put everything in one post, so, another test:

Then, changing the beginning of the _querySensor function to this:

int dht::_querySensor(uint8_t pin, uint8_t pinWr) {
  int ret = 0;

  pinWr = 7; // <-- CHANGED
  pin = 7;

  // EMPTY BUFFER
  for (uint8_t i = 0; i < 5; i++)
    bits[i] = 0;

  // noInterrupts();
  delay(2000);

  // pinMode(pin, INPUT); // <-- CHANGED

  pinMode(pinWr, OUTPUT);
  digitalWrite(pinWr, HIGH);
  delay(1000);

  // REQUEST SAMPLE
  pinMode(pinWr, OUTPUT);
  digitalWrite(pinWr, LOW);
  delay(18);
  digitalWrite(pinWr, HIGH);

  pinMode(pin, INPUT); // <-- CHANGED

  uint32_t loopCnt;
  // ...
}

And using only one wire (from pin7 to DATA pin), the output is:

<30000>DHT11,   126396us Time L1 Time out error,    -999.0, -999.0
<30000>DHT11,   126388us Time L1 Time out error,    -999.0, -999.0

So, it does not reach even the first part. It uses 30000 loops (126ms) waiting for a LOW (Time L1).

The attached images are:

  • Circuit using 2 wires (1 read, 1 write)
  • Circuit using 1 wire (single line writes and reads, as are usually implemented every library)
  • DHT11 to see the pins info, DHT11 to see how the V is connected to N, and DHT22 version.

The DHT sensors need a pull-up resistor on the data pin, the DHT11 might have one, the DHT22 doesn't seem to include one. Use a 4.7kΩ.

Circuit using 2 wires (1 read, 1 write)

There is no distinct pin for read and write.

pylon:

  1. Sorry, I should have taken another picture of the DHT22 from the other side. It has the same type of resistor: 103, 10KΩ. So, it is also included and it wouldn't be needed, like the DHT11.

  2. Yes, there is only 1 pin for data, but with that circuit config+code I was trying another test: pin 7 (read) and pin 8 (write) from the Arduino connected to the same pin of the DHT (data). So, I mean 2 wires (2 pins) in the arduino to 1 pin in the DHT.

1. Try the following working program taken from IDE for dht11 sensor.
Vcc ----> 5V
GND ---> GND
DATA ---> DPin-4
Library : this one

#include "DHT.h"

#define DHTPIN 4     // what digital pin we're connected to
#define DHTTYPE DHT11   // DHT 11

DHT dht(DHTPIN, DHTTYPE);

void setup() 
{
  Serial.begin(9600);
  Serial.println("DHTxx test!");

  dht.begin();
}

void loop() 
{
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");
}

Try the following working program taken from the IDE for dht22 sensor.

  • ------> 5V
  • ------> GND
    Out ----> DPin-2
    Library used: this one.
#include <SimpleDHT.h>

// for DHT22,
//      VCC: 5V or 3V
//      GND: GND
//      DATA: 2
int pinDHT22 = 2;
SimpleDHT22 dht22;

void setup() {
  Serial.begin(9600);
}

void loop() 
{
  // start working...
  Serial.println("=================================");
  Serial.println("Sample DHT22 with RAW bits...");
  
  // read with raw sample data.
  // @remark We use read2 to get a float data, such as 10.1*C
  //    if user doesn't care about the accurate data, use read to get a byte data, such as 10*C.
  float temperature = 0;
  float humidity = 0;
  byte data[40] = {0};
  int err = SimpleDHTErrSuccess;
  if ((err = dht22.read2(pinDHT22, &temperature, &humidity, data)) != SimpleDHTErrSuccess) 
  {
    Serial.print("Read DHT22 failed, err="); 
    Serial.println(err);
    delay(2000);
    return;
  }
  
  Serial.print("Sample RAW Bits: ");
  for (int i = 0; i < 40; i++) 
  {
    Serial.print((int)data[i]);
    if (i > 0 && ((i + 1) % 4) == 0) 
    {
      Serial.print(' ');
    }
  }
  Serial.println("");
  
  Serial.print("Sample OK: ");
  Serial.print((float)temperature); 
  Serial.print(" *C, ");
  Serial.print((float)humidity); 
  Serial.println(" RH%");
  
  // DHT22 sampling rate is 0.5HZ.
  delay(2500);
}

GolamMostafa:
1. Try the following working program taken from IDE for dht11 sensor.
Vcc ----> 5V
....

Hi.

First, your code does not match the library. So, I used the library and adapted the code to work with the library.

#include <dht11forum.h>


dht11 DHT11;

#define DHT11PIN 4

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  delay(1000);
}

void loop()
{
  Serial.println("\n");

  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case DHTLIB_OK:
    Serial.println("OK");
    break;
    case DHTLIB_ERROR_CHECKSUM:
    Serial.println("Checksum error");
    break;
    case DHTLIB_ERROR_TIMEOUT:
    Serial.println("Time out error");
    break;
    default:
    Serial.println("Unknown error");
    break;
  }

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

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

  delay(2000);
}

Then, using the pins you said, the results are wrong. It shows constantly this:

Read sensor: Checksum error
Humidity (%): 255.00
Temperature (°C): 255.00

The other test (SimpleDHT22), using the pins you said, constantly giving:

Sample DHT22 with RAW bits...
Read DHT22 failed, err=101

I have tested the programs of Post#5 using real sensors of my stock. You have problems that could be bad sensors or bad wiring or bad jumpers. Check the continuity of the jumpers.

In this situation, you are required to have another dht11/dht22/BME280 sensor to figure out whta is wrong?

Thanks to all. Finally, after struggling... it was the wires: I got a multimeter today and I tested the wires. 2 red wires had some sort of problem and without them in the circuit everything works.