2016年1月22日 星期五

grove dht sensor (溫度..濕度)



雖然說對這顆sensor 已經很熟...不過這次買的starter kit 裡面有...也就順便study一下

原理和protocol 都和以前一樣...只是它包好了一個function...你可以直接呼叫去讀值

直接看sample code
# module_type:
#             DHT11 0
#             DHT22 1
#             DHT21 2
#             DHT2301 3


[ temp,hum ] = dht(dht_sensor_port,0)  #Get the temperature and Humidity from the DHT sensor

其實就一行code....

dht(port_num, module_type)

module  的數值有四種.....由於我們的是DHT11 ....所以填0...

然後直接就把   溫度和濕度放在變數  temp 和 hum...很方便吧.....

當然我們還是來看看它是怎麼實做出來的....

整個 source code在Reference 2可以看到

// pull the pin high and wait 250 milliseconds
digitalWrite(_pin, HIGH);
delay(250);

一開始....先把  GPIO 拉High 維持 250ms

data[0] = data[1] = data[2] = data[3] = data[4] = 0;

先把data[0] 到 data[4] 初始化

// now pull it low for ~20 milliseconds
pinMode(_pin, OUTPUT);
digitalWrite(_pin, LOW);
delay(20);
digitalWrite(_pin, HIGH);
delayMicroseconds(40);
pinMode(_pin, INPUT);

然後再拉Low ....維持 20 ms

然後再拉High....維持 40  us.....

接下來把pin改成input mode...

define MAXTIMINGS 85


for ( i=0; i< MAXTIMINGS; i++) {
counter = 0;
while (digitalRead(_pin) == laststate) {
counter++;
delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = digitalRead(_pin);
if (counter == 255) break;
// ignore first 3 transitions
if ((i >= 4) && (i%2 == 0)) {
// shove each bit into the storage bytes
data[j/8] <<= 1;
if (counter > _count)
data[j/8] |= 1;
j++;
}
}

他用一個for loop.....  最多跑85次

接下用一個 while loop...一直去check 現在讀到的value和之前讀到的value有沒有一樣
如果有一樣...就去睡覺1us....讓cpu可以去做其他事情
這個while loop會check到現在讀出來的level和上次是不一樣的
counter紀錄這段時間有多久...單位us

他這邊有個check error的機制就是當時間已經超過 255us...

它就會終止迴圈....然後認為這次的傳輸是失敗的

counter=0
while (digitalRead(_pin) == laststate){
counter++;
delayMicroseconds(1);}

if (counter == 255) break;

接下來就是去check 這次的counter有多久...

如果counter大於 _count....就為這次的傳輸是傳 '1'
如果counter沒有大於_count...代表這次的傳輸是傳'0'...也就是不需要做任何事

然後由於他是MSB先傳....所以要做bit 的shift....

至於_count是一開始物件初始化的時候會決定 .....datasheet來看...應該是30或是40

然後前四個傳輸不要管....從第5個(i>=4)開始看...而且只看偶數(i%2)......

因為我們觸發的條件是edge...但是一次傳輸有兩個edge...

但我有點搞不懂是...為什麼前四個傳輸不看

if ((i >= 4) && (i%2 == 0)) {
data[j/8] <<= 1;
if (counter > _count)
data[j/8] |= 1;
j++;}



最後再check CRC
// check we read 40 bits and that the checksum matches
if ((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
return true; }

check CRC的方式也和之前一樣....

大體上來說和之前實作的dht11一樣....




Reference 1 : http://www.seeedstudio.com/wiki/Grove_-_Temperature_and_Humidity_Sensor

Reference 2 : https://github.com/Seeed-Studio/Grove_Temperature_And_Humidity_Sensor/blob/master/DHT.cpp

沒有留言:

張貼留言