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.
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.
Yukarıda anlattıklarımızı birer başlık altında daha detaylı bir şekilde inceleyelim.
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.
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...
Bu yorum yazar tarafından silindi.
YanıtlaSilmerhaba size nası lulaşa bilirim bir konuda yarmdımınıza ihtiyacım var
YanıtlaSiltelefonum 05324321619
YanıtlaSilBu yorum yazar tarafından silindi.
YanıtlaSilSorun nedir nasıl yardımcı olabilirim
YanıtlaSilarduino ile negatif sıcaklık ölçümü nasıl yapılır
YanıtlaSilMerhaba. Bir sorum var ama cevaplayabilir misiniz?
YanıtlaSil