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
Wiring up the DHT11 sensor
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 (click to enlarge) |
- 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.
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:
Display the temperature or humidity on LCD:
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:
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.
No comments:
Post a Comment