29 Temmuz 2016 Cuma

DHT22 İLE SICAKLIK VE NEM ÖLÇÜMÜ

   Bu yazımızda dijital sıcaklık ve nem sensörü olan DHT22'nin kullanımını öğreneceğiz. Hemen ardından da PIC16F877A mikrodenetleyici ile bir uygulama gerçekleştireceğiz. Uygulamada DHT22 sesnsöründen okuduğumuz verileri 16x2 LCD ekrana yazdıracağız.
   DHT22 tek data hattı üzerinden mikrodenetleyiciler ile iletişim sağlar. -40 / 80 °C arasında sıcaklığı ve 0-100%RH arasında bağıl nemi algılayabilir. Sıcaklık ölçüm doğruluğu 0.5 °C ve bağıl nem ölçüm doğruluğu ise 2%RH 'dır.
   DHT22 sensörü ve mikrodenetleyici ile bağlantı şeması aşağıdaki gibidir.





   Şimdi DHT22'nin ölçüm yapmaya nasıl başlatılacağını ve ölçüm sonucu elde edilecek dijital verinin formatını inceleyeceğiz.
 
DHT22 sensörü ilk başta bekleme durumundadır. Mikrodenetleyici tarafından bir start sinyali gönderilerek çalışma durumuna geçer. Mikrodenetleyici start sinyali gönderimini bittirdiğinde, DHT22 daha sonra mikrodenetleyiciye göndereceği 40 bitlik nem ve sıcaklık datalarının habercisi olan response sinyalini gönderir. Mikrodenetleyiciden start sinyali gelmeden, DHT22, mikrodenetleyiciye  response sinyalini göndermez. Beklenen cevabın gelmesinden sonra DHT22 ölçüm sonucu elde ettiği 40 bitlik dijital veriyi mikrodenetleyiciye gönderir. 40 bitlik veri gönderimi bittiğinde sensör tekrar bekleme durumuna geçer ta ki  bir start sinyali daha gelene kadar.
   Mikrodenetleyici ile sensörün genel iletişim sürecini aşağıdaki  şekilden de görebilirsiniz.


    Yukarıda anlattıklarımızı birer başlık altında daha detaylı bir  şekilde inceleyelim. 

1) Mikrodenetleyicinin DHT22'ye start sinyali göndermesi ve DHT22'nin mikrodenetleyiciye response sinyali göndermesi:

    Mikrodenetleyici ile DHT22 nin iletişim sağladığı data pini normalde high voltaj ( lojik '1' ) seviyesindedir. Mikrodenetleyici ile DHT22 arasında iletişim başladığında, mikrodenetleyici data pinini low seviyesine ( lojik '0' ) çeker. Mikrodenetleyici lojik '0' seviyesinde en az 1~10ms bekleyerek DHT22' nin bu sinyali bulmasını sağlar. Ardından mikrodenetleyici data pinini high seviyesine çeker ve DHT22'nin cevap vermesi (response sinyali) için 20~40us bekler.
     DHT22 start sinyalini tespit edince, önce cevap olarak data pinini low seviyesine düşürür ve 80us bu seviyede tutar. Sonra DHT22 veri göndermeye hazırlanmak amacıyla data pinini high seviyesine çeker ve 80us de bu seviyede bekler. Aşağıda ki şekilde start ve response sinyallerinin gelişim sürecini görebilirsiniz.













2)  DHT22'nin mikrodenetleyiciye dijital nem ve sıcaklık verilerini göndermesi:

     DHT22, mikrodenetleyiciye veriyi gönderirken, her bir biti bir kare dalga saykılı olarak gönderir. Gönderilen her bir bit low voltaj seviyesi ile başlar ve 50us bu seviyede devam eder. Hemen ardından high voltaj seviyesine yükselir. High seviyesinde kalma süresi gönderilen bitin lojik '1' veya '0' olma durumunu belirler. High seviyesinde kalma süresi 26~28us ise gelen bit lojik '0' , 70us ise lojik '1' demektir. Aşağıdaki şekilden de gayet iyi anlaşılmaktadır.



    DHT22 den mikrodenetleyiciye gönderilen veri toplamda 40 bitden oluşmaktadır. İlk 16 bit nem datasını, sonra ki 16 bit ise sıcaklık datasını içerir. Son 8 bit ise check sum bitleridir. Sıcaklık ve nemin gerçek değerlerinin nasıl hesaplanacağını aşağıdaki örnekleri inceleyerek öğrenebilirsiniz.





















    Örneklerden de anlaşıldığı gibi 40 bitlik datanın ilk 16 bitinin decimal karşılığını alıp elde edilen sayıyı 10'a böldüğümüzde nemin gerçek değerini buluruz. Bir sonraki 16 bitin decimal karşılığını alıp elde edilen sayıyı 10'a böldüğümüzde sıcaklığın gerçek değerini buluruz. Burada ki önemli bir nokta şudur; sıcaklık datasına ait 16 bitin en ağır biti '1' ise sıcaklık sıfırın altındadır. Bu durumda en ağır biti görmezden gelerek hesaplama yapılır fakat bilinir ki elde edilen sıcaklık değeri sıfırın altındadır. Son 8 bit ise nem ve sıcaklık verilerinin 8 bitlik parçalar halinde toplamına eşittir.
     Uygulamamızın devre şeması da aşağıdaki şekildedir.
































Mikrodenetleyici programı:

//************  LCD module connections  ******************
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB4_bit;
sbit LCD_D4 at RB3_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB1_bit;
sbit LCD_D7 at RB0_bit;

sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB4_bit;
sbit LCD_D4_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB1_bit;
sbit LCD_D7_Direction at TRISB0_bit;

//****************************************************



// AM2302 module connections
sbit AM2302_Bus_In at RD0_bit;
sbit AM2302_Bus_Out at RD0_bit;
sbit AM2302_Bus_Direction at TRISD0_bit;
// END AM2302 module connections

char AM2302_Data[5] = {0, 0, 0, 0, 0};
unsigned humidity = 0, temperature = 0;
 const char degree[] = {14,10,14,0,0,0,0,0};
void degreeChar(char pos_row, char pos_char) {
  char i;
    Lcd_Cmd(64);
    for (i = 0; i<=7; i++) Lcd_Chr_CP(degree[i]);
    Lcd_Cmd(_LCD_RETURN_HOME);
    Lcd_Chr(pos_row, pos_char, 0);
}
//Get Sensor values
char AM2302_Read(unsigned *humidity, unsigned *temperature) {
  char i = 0, j = 1;
  char timeout = 0;
  char sensor_byte;
  AM2302_Bus_Out = 0;

  AM2302_Bus_Direction = 1;                         //Set AM2302_Bus as input
  AM2302_Bus_Direction = 0;                         //Set AM2302_Bus as output
  AM2302_Bus_Out = 0;                               //Host the start signal down time min: 0.8ms, typ: 1ms, max: 20ms
  Delay_ms(18);                                    //Delay 2ms
  AM2302_Bus_Out = 1;                               //Set AM2302_Bus HIGH
  AM2302_Bus_Direction = 1;                         //Set AM2302_Bus as input

  // Bus master has released time min: 20us, typ: 30us, max: 200us
  timeout = 200;
  while (AM2302_Bus_In == 1) {
    Delay_us(1);
    if (!timeout--) {
      return 1;
    } //ERROR: Sensor not responding
  }

  // AM2302 response signal min: 75us, typ: 80us, max: 85us
  while (!AM2302_Bus_In) { //response to low time
    Delay_us(85);
  }

  while (AM2302_Bus_In) {  //response to high time
    Delay_us(55);
  }

  /*
   * time in us:            min  typ  max
   * signal 0 high time:    22   26   30 (bit=0)
   * signal 1 high time:    68   70   75 (bit=1)
   * signal 0,1 down time:  48   50   55
   */

  i = 0; //get 5 byte
  for (i = 0; i < 5; i++) {
    j = 1;
    for (j = 1; j <= 8; j++) { //get 8 bits from sensor
      while (!AM2302_Bus_In) { //signal "0", "1" low time
        Delay_us(1);
      }
      Delay_us(30);
      sensor_byte <<= 1;       //add new lower byte
      if (AM2302_Bus_In) {     //if sda high after 30us => bit=1 else bit=0
        sensor_byte |= 1;
        delay_us(45);
        while (AM2302_Bus_In) {
          Delay_us(1);
        }
      }
    }
    AM2302_Data[i] = sensor_byte;
  }

  *humidity = (AM2302_Data[0] << 8) + AM2302_Data[1];
  *temperature = (AM2302_Data[2] << 8) + AM2302_Data[3];

  return 0;
}

// Process and display current value to LCD
void processValue(unsigned humidity, unsigned temperature) {
  char txt[]= "00.0";

  LCD_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  //temp = humidity / 10.0;
  if(humidity>=1000)  Lcd_Chr(1,9,(humidity/1000) +48);
  else  Lcd_Out(1,9," ");
  txt[0]= humidity/100%10 +48;
  txt[1]= (humidity/10)%10 +48;
  //txt[2]= '.';
  txt[3]= humidity%10 +48;
  Lcd_Out(1,1,"NEM    :");
  Lcd_Out(1,10,txt);
  Lcd_Chr(1,15,0x25);

  //temp = temperature / 10.0;
  if(temperature&0x8000) Lcd_Out(2,9,"-");
  else  Lcd_Out(2,9," ");
  temperature&=0x7FFF;
  txt[0]= temperature/100 +48;
  txt[1]= (temperature/10)%10 +48;
  //txt[2]= '.';
  txt[3]= temperature%10 +48;
  Lcd_Out(2,1,"SICAKLK:");
  Lcd_Out(2,10,txt);
  degreeChar(2, 14);
  Lcd_Chr(2,15,0x43);
}

void Display_Init(){
  LCD_Init();
  LCD_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);


  Lcd_Out(1,3,"DHT22 Sensor");
  Lcd_Out(2,3,"  Uygulama  ");
  delay_ms(2000);
}

void main() {
  //char k = 0, t;

  Display_Init();

  while (1) {
    if (AM2302_Read(&humidity, &temperature) == 0)                 // Display AM2302_Read sensor values via LCD
      processValue(humidity, temperature);                         // Display AM2302_Read sensor values via LCD
else {
      LCD_Cmd(_LCD_CLEAR);
      Lcd_Cmd(_LCD_CURSOR_OFF);
      Lcd_Out(1,3,"Sensor cevap");
      Lcd_Out(2,3,"vermiyor");
    }

    Delay_ms(1000); //Delay 2000ms

  }
}

   MikroC programımız yukarıda ki gibidir. Programı yukarıda verilen bilgiler ışığında incelediğinizde umuyorum ki anlaşılacaktır. Uygulamamızın isis simülasyon videosu da aşağıda yer almaktadır.


     İlgili arkadaşlara başarılar dilerim...

7 yorum:

  1. Bu yorum yazar tarafından silindi.

    YanıtlaSil
  2. merhaba size nası lulaşa bilirim bir konuda yarmdımınıza ihtiyacım var

    YanıtlaSil
  3. Bu yorum yazar tarafından silindi.

    YanıtlaSil
  4. Sorun nedir nasıl yardımcı olabilirim

    YanıtlaSil
  5. arduino ile negatif sıcaklık ölçümü nasıl yapılır

    YanıtlaSil
  6. Merhaba. Bir sorum var ama cevaplayabilir misiniz?

    YanıtlaSil