جستجو
برای جستجو متن مورد نظر وارد کنید و Enter بزنید برای بستن Esc بزنید.
برای آشنایی با پروتکل One –Wire می خواهیم سنسور DHT21 را بصورت دستی راه اندازی نماییم و نتیجه عملکرد برنامه خود را برای صحت سنجی با کتابخانه DHTLib مقایسه نماییم و مقادیر رطوبت و دما کتابخانه فوق را با مقادیر تابع خود در پورت سریال نمایش دهیم.
ما از سنسور AM2301 استفاده کرده ایم که داخل خود حاوی سنسور DHT21 است.

بعد از ایجاد شرایط start توسط میکروکنترلر و ارسال ACK از سنسور , سنسور 40 بیت دیتا برای ما ارسال می کند. که 16 بیت اول برای اطلاعات رطوبت و 16 بیت دیگر حاوی اطلاعات دمایی می باشد و همچنین بایت اخر حاوی CheckSum می باشد که می تواند توسط میکروکنترلر برای بررسی و خطایابی استفاده شود.
در حالت عادی باس در وضعیت یک منطقی قرار دارد.مقاومت پول اپ بصورت داخلی درون سنسور Am2301 قرار گرفته است و در صورت اینکه از سنسور DHT21 به تنهایی استفاده می کنید باید یک مقاومت 4.7 کیلو اهم بصورت pull up بر روی خط دیتای ان قرار دهید.
تغذیه کاری از 3.3 تا 5 ولت , اندازه گیری رطوبت از 0 تا 100 درصد و همچنین قابلیت اندازه گیری دما از منفی 40 تا مثبت 80 درجه سانتی گراد از ویژگی های این سنسور می باشد.

در تصویر بالا فرایند ارسال اطلاعات سنسور مشخص شده است.سنسور ابتدا بایت پرارزش (از دو بایت دیتای دما یا رطوبت) و بیت پر ارزش (در هر بایت) را برای ما ارسال می کند.
بررسی برنامه:
#include <dht.h>
فراخوانی کتابخانه سنسور DHT برای بررسی با مقادیر بدست امده توسط تابع ما
dht DHT;
ایجاد شئی از کلاس کتابخانه فوق
#define pin 7
مشخص کردن پایه اردوینو متصل به سنسور.شما می توانید از هر پایه دلخواه استفاده نمایید.
void setup()
{
Serial.begin(9600);
Serial.println("DHT TEST");
راه اندازی پورت سریال با بادریت 9600 و پرینت پیغام دلخواه
pinMode(pin , OUTPUT);
digitalWrite(pin , HIGH);
قرار دادن پایه دیتای سنسور در وضعیت خروجی و یک منطقی
delay(1500);
فرصت زمانی برای پایدار شدن سنسور
}
//0 is ok else is error
uint8_t dhtRead() {
تابع ما در صورت موفقیت خواندن از سنسور مقدار 0 و در صورت هر مشکلی دیگر مقداری غیر از صفر بر می گرداند.
uint8_t data[5] = {0, 0, 0, 0, 0};
ارایه با ظرفیت 5 خانه برای نگه داری 5 بایت دریافتی از سنسور
pinMode(pin , OUTPUT);
digitalWrite(pin , LOW);
ایجاد سیگنال ریست برای فرایند start توسط میکروکنترلر
delay(18);
حداقل زمان ریست نگه داشتن باس طبق دیتاشیت 1 میلی ثانیه و حداکثر 20 میلی ثانیه ذکر شده است.
digitalWrite(pin , HIGH);
یک کردن باس توسط میکروکنترلر
pinMode(pin , INPUT);
و قرار دادن پایه میکروکنترلر در حالت ورودی برای خواندن از سنسور(در اینجا چون فقط سنسور دیتا می فرستد باید پایه ما در حالت ورودی قرار بگیرد).در این حالت باس توسط مقاومت pull up در حالت یک منطقی قرار می گیرد تا وقتی سنسور به ما پاسخ دهد.(باس صفر شود)
while (digitalRead(pin) == HIGH);
انتظار تا وقتی باس در حالت یک منطقی است .منتظر می مانیم تا سنسور با صفر کردن باس به سیگنال ریست ما پاسخ دهد.
while (digitalRead(pin) == LOW);
سنسور باس را صفر کرد (به سیگنال ریست پاسخ داد.) و منتظر می مانیم تا سنسور این وضعیت را رها کند.
for (uint8_t pos = 0; pos < 5; pos++) {
منتظر برای دریافت 5 بایت توسط حلقه for
uint8_t shift = 128;
چون سنسور ابتدا بیت پر ارزش را می فرستند مقدار متغییر shift روی عدد 128 قرار گرفته است تا ابتدا بتوانیم با بیت پر ارزش در بایت خود کار کنیم.
for (uint8_t x = 0; x < 8; x++) {
حلقه for برای دریافت 8 بیت (بایت مورد نظر)
روش سنسور به این صورت است که به ازای هر بیت یک سیگنال حاوی صفر منطقی و یک منطقی می فرستد.میزان سطح صفر منطقی توسط سنسور ثابت بوده و کمتر بودن سطح یک منطقی نسبت به سطح صفر منطقی بیانگر بیت صفر و در صورت بیشتر بودن بیانگر یک منطقی می باشد.
بنابراین ما با شمارش مدت زمان صفر و یک قرار گرفتن پایه ورودی می توانیم به وضعیت بیت ارسالی پی ببریم
uint32_t zero = 0;
while (digitalRead(pin) == HIGH);
منتظر تا وقتی باس در حالت pull up قرار گرفته است
while (digitalRead(pin) == LOW) {
شروع بیت همیشه با سطح صفر منطقی می باشد.
zero++;
شمارش تعداد زمانهای صفر بودن
}
uint32_t counter = 0;
while (digitalRead(pin) == HIGH) {
محاسبه مدت زمان یک بودن سیگنال
counter++;
}
if (counter > zero) { //it is 1
در صورت بیشتر بودن زمان یک به زمان صفر ان بیت یک منطقی حساب شده و ان بیت در بایت مورد نظر توسط متغییر shift یک می شود
data[pos] = data[pos] | shift;
}
shift = shift >> 1;
حرکت shift یک واحد به سمت راست تا در عملیات بعدی به مکان درست بیت در بایت مورد نظر برویم.
}
}
while (digitalRead(pin) == LOW);
منتظر تا وقتی سنسور باس را در وضعیت صفر قرار می دهد.(ایجاد شرایط پایان توسط سنسور)
pinMode(pin , OUTPUT);
digitalWrite(pin , HIGH);
خروجی کردن پایه میکروکنترلر و یک کردن ان برای اماده شده باس در استفاده بعدی.
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
بایت اخر ما data[4] حاوی کد چک سام می باشد.سنسور 4 بایت دیتا (اطلاعات دما و رطوبت) را درون خود جمع کرده و نتیجه جمع را در غالب کد 8 بیتی بنام checksum برای ما می فرستد.و ما نیز با دریافت دیتاها و جمع کردن انها نتیجه جمع را با کد checksum مقایسه می کنیم و در صورت برابری متوجه می شویم که دیتای دریافتی ما توسط نویز یا … خراب نشده و سالم به دست ما رسیده است.
//checksum ok
uint8_t sign = 0;
if((data[2] & 128) != 0){
در صورتی که پر ارزش ترین بیت بایت پرارزش(این بیت , بیت علامت است) اطلاعات دما برابر با یک باشد یعنی دمای اندازه گیری شده زیر صفر است.
sign = 1;
}
و ما متغییر sign را برابر یک می کنیم
data[2] = data[2] & 127;
و بیت علامت (پرارزش ترین بیت) را صفر می کنیم تا تاثیراشتباهی روی مقدار بدست امده در محاسبات نذارد.
uint16_t temp = data[2] << 8;
temp = temp + data[3];
ریختن دو بایت پر ارزش و کم ارزش درون یک متغییر 16 بیتی برای رسیدن به مقدار واحد
uint16_t rh = data[0] << 8;
rh = rh + data[1];
و همین کار را برای رطوبت می کنیم.
float t = temp;
t = t / 10;
با تقسیم مقادیر 16 بیتی بر عدد 10 مقدار دما و رطوبت به درجه سانتی گراد و درصد بدست می اید.
float h = rh;
h = h / 10;
if(sign == 1){
t = t * (-1);
}
اگر قبلا بیت علامت ما یک شد پس مقدار خوانده شده توسط سنسور منفی است و ما نیز مقدار خود را در منفی یک ضرب می کنیم تا به منفی تبدیل شود.
Serial.println("My Read .....");
Serial.print("Temp:");
Serial.println(t);
و نمایش مقادیر روی پورت سریال
Serial.print("RH:");
Serial.println(h);
Serial.println("..........");
}
else {
Serial.println("checksum error");
return 6;
}
return 0;
}
void loop()
{
DHT.read21(pin);
خواندن از سنسور توسط کتابخانه DHTLIB
Serial.println("Lib Read .....");
Serial.print("Temp:");
Serial.println(DHT.temperature);
Serial.print("RH:");
Serial.println(DHT.humidity);
Serial.println("..........");
نمایش مقادیر رطوبت و دمای ان
delay(2000);
Serial.println(dhtRead());
صدا زدن تابع خود برای خواندن دما و رطوبت در خط بالا
delay(2000);
}

در ادامه می توانید فایلهای برنامه و کتابخانه DHTLib را دانلود کنید.