Sunday 13 March 2016

DHT11 humidity and temperature sensor interfacing

when i first got this sensor in my hand i thought it might be an analog sensor and tried with analog channels which dint work.

Then after googling some time i found a data sheet saying this sensor works on 1 wire interface which means a single microcontroller pin used as both trigger and input reading.



This sensor provides 40 bits of data in a single burst.

8 bits humidity data integral part.
8 bits humidity data decimal part
8 bits temperature data integral part.
8 bits temperature data decimal part
8 bits check sum data

 There is a data frame sequence to be followed to read the data from this sensor. I copied these frames from its data sheet.

So got the data frames are ready. My choice of microcontroller is ATmega8 as i got an awesome USB programmable development board with me.
Good support drivers provided with this board like lcd, uart, adc all in winavr compatible C.
I am using PORTC pin PC0 an sensor data pin.



here is the code:
//============== start of program=================================

#include<avr/io.h>
#include<util/delay.h>
#include"uart.h"// UART header file provided with the development board
                          // serial communication

unsigned char temp=0,humidity=0;// actual values
unsigned char hm_bit_count=0;// count the 40 bit sequence
unsigned char hm_pulse_width=0; // to identify the pulse with in case of '0' and '1'
unsigned char hm_data_buffer[50];//40 bit sequence

void main()
{


 uart_init();// configures the UART value
_delay_ms(100);

while(1)
{

 DDRC=0x01;//PC0 out put
PORTC=0x01; //PC0 high
_delay_ms(10);// 10 ms high for stable value

PORTC=0x00;//PC0 low
_delay_ms(18);//low delay trigger to sensor
DDRC=0x00;// PC0 input
PORTC=0x01;//PC0 internal pull up enable
_delay_us(2);//input mode and pullup 20us wait min(i kept 2 instead of 20 )
while((PINC&0x01)==1);//wait untill the sensor pulls the line to low
  while((PINC&0x01)==0);//wait during the line is  low for 80us
  while((PINC&0x01)==1);//wait during the line is high for 80us


// reading sequence starts

    for(hm_bit_count=0;hm_bit_count<40;hm_bit_count++)//reading sequence of 40 bits
{
      while((PINC&0x01)==0);//wait for 50 micro sec delay before bit

      for(hm_pulse_width=0;hm_pulse_width<80;hm_pulse_width++)//max width is 70
    {
 if((PINC&0x01)==1)//pin high
  _delay_us(1);
  else
  break;
     }

  if(hm_pulse_width>40)//if width is 28us then 0 and is 70 for 1 so im using 40 as threshold
          hm_data_buffer[hm_bit_count]='1';// storing character 1
else
hm_data_buffer[hm_bit_count]='0';// storing character 0

}

 tx_string("\n\r raw data: ");// display function using UART
 tx_string(hm_data_buffer); //displays the buffer values


  temp=0;humidity=0;

// i am considering only integral part of humidity and temperature values.

  for(hm_bit_count=0;hm_bit_count<8;hm_bit_count++)// converting raw bits to single byte value
  {

   if(hm_data_buffer[hm_bit_count]=='0')
   humidity=(humidity&0xfe);
   else
   humidity=(humidity|0x01);
   //if(hm_bit_count<
   humidity=humidity<<1;
  }

   for(hm_bit_count=16;hm_bit_count<24;hm_bit_count++)
  {

   if(hm_data_buffer[hm_bit_count]=='0')
   temp=(temp&0xfe);
   else
   temp=(temp|0x01);
   //if(hm_bit_count<
   temp=temp<<1;
  }

tx_string("   humidity: ");tx_num(humidity);
tx_string("   temperature : ");tx_num(temp);

}//end of while
}//end of main
//============== end of program=================================

NOTE: in the above program i just omitted the decimal part of the sensor data and displaying only the integral part of them.

In order to display the values on PC i'm using CP2102 usb to serial converter and tera term software at 9600 baud rate.