Interfacing Temperature and Humidity Sensor (DHT11) With Raspberry Pi

interfacing DHT11 with raspberry pi
DHT11 is a 4 pin sensor which can measure temperatures ranging from 0-50°C & relative humidity ranging from 20-95%.The sensor uses its own proprietary 1-wire protocol to communicate with Raspberry Pi and runs from 3.3V-5V. The timings must be precise and according to the datasheet of the sensor.

Raspberry Pi initiates the data transmission process by pulling the data bus low for about 18 ms and keeps it HIGH for about 20-40 μs before releasing it.Subsequently, the sensor responds to the Pi's data transfer request by  pulling the data bus LOW for 80 μs followed by 80 μs of HIGH.At this point Pi is ready to receive data from the sensor.Data is sent in packet of 40 bits (5 bytes) via the data line with the most significant bit at the beginning.

Data is transmitted in the following order:- Integer Part of Relative Humidity--->Decimal Part of Relative Humidity--->Integer Part of Temperature--->Decimal Part of Temperature---> Checksum. Checksum consists the last 8 bits of each part. Transmission of '0' & '1' is done by varying the width of the pulse.For transmitting '0' the data bus is held HIGH for 26-28μs, and 70μs for transmitting '1'.A delay of 50μs(LOW) is introduced before any new data bit is transmitted.After the transmission of last data-bit the data line is held LOW for 50μs and released.

DHT11 sensor timing states

Circuit:-

Holding the DHT11 towards you (the one with grid), the left pin is connected to VCC (pin 1).The data pin is next  after VCC and is connected to pin 7.Next pin is NC(no connection).Finally the last pin is connected to GND(pin 25).To prevent random data connect a 10K resistor between data and VCC pin of DHT11.

Software:-
WiringPi which uses C like Arduino language is used to read the sensor value. WiringPi is maintained under GIT for ease of change tracking.If you do not have GIT installed, then under any of the Debian releases, you can install it with-
sudo apt-get install git-core

To obtain WiringPi using GIT:
git clone git://git.drogon.net/wiringPi

If you have already used the clone operation for the first time, then

cd wiringPi
git pull origin
Will fetch an updated version then you can re-run the build script below.

To build/install there is a new simplified script:
cd wiringPi
./build

Save the below code as temp_rh_sensor.c...

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAX_TIME 85
#define DHT11PIN 7
int dht11_val[5]={0,0,0,0,0};

void dht11_read_val()
{
  uint8_t lststate=HIGH;
  uint8_t counter=0;
  uint8_t j=0,i;
  float farenheit;
  for(i=0;i<5;i++)
     dht11_val[i]=0;
  pinMode(DHT11PIN,OUTPUT);
  digitalWrite(DHT11PIN,LOW);
  delay(18);
  digitalWrite(DHT11PIN,HIGH);
  delayMicroseconds(40);
  pinMode(DHT11PIN,INPUT);
  for(i=0;i<MAX_TIME;i++)
  {
    counter=0;
    while(digitalRead(DHT11PIN)==lststate){
      counter++;
      delayMicroseconds(1);
      if(counter==255)
        break;
    }
    lststate=digitalRead(DHT11PIN);
    if(counter==255)
       break;
    // top 3 transistions are ignored
    if((i>=4)&&(i%2==0)){
      dht11_val[j/8]<<=1;
      if(counter>16)
        dht11_val[j/8]|=1;
      j++;
    }
  }
  // verify cheksum and print the verified data
  if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF)))
  {
    farenheit=dht11_val[2]*9./5.+32;
    printf("Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3],farenheit);
  }
  else
    printf("Invalid Data!!\n");
}

int main(void)
{
  printf("Interfacing Temperature and Humidity Sensor (DHT11) With Raspberry Pi\n");
  if(wiringPiSetup()==-1)
    exit(1);
  while(1)
  {
     dht11_read_val();
     delay(3000);
  }
  return 0;
}

Compile the code as...
gcc -o sensor temp_rh_sensor.c -L/usr/local/lib -lwiringPi

Now execute it...
sudo ./sensor

[ Humidity = 87.0 % Temperature = 32.2 *C (90.0 *F) ]

11 comments

  1. I dont have a "10K ohm resistor" and testing your code says invalid data, do I need to have that resistor ?

    ReplyDelete
  2. Without the 10K resistor data may get corrupted as the pin is left floating.You can try with 47K or 100K as it merely pulls the data bus to GND. You are getting invalid data because of failed check-sum verification.

    ReplyDelete
  3. Hi Rahul,

    The data is infact seems to be getting corrupted as after removing the checksum verification I am getting :

    Humidity = 0.0 % Temperature = 0.0 *C (32.0 *F)

    This is my very first electronics venture, it took me almost a month to get DHT11 from China and at it would be hard to get an resistor in my small town :(

    Thanks

    ReplyDelete
  4. Hello, good explanation!

    If I need to change the pin number to 18, what line do I have to change?

    This one?
    #define DHT11PIN 7 -> #define DHT11PIN 18


    If yes, the raspi crash..

    ReplyDelete
  5. thanks for the article, this works nicely!
    What I'm trying to do is to connect second DTH11 sensor. What I've noticed it only works with pin7 and when I try to connect it to a different pin - it doesn't give me data (of course I've updated C code to use different pin). Do you know if there are any restrictions on what pin to use?

    ReplyDelete
  6. Hi yall,

    nice work, but I'm running into some weird issue. I try to run sensor to feed data to some rrd file, so I have to extract the payload from sensors' output. Just executed sensor give me fine continously output, but as soon as I try to process the output by piping to awk, grep or comparables I end up with no output at all, I also can't redirect the output to a file.

    The interesting part is, if I redirect stderr to /dev/null I'm presented data:

    [email protected]ypi ~ $ sudo sensor 2> /dev/null
    Interfacing Temperature and Humidity Sensor (DHT11) With Raspberry Pi
    Humidity = 38.0 % Temperature = 20.0 *C (68.0 *F)
    Humidity = 38.0 % Temperature = 20.0 *C (68.0 *F)

    If I redirect stdout to /dev/null I end up with nothing, so the output obviously goes to stdout:

    [email protected] ~ $ sudo sensor 1> /dev/null
    *nothing*

    However, redirecting stdout to a file is unsuccessful as well:

    [email protected] ~ $ sudo sensor 1> out.file

    Strange...

    ReplyDelete
  7. Do you have any code to get the readings from the DHT11 sensor in Python. I have ordered a sensor and will be connecting it to my raspberry pi.

    Thanks.

    ReplyDelete
  8. Nice tutorial. Got it to work , but even though I have the resistor accross the VCC and Data pins i still get intermittent invalid data, change from a 10k to a 47k resistor but results are the same. any ideas as to what may be at fault?
    cheers, fitzroy.

    ReplyDelete
  9. Hello is your code open source an can i use it in my own project?

    ReplyDelete
  10. Nice information about the Humidity, now you can control the Humidity using
    Humidity Controller

    ReplyDelete