utorak, 19. veljače 2013.

Using DHT22 sensor with Pic18f4550



Quick example of how to use DHT22 sensor with pic18f4550.

Dht22 is a cheap but relatively accurate digital temperature and humidity sensor. Sensor works on 3-5V and it gives you digital signal on one data pin. You can pull out new data every 2 seconds.

You can find it on ebay for about 4-5$.






So, lets get started, to get this sensor working pin1 has to be connected to 3-5V, pin2 is data pin, pin3 is empty and pin4 has to be connected to GND.

It is also recommended to connect data pin to VCC with 10K resistor to act as a medium-strength pull up on the data line

according to datasheet first thing you have to do i to send a signal to sensor. You do that by setting a microcontroller pin to output and sending a low-high signal.

/**
* DHT22 sensor start
*/
unsigned short StartSignal(){
  TRISC0_bit = 0;  // set data port to output
  RC0_bit = 0;       // data output LOW
  Delay_ms(25);    // Low for at least 18ms (it can be even shorter)
  RC0_bit = 1;       // set output HIGH
  Delay_us(30);     // High for 20-40 us
  TRISC0_bit = 1;  // Data port is input  

                           //sensor should now ser input to LOW for next 80us
  Delay_us(2);    
  return 1;
}


Sensor will now set data pin to low for next 80us and then high for next 80us. After this sequence sensor will start sending data.

/**
*  DHT22 senzor - check response from dht22
*/
unsigned short CheckResponse(){

  if (!RC0_bit){
     while (!RC0_bit){}  //waiting till sensor starts sending ones
     if (RC0_bit){
       while (RC0_bit){} //waiting till 80us high period is over
       delay_us(20);      //just in case delay.
       return 1;
     }
  }
  else if (RC0_bit){      // if data pin is still high, then something is wrong
         Lcd_Out(1,1,"error data=1    ");
         Delay_ms(1000);
         return 0;
  }
}


Microcontroller can now read 40bit data.

DATA = 
+ 8 bit integral RH data
+ 8 bit decimal RH data
+8 bit integral T data
+8 bit decimal T data
+8 bit checksum

If the data transmission is right, check-sum should be the last 8 bit of "8 bit integral RH data+8 bit decimal RH
data+8 bit integral T data+8 bit decimal T data.


So you need to do four readings for every byte.

if sensor sends 70us high state for 1 and 26-28us high state for 0.
after each bit there is a 50us low state.

/**
* DHT22 senzor - read data
*/
unsigned short ReadByte()
{
  unsigned short num = 0, t;
 
TRISC0_bit = 1; //postavljam input
  for (i=0; i<8; i++){
   while(!
RC0_bit);
   Delay_us(40);
   if(
RC0_bit) num |= 1<<(7-i);  // If time > 40us, Data is 1
   while(
RC0_bit);
  }
  return num;
}
 

 
/**
* DHT22 main
*/
void getTempHum(){
     unsigned short s_signal, check;
     Delay_ms(2000);
     s_signal=StartSignal();
     if (s_signal){
        check = CheckResponse();
     }
     if (!check) {
       Lcd_Out(2,1,"Sensor ERR         ");
       Delay_ms(900);
     }
     else{
        RH_Byte1 = ReadByte();
        RH_Byte2 = ReadByte();
        T_Byte1 = ReadByte();
        T_Byte2 = ReadByte();
        CheckSum = ReadByte();



        //preparing output

        ToText(output3, 1, ToInt(T_Byte1,T_Byte2) );
        ToText(output4, 1, ToInt(RH_Byte1,RH_Byte2));

       Lcd_Out(1, 1,
output3);
       Lcd_Out(2, 1,
output4);
       Delay_ms(2);
     }
}




  

- matija kancijan 

Broj komentara: 7:

Unknown kaže...

Which software is used to compile the codes ? anyway it dosen't matter as far as the logic seems good :),,, Logic seems to be good.
Great Job :)

Hoping for some more good posts.

Great job :)



Regards Ron
www.rakeshmondal.info/

kanc kaže...

Thank You Rakesh,

software used to compile this code was "mikroC" from MikroElektronika

http://www.mikroe.com/mikroc/pic/

simone kaže...

is to send the complete source code for the email luciano_amorim29@yahoo.com.br

Unknown kaže...

Please send the complete source code for the email cruzsolanom@hotmail.com, thanks for all

Hasan GÜLER kaže...

Great job my friends, could you please sen me source code? I have a homework project. Thank you. gulerhasan@yahoo.com

Alejandro kaže...

Hello, My name is Alejandro from Argentina. I tried to connect DHT22 sensor with PIC 18F4550, but it did not work. I connected DHT22 Pin1 to Vcc, Pin2 to Pin15 (RC0)from PIC with a resistor of 10K to Vcc, Pin 3 no connected and Pin 4 connected to Vcc. I tried with Crystal 4 Mhz and 20 Mhz, but it did not work. I don't know what is the problem. The source code is in MikroC:

#ifndef __DHT22_NEW_H
#define __DHT22_NEW_H

#define dht22 RC0_bit
#define dht_io TRISC0_bit

void dht_init (void);
short int leer_datos_dht(void);
void leer_dht22 ();//float *dhthum,float *dthtemp);

#endif

#ifndef __DHT22_NEW_C
#define __DHT22_NEW_C
#include

short int dht22_dat[5];

void dht_init (void){
dht_io=0;
Delay_Ms(1);
dht22=1;
}

short int leer_datos_dht(void){
short int i = 0;
short int result=0;
for (i=0; i< 8; i++) {
//We enter this during the first start bit (low for 50uS) of the byte
//Next: wait until pin goes high
while(dht22==0);
delay_us(30);
if (dht22==1){//Was: if(PINC & _BV(dht_PIN))
result |=(1<<(7-i));
}
while (dht22==1);
//Was: while((PINC & _BV(dht_PIN)));
}//end of "for.."

return result;
}

void leer_dht22(){// (char *dhthum, char *dthtemp){
//byte GlobalErr=0;
unsigned short dht22_in, i, dht22_checksum;
int temperatura, humedad;
float temp, hum;
char message1[10];
char message2[10];

dht_io=0; // configurar el pin como salida
dht22=1;
Delay_Us(20);
dht22=0;
Delay_Ms(18);
dht22=1;
Delay_Us(22);

dht_io=1;// configurar el pin como entrada
Delay_Us(5);
dht22_in=dht22;

if(dht22_in) {
//GlobalErr=1;
Lcd_Out(1,1,"Con 1 de inicio no encontrada");
return;
}

Delay_Us(80);
dht22_in=dht22;

if(!dht22_in){
//GlobalErr=2;
Lcd_Out(1,1,"con 2 de inicio no encontrada");
return;
}

delay_us(80);

for (i=0; i<5; i++){
dht22_dat[ i ] = leer_datos_dht(); // capturando datos
}

dht_io=0;
delay_us(10);
dht22=1;

dht22_checksum= dht22_dat[0]+dht22_dat[1]+dht22_dat[2]+dht22_dat[3];

if(dht22_dat[4]!=dht22_checksum){
//GlobalErr=3;
Lcd_Out(1,1,"\r\nDHT checksum error");
}

message1[0] = dht22_dat[2]/10 + 48;
message1[1] = dht22_dat[2]%10 + 48;
message1[2] = dht22_dat[3]/10 + 48;
message1[3] = 223; // Degree symbol
message1[4] = '\0';
message2[0] = dht22_dat[0]/10 + 48;
message2[1] = dht22_dat[0]%10 + 48;
message2[2] = dht22_dat[1]/10 + 48;
message2[3] = '\0';

Lcd_Cmd(_Lcd_Clear);
Lcd_Out(1, 1, message1);
Lcd_Out(2, 1, message2);

/*humedad = make16(dht22_dat[0],dht22_dat[1]);
temperatura = make16(dht22_dat[2],dht22_dat[3]);

hum = humedad;
temp = temperatura;

dhthum = (hum)/10;
dthtemp = (temp)/10;*/
}
#endif

#include
// LCD module connections
sbit LCD_RS at RD0_bit;
sbit LCD_RW at RD1_bit;
sbit LCD_EN at RD2_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD2_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections

void main() {

ADCON0=0;
ADCON1=00001111;// 'All digital
CMCON=7;// 'Comparators OFF
INTCON2=0;//
TRISD = 0x00;
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1, 1, "Iniciando...");
delay_ms(500);
dht_init();
while(1) {
delay_ms(500);
leer_dht22();

}
}

Do you have any idea about this? Are there any problem with this source code?

Thanks!!
Alejandro

Unknown kaže...

Great job Boy, could you please share with me source code? jaskoeldefenso@gmail.com
Thanks