How to interface DHT22 with PIC microcontroller

Published by MKDas on

In this article, we are going to learn how to interface the DHT22 Temperature and Humidity sensor with the PIC16F877A microcontroller. DHT22 is related to DHT11 with some changes in data communication. This sensor is also known as AM2302/RHT03. As the Proteus library of DHT22 is not so available, so the library file will be attached in this article below. So let’s interface DHT22 with PIC microcontroller.

Disclaimer: Electricity is always dangerous. Skill required to work with electricity. Do work at your own risk. The author will not be responsible for any misuse or harmful act. This website contents are also copyright protected. Anything copied and directly posted on your website and claiming it as yours is prohibited and nonsensical. The author published all the articles as open source to help you to make your project and learning purpose only. Learn and make one for yourself. If need any help feel free to ask the author. The author will be helpful to you. Thanks.

About DHT22 sensor:

Before interfacing DHT22 with PIC microcontroller we need to know about the DHT22 first, The DHT22(AM2302, RHT03) sensor comes in a single row 4-pin package and operates from 3.3 to 5.5V power supply. It can measure temperature from -40-80 °C with an accuracy of ±0.5°C and relative humidity ranging from 0-100% with an accuracy of  ±2%. The sensor provides fully calibrated digital outputs for the two measurements.

It has got its own proprietary 1-wire protocol, and therefore, the communication between the sensor and a microcontroller is not possible through a direct interface with any of its peripherals. The protocol must be implemented in the firmware of the MCU with precise timing required by the sensor.

DHT22 sensor


The following timing diagrams describe the data transfer protocol between an MCU and the DHT22 sensor. The MCU initiates data transmission by issuing a “Start” signal. The MCU pin must be configured as output for this purpose. The MCU first pulls the data line low for at least 18 ms and then pulls it high for the next 20-40 us before it releases it. Next, the sensor responds to the MCU “Start“  signal by pulling the line low for 80 us followed by a logic high signal that also lasts for 80 us.

Remember that the MCU pin must be configured to input after finishing the “Start“ signal. Once detecting the response signal from the sensor, the MCU should be ready to receive data from the sensor. The sensor then sends 40 bits (5 bytes) of data continuously in the data line. Note that while transmitting bytes, the sensor sends the most significant bit first.

DHT22 RHT03 AM2302 sensor timing

Data consists of decimal and integral parts. Complete data transmission is 40bit, and the sensor sends higher data bit first. Data format: 16 bits RH data + 16 bits temperature data + 8bit checksum. If the data transmission is right, the check-sum should be the last 8bit of “MSB 8-bit RH data + LSB 8-bit RH data + MSB 8-bit temperature data + LSB 8-bit temperature data”.

DHT22 RHT03 AM2302 sensor timing 2

The DHT22 is a digital sensor so it sends 1’s and 0’s, but it is very important to know how it sends the digital data. The figure below shows how the sensor sends its information:

Download DHT22 Proteus Library.

Example1:

MCU has received 40 bits of data from AM2302 as
0000 0010 1000 1100 0000 0001 0101 1111 1110 1110
16 bits RH data 16 bits T data checksum
Here we convert 16 bits RH data from binary system to decimal system,
0000 0010 1000 1100 → 652


Binary system Decimal system
RH=652/10=65.2%RH
Here we convert 16 bits T data from binary system to decimal system,
0000 0001 0101 1111 → 351
Binary system Decimal system
T=351/10=35.1℃
When the highest bit of temperature is 1, it means the temperature is below 0 degrees Celsius.

Example2:

1000 0000 0110 0101, T= minus 10.1℃
16 bits T data
Sum=0000 0010+1000 1100+0000 0001+0101 1111=1110 1110
Check-sum=the last 8 bits of Sum=1110 1110

Circuit diagram:

Here is the circuit diagram of our project DHT22 with PIC microcontroller:

Circuit Diagram

You may find this helpful too: PCB design & Software help.

MicroC coding:

/*******************************************************************************
Program for, "DHT11 interfacing with PIC16F877A"
Program written by_ Engr. Mithun K. Das
MCU: PIC16F877A; X-tal: 8MHz; mikroC pro for PIC v7.6.0
Date: 15-05-2020
*******************************************************************************/

// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// END of LCD initialization

// DHT22 pin connection (here data pin is connected to pin RB0)
#define DHT22_PIN         RB1_bit
#define DHT22_PIN_DIR     TRISB1_bit

#include <stdint.h>

// read one byte from sensor
uint8_t dht22_read_byte()
{
  uint8_t i = 8, dht22_byte = 0;

  while(i--)
  {
    while( !DHT22_PIN );

    Delay_us(40);

    if( DHT22_PIN )
    {
      dht22_byte |= (1 << i);   // set bit i
      while( DHT22_PIN );
    }
  }
  return(dht22_byte);
}

// read humidity (in hundredths rH%) and temperature (in hundredths °Celsius) from sensor
void dht22_read(uint16_t *dht22_humi, int16_t *dht22_temp)
{
  // send start signal
  DHT22_PIN     = 0;   // connection pin output low
  DHT22_PIN_DIR = 0;   // configure connection pin as output
  Delay_ms(25);        // wait 25 ms
  DHT22_PIN     = 1;   // connection pin output high
  Delay_us(30);        // wait 30 us
  DHT22_PIN_DIR = 1;   // configure connection pin as input

  // check sensor response
  while( DHT22_PIN );
  while(!DHT22_PIN );
  while( DHT22_PIN );

  // read data
  *dht22_humi = dht22_read_byte();  // read humidity byte 1
  *dht22_humi = (*dht22_humi << 8) | dht22_read_byte();  // read humidity byte 2
  *dht22_temp = dht22_read_byte();  // read temperature byte 1
  *dht22_temp = (*dht22_temp << 8) | dht22_read_byte();  // read temperature byte 2
  dht22_read_byte();               // read checksum (skipped)

  if(*dht22_temp & 0x8000)// if temperature is negative
  {
    *dht22_temp &= 0x7FFF;
    *dht22_temp *= -1;
  }
}

char message[] = "00.0";
int humidity, temperature;

// main function
void main()
{

  ADCON1 = 0x07;//ADC Off
  ADCON0 = 0x00;
  CMCON = 0x07;//comparator off
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Out(1,1,"DHT22 WITH");
  Lcd_Out(2,1,"PIC16F877A");
  Delay_ms(2000);
  Lcd_Cmd(_LCD_CLEAR);

  while(1)
  {

    dht22_read(&humidity, &temperature);

    Lcd_Out(1,1,"HUMIDITY:");
    Lcd_Out(2,1,"TEMP:");

    message[0] = humidity/100 + 48;
    message[1] = humidity/10%10 + 48;
    message[3] = humidity%10 + 48;
    Lcd_Out(1,11, message);
    Lcd_Out(1,16,"%");

    message[0] = temperature/100 + 48;
    message[1] = temperature/10%10 + 48;
    message[3] = temperature%10 + 48;
    Lcd_Out(2,11, message);
    Lcd_Chr_CP(223);
    Lcd_Out(2,16,"C");

    Delay_ms(1000);  // wait a second

  }//while(1)
}
// end of code.

Code explanation:

uint8_t dht22_read_byte()
{
  uint8_t i = 8, dht22_byte = 0;
  while(i--)
  {
    while( !DHT22_PIN );
    Delay_us(40);
    if( DHT22_PIN )
    {
      dht22_byte |= (1 << i);   // set bit i
      while( DHT22_PIN );
    }
  }
  return(dht22_byte);
}

This sub-function is to read each byte of 8bit data from the DHT22 sensor. This function is called from the main DHTread function.

void dht22_read(uint16_t *dht22_humi, int16_t *dht22_temp)
{
  // send start signal
  DHT22_PIN     = 0;   // connection pin output low
  DHT22_PIN_DIR = 0;   // configure connection pin as output
  Delay_ms(25);        // wait 25 ms
  DHT22_PIN     = 1;   // connection pin output high
  Delay_us(30);        // wait 30 us
  DHT22_PIN_DIR = 1;   // configure connection pin as input

  // check sensor response
  while( DHT22_PIN );
  while(!DHT22_PIN );
  while( DHT22_PIN );

  // read data
  *dht22_humi = dht22_read_byte();  // read humidity byte 1
  *dht22_humi = (*dht22_humi << 8) | dht22_read_byte();  // read humidity byte 2
  *dht22_temp = dht22_read_byte();  // read temperature byte 1
  *dht22_temp = (*dht22_temp << 8) | dht22_read_byte();  // read temperature byte 2
  dht22_read_byte();               // read checksum (skipped)

  if(*dht22_temp & 0x8000)// if temperature is negative
  {
    *dht22_temp &= 0x7FFF;
    *dht22_temp *= -1;
  }
}

Like DHT11, a start signal is required for DHT22 too. Then we need to check the response from DHT22. If the response is ok, then we can start the reading. The first two bytes are for humidity and the next two bytes are for temperature data. Finally, we eliminated the negative data from the result if any.

Test result:

Simulation result

Simulation works fine, real hardware works fine too. This library file can be used in suitable designs and real devices can be made. I tested the hardware before, at that time I had no plan for blogging. That is why did not record any video of those projects.

Anyway, in this article, you learned how to interface the DHT22 sensor with the PIC16F877A microcontroller. If you understand the concept of the code, then you can use any similar micro-controller. I hope you’ll make one and post here your test result.

I hope this project was helpful to you. If you make one for yourself, it will be a great pleasure for me. Anywhere you need help, let me know. Please share this project and subscribe to my blog. Thank you.


MKDas

I'm Mithun K. Das; B.Sc. in EEE from KUET, Bangladesh. Blog: https://labprojectsbd.com. "First, electronics was my passion, then it was my education, and finally, electronics is now my profession." I run my own electronics lab, M's Lab (https://mlabsbd.com). Where I work with the creation of new products from ideas to something in real life. Besides this is my personal blog where I write for hobbyists and newcomers in the electronics arena. I also have a YouTube channel where I publish other helpful videos, you can find the link inside the articles. I always try to keep it simple so that it becomes easy to understand. I hope these will help them to learn electronics and apply the knowledge in their real life.

2 Comments

Er S S RANA · December 15, 2020 at 1:54 pm

Dear Dasji
Please elaborate the addition of decimal value 48 to humidity as well as temperature. LCD functions used in the program have also not been defined. Please share link of used lcd functions.
With Regards.
Thanking you.

    Mithun K. Das · December 19, 2020 at 4:38 am

    +48 to convert the decimal to ASCII value. And the LCD functions are built-in functions of the compiler.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *