ARM – Not7: DHT11 Sıcaklık ve Nem Sensörü

Yayınlandı: 22 Mayıs 2016 / ARM STM32F4DISCOVERY Programlama...
Etiketler:, , , , , , , ,

imagesPek çok uygulamada sıcaklık ve nem değerlerinin birlikte ölçülmesi gerekmektedir. Örneğin tarım işletmeleri, mantar üretim çiftlikleri, soğuk hava depoları, tütün, kağıt, hububat, baharat depoları, seralar, çimlendirme odaları, kuluçka makinaları gibi yerlerde sıcaklık ve nemin birlikte ölçülmesi gerekmektedir.

Sıcaklık ve nem ölçen sensörlerden belkide en popüler olanı Sensirion firmasının üretmiş olduğu SHT11 isimli sensördür. Bu sensörün ölçüm hassasiyeti yüksek olmakla birlikte fiyatı yüksektir. Bu sensöre alternatif olarak üretilmiş düşük fiyatlı fakat hassasiyet değerleri SHT11 kadar iyi olmayan çin ürünü DHT11 sensörü de piyasada kendisine oldukça yaygın bir kullanım alanı bulmuştur.

DHT11’in ilginç bir çıkış üretme şekli var. Bu sebeple sensörü incelemek istedim ve çıkışını rahatlıkla okuyabilmek için bir kütüphane oluşturdum. Bu kütüphane dosylarını da mikroelektronika derleyicileri için bir kod paylaşım platformu olan libstock isimli siteye yükledim. Konunun sonunda bu dosyaları paylaşacağım.

Sensörün besleme aralığı 3.5V-5.5V aralığındadır. Sensörün sıcaklık ölçüm aralığı 2 celcius derece hassasiyetle 0-50 C, nem ölçüm hassasiyeti ise %5’tir. Sensörü mikrodenetleyiciye bağlamak için aşağıdaki gibi bir bağlantı kullanılabilir.

DHT11-connection-diagram

Sensörün çıkışını inceleyelim:

images

Diyagramdan görüldüğü üzere sensörden veri okumaya başlamak için ilk olarak mikrodenetleyicinin bir pinini çıkış olarak tanımlayıp sensörün data ucuna bağlamamız gerekiyor. Bağlantı sağlandıktan sonra mcu’nun çıkış ucundan 18 ms boyunca “0” sinyali göndermemiz ve 20-40us arasında “1” sinyali göndermemiz gerekmektedir. Bu işlemden sonra mcu’nun ilgili pini giriş olarak ayarlanmalı ve sensörün göndereceği veriyi beklemesi gerekmektedir. Sensör başlangıç sinyali olarak 80us “0” ve 80us “1” gönderir.  Başlangıç sinyalinden sonra sensör 40 bit veri göndermeye başlar. Bu verilerin 0 veya 1 olma durumları da şöyle anlaşılır: Eğer sensör ilk olarak 50us “0” 26-28us “1” sinyali gönderiyorsa o veri “0”, eğer ilk olarak 50 us “0” 70 us “1” gönderiyorsa o veri “1” anlamına gelmektedir.

Sensör her seferinde toplam 5 byte veri gönderir. Bu veriler sırasıyla nem değerinin tam kısmı, nem değerinin ondalık kısmı, sıcaklık verisinin tam kısmı, sıcaklık verisinin ondalık kısmı ve hata kontrol verisidir. Hata kontrol verisi kendisinden önce gelen 4 byte verinin toplamına eşittir. Eğer bu eşitlik sağlanmıyorsa veriler düzgün okunamamış demektir.  Aşağıda sensörden gelen verilerin hesaplanmasını anlatan datasheet örneğini görebilirsiniz.

Adsız

Hazırlamış olduğum kütüphane sayesinde yukarıda anlattığım bilgilerin hiç birisiyle uğraşmanıza gerek kalmadan sensör verisini rahatlıkla ölçebilirsiniz elbette. Ben buradaki örnek uygulamada STM32L053 Nucleo kitini kullandım ve sensörden ölçtüğüm veriyi usb port üzerinden oluşturulan sanal seri porta aktararak bilgisayarda görüntüledim.

Uygulamanın kodlarına göz atalım:

//DHT11 DEFINITONS
sbit DHT11_Pin_Output at GPIOC_ODR.B3;
sbit DHT11_Pin_Input at GPIOC_IDR.B3;
unsigned long DHT11_DIR_BASE at GPIOC_BASE;
unsigned long DHT11_DIR_PIN =_GPIO_PINMASK_3;
//END OF DHT11 DEFINITONS

char txt[7];

/////////////////////////////////
void main() {
  delay_ms(100);
  UART2_Init(9600);
  DHT11_init();

  while(1)
  {
   Dht11_Start();
   DHT11_Read();
   
   if(DHT11_CHKSM==((DHT11_TMP>>8)+(DHT11_HUM>>8)+(DHT11_TMP&0xff)+(DHT11_HUM&0xff)))
   {
    inttostr(DHT11_TMP>>8,txt);
    uart2_write('T');
    uart2_write('M');
    uart2_write('P');
    uart2_write('=');
    uart2_write(txt[4]);
    uart2_write(txt[5]);
    uart2_write(176);
    uart2_write('C');
    uart2_write('\r');
    uart2_write('\n');

    inttostr(DHT11_HUM>>8,txt);
    uart2_write('H');
    uart2_write('U');
    uart2_write('M');
    uart2_write('=');
    uart2_write('%');
    uart2_write(txt[4]);
    uart2_write(txt[5]);
    uart2_write('\r');
    uart2_write('\n');
    uart2_write('*');
    uart2_write('*');
    uart2_write('*');
    uart2_write('*');
    uart2_write('\r');
    uart2_write('\n');
    delay_ms(500);
  }
 }
}

Kütüphaneyi kullanırken ilk olarak pin tanımlamalarını yapmamız gerekiyor. Daha sonra “DHT11_Init();” fonksiyonu ile kurulumu tamamlamış oluyoruz. DHT11’den veri okumak içinse “DHT11_read();” yazmamız yeterli. Bu fonksiyonu kullandıktan sonra veriler DHT11_HUM, DHT11_TMP ve DHT11_CHKSM isimli işaretsiz integer tipinde olan(16bit) ve kütüphane içerisinde önceden tanımlanmış olan (sizin ayrıca tanımlamanıza gerek yok) değişkenlere aktarılıyor.  Bu değişkenlerin ilk 8 byteları tam kısım son 8 byteları ise ondalık kısım. Bu bilgiler ışığında gerisi bize kalıyor. Yukarıdaki koda dikkat edilirse bütün değişken verilerinin toplanarak sensörün gönderdiği son byta olan cheksum verisiyle karşılaştırıldığı ve eğer gelen veriler doğruysa işlem yapıldığı görülebilir.

Kütüphane ve örnek kod dosyalarına buradan ulaşabilirsiniz. Ayrıca libstockta  DHT11’i PIC mikrodeneytleyiciler ile kullanmak için de bir kütüphane yükledim. Ona da libstock profilimden ulaşabilirsiniz.

Kütüphane dosyalarını derleyiciye yüklemek için “mikroelektronika package manager” isimli programı buradan bilgisayarınıza indirip kurmalısınız.

İyi çalışmalar.

yorum
  1. Onur dedi ki:

    “Bu değişkenlerin ilk 8 byteları tam kısım son 8 byteları ise ondalık kısım.” cümlesindeki “bytelar”, “bitler” olması gerekiyor sanırım.

  2. Gökhan Gökçen dedi ki:

    iyi günler dilerim. Hocam sanırım microc pro arm ile yazılmış örnek kod parçaları var dht11 için. Board olarakta STM32L053 kullanılmış anladığım kadarı ile ben bu kodları f407vg için nasıl düzenleyebilirim?

  3. sömek dedi ki:

    kolay gelsin hocam acil yardımınıza ihtiyacım var dht11 sensörürnün pic için yaptıgınız yazılımı buldum ve16f870 göre ayarladım asılda tek yaptğım şey sensörün data ucunu rb0 dan ra0a almak ama çalışmadı düzeltip tekrar r0a bağladım yine çalışma yardımcı olursanız çok sevinirim

    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;

    //DHT11 DEFINITONS
    sbit DHT11_Pin at RA0_bit;
    sbit DHT11_DIR at TRISA0_bit;
    extern unsigned int DHT11_TMP;
    extern unsigned int DHT11_HUM;
    extern char DHT11_CHKSM;
    //END OF DHT11 DEFINITONS

    long veri;
    int isi,nem;
    char bekleme=0;
    char txt[7];

    //////////////////////////////////////////////

    void main() {
    ADCON1=0x0f;
    TRISB=1;
    PORTB=1;
    TRISA=1;
    PORTA=0;
    lcd_init();
    DHT11_init();
    Lcd_Cmd(_LCD_CURSOR_OFF);
    Lcd_Cmd(_LCD_CLEAR);
    lcd_out(1,1,”SICAKLIK=”);
    Lcd_Out(2,1,”NEM=%”);
    delay_ms(500);

    while(1)
    {
    Dht11_Start();
    DHT11_Read();

    if(DHT11_CHKSM==((DHT11_TMP>>8)+(DHT11_HUM>>8)+(DHT11_TMP&0xff)+(DHT11_HUM&0xff)))
    {
    inttostr(DHT11_TMP>>8,txt);
    lcd_out(1,10,txt);
    inttostr(DHT11_HUM>>8,txt);
    lcd_out(2,6,txt);
    }
    }
    }

    sıcaklı ve nem degerleri sabit 0 gösteriyor

  4. sömek dedi ki:

    Ayarladım hocam sensörü okuduğum pini giriş olarak tanımladım. kaç saattır yapmaya çalışıyorum yok kafama takılan bi kaç soru var 1.si işlemciyi hızı olarak kaç mhzlik kristal kullanıcaz bide bu devre kesin olarak denenmiş midir hocam yardımcı olun yapayım şunu

    • mikrodunya dedi ki:

      Devreyi denemesem buraya koymazdim. Kac mhz kullanacaginiz size kalmis. Ben sadece kodlari verdim. Ayni mcuyu kullanirsaniz sikinti olmaz.

  5. sömek dedi ki:

    hocam cevap yazdığınız için teşekkür ederim hallettim 8 mhz takınca çalıştı şimdi değerlerin virgülden sonra ki kısımları için uğraşıyorum siz yapmamışsınız 🙂

    • mikrodunya dedi ki:

      Evet. Kutuphanemde ondalik kisimlarin da aliniyor olmasina ragmen ornek programda ondalik kisimlari gostermedim. Az bir tecrubeye sahip bir yazilimcinin ondalik kisimlari gostermesi isten bile degil.

Yorum bırakın