Friday, February 10, 2017

DHT11 Library Temperature and Humidity Sensor

 Interfacing DHT11 sensor with an AVR Microcontroller


This post describes how to interface a DHT11 temperature and humidity sensor with an AVR microcontroller and how to read and display the data on an LCD using the DHT11 library.

DTH11 is a low cost hobby digital sensor used to measure temperature and relative humidity. Digital means that the sensor incorporates a 8 bit microcontroller inside that takes care of ADC measurements for you. With an analog sensor you would have to set up an ADC and measure the sensor resistance directly and interpret the data. The DHT11 sensor uses a proprietary 1-wire protocol which is described down bellow.
The DHT11 sensor comes in a single row 4-pin package, breadboard friendly, and operates from 3.5 to 5.5V. It can measure temperature from 0-50 °C with an accuracy of ±2°C and relative humidity ranging from 20-95% with an accuracy of  ±5%. During measurement it draws 0.3mA and in standby 60uA.
The sampling rate is 0.5 Hz in some datasheets and 1 Hz on others; this means it is not recommended to read the sensor more than once every second or every two seconds. The recommended sample rate is 5 seconds to prevent the display changing to often.

DHT11 pinout

DHT11 Pinout

Wiring up the DHT11 sensor

Wiring up DHT11
Pin 1 is connected to power supply VCC.
Pin 2 is the DATA LINE that communicates with the MCU and in this example is connected to pin PC5. However you can connect it to any digital pin on the microcontroller. A 4.7k resistor is used to pull up the pin according to the datasheet.
Pin 3 is not connected. You can let it flapping in the breeze.
Pin 4 is connected to ground.

DHT11 serial 1-wire bi-directional communication protocol

DHT11 communication protocol

DHT11 communication protocol (click to enlarge)

In the idle state DHT11 sensor data line must be kept high by the pull-up resistor.
  • The reading starts when the microcontroller pulls the bus LOW for at least 18 milliseconds and then waits for about 20 - 40 microseconds for the sensor to pull the bus LOW. During this time the MCU pin is in reading mode and the bus line is HIGH as can be seen in the above diagram.
  • The DHT11 sensor then respond by pulling the line LOW for 80 us and then HIGH for 80 us.
  • From now the sensor starts transmitting 40 bits (5 bytes) of data. BIT 0 is transmitted by pulling the line LOW for 50 us and then HIGH for 26 - 28 us. BIT 1 is transmitted by pulling the line LOW for 50 us and then HIGH for 70 us.
  • After all 40 bits are sent, the sensor pulls the line bus LOW for 50 us and then the line is pulled HIGH by the pull-up resistor until the microcontroller initiates a new reading.

 

  • DHT11 data format:

The bits are sent starting with MSB (Most Significant Bit).
40 bits = 8bit humidity integer data + 8bit humidity decimal data + 8 bit temperature integer data + 8bit decimal temperature data + 8 bit parity bit.
Because DHT11 temperature accuracy is ±2°C and humidity is ±5% the decimal bits will always be 0.
The checksum is calculated by adding the first 4 bytes and the sum of them must be equal to the 5'th byte - the parity bit.

DHT11 sensor library for AVR microcontrollers

This library is easy to implement and use and incorporates safety checks to prevent the MCU remaining stuck in a while loop while waiting for sensor responses, in case the sensor breaks and remain in a HIGH or LOW state.
First download and copy the library in your project and then open it to specify the location of the pin where the sensor is connected.

In the setup section you have the following settings:
// Depending on the port and pin you are using replace the x with the port letter, e.g. C, D, B, and n with the pin number
#define SENSOR_DDR              DDRx
#define SENSOR_PORT             PORTx
#define SENSOR_PIN              PINx
#define SENSOR_PIN_BIT          PCn

// SAMPLE_DELAY in milliseconds. Default is 2 seconds
#define SAMPLE_DELAY            2000

// This is used by the "DHT11ReadDataAvg" function to take an average measurement and indicates how many samples to take
#define DHT_NR_OF_SAMPLES       8

// It is recommended to calibrate the sensor by using other two temperature measuring devices and put the offset here (in degrees celsius. If positive, will be added to final result, if negative, will be subtracted
#define DHT_TEMP_ERROR_OFFSET   0

// Comment this line out if you want to add the delay in your code
#define ADD_MINIMUM_DELAY

In the main file include the DTH11 library:
#include "DHT11sensor v1.0.h"

  •  Read the temperature or humidity:

To read the temperature or humidity first use the function "DHT11ReadData()". If the reading was successfully the function will return 1, if there was an error the return error code will be 0 and if there is a checksum error the returned code is -1. Based on this error codes you can take proper actions.

  • Display the temperature or humidity on LCD:

DHT11DisplayTemperature() will display the temperature on an LCD followed by the Celsius sign.
DHT11DisplayHumidity() will display humidity on an LCD followed by the % sign.
To be able to use the display functions you need to download and add the LCD library from here OnLCDLib v1.3.h (link opens in a new tab).

  • Measuring and displaying an average of temperature and humidity:

DHT11ReadDataAvg() this function will take n number of readings, n being defined by DHT_NR_OF_SAMPLES and average them. After each reading a delay will be added and the duration depends on SAMPLE_DELAY . So if the delay is 2 seconds  and number of samples is 8 the total average reading will be 16 seconds.
If you use DHT11ReadDataAvg you don't have to use DHT11ReadData function.

Both DHT11ReadDataAvg and DHT11ReadData functions dumps the received data in DHT11Data array. So if you use UART you can access this array to send the data instead of displaying on LCD. Humidity value is in DHT11Data[0] and the temperature is in DHT11Data[2].

Example on how to use the DHT11 library in a main.c project
/****************************************
 INCLUDES
*****************************************/
#include <avr/io.h>
#include <util/delay.h>
#include "DHT11sensor v1.0.h"


/****************************************
 MAIN FUNCTION
*****************************************/

int main(void){
    // Initialise the LCD
    LCDSetup(LCD_CURSOR_NONE);

    int8_t DHTreturnCode;
 
    while(1){
        DHTreturnCode = DHT11ReadData();

        if(DHTreturnCode == 1){
            LCDHome();
            DHT11DisplayTemperature();
            LCDGotoXY(1,2);
            DHT11DisplayHumidity();
        }else{
            if(DHTreturnCode == -1){
                LCDHome();
                LCDWriteString("Checksum Error");
            }else{
                LCDHome();
                LCDWriteString("Unknown Error");
            }
        }
    }
}

Tip: don't put the sensor near a voltage regulator or other heat sources.

Download DHT11 Library

DHT11sensor v1.0.h
 

No comments:

Post a Comment