2020年9月22日 星期二

六、6-4 溫溼度感測器(DHT11/22)實習

 在日常生活中我們在測量周遭的溫度時也常會連濕度一起測量而在Arduino的世界中有一款名為DHT系列的感測器就同時具有量測溫度與濕度的能力只是溫度量測的範圍與精確度沒有前面介紹那兩種那麼好而已

接著就讓我們看一下這個DHT系列的感測器的種類及特性


圖六、6-4_1  DHT11/22數位式溫/濕度感測器特性與規格比較


在DHT的家族系列中共有DHT11/21/22三個成員不過常用的是上面【圖六、6-4_1】中的DHT11/22兩種其中的DHT22的性能與精確度比較好但是與DHT11的價格也差距較大一般如果不是太要求準確度的地方或者只是要練習一下DHT11還是可以湊合著用在本範例中就是以DHT11為測試標的如果要改用DHT22那麼我們的範例程式只要稍作修改就可以適用了

從【圖六、6-4_1】所列的特性與規格中可知DHT11的溫度測量範圍是0~50C而誤差為+/-2C至於濕度的測量範圍是0~80%誤差為+/-5%看起來就不是很準;不過由於人類對溫度與濕度的感覺並不是很靈敏所以在一般的室內環境應該還算夠用。由於受限於所使用的感測器材料再加上濕度本來就不可能變化得很劇烈所以DHT11量測的速度最快一秒中只能一次在實際使用時建議2秒鐘測量一次會比較可靠。

下面的【圖六、6-4_2】左邊是DHT11的外觀與接腳它對外有4根接腳但其中有一隻是空接腳(Pin 3);由於他對外只有一支介面接腳(DATA)所以和DS18B20一樣在實際使用時必須在外面加上一個接到VCC的提升電阻。在Arduino的世界中當然也有許多廠商把它做成可直接使用的擴充模組由於沒有一定的標準所以各做各的結果就是對外的接腳排列很亂在【圖六、6-4_2】中間與右邊的模組板就是不同廠商所製造的產品很明顯看的出來兩者的腳位完全相反因此讀者在使用時一定要看清楚到底接腳的名稱與排列為何﹖否則無法正常動作還事小把零件都燒了就麻煩了!

圖六、6-4_2  DHT11數位式溫/濕度感測器及模組外觀接腳


功能與動作說明

1、以ESP8266建立一無線WiFi AP存取點(即Soft—AP模式),這個AP存取點的SSID名稱為『ESP_softAP01』,而且不使用連線密碼。

2、此AP存取點內建伺服器的IP位址為:[ 192.168.4.1 ]

3、當有客戶端(Client手機、平板或筆電)裝置以瀏覽器連線上此伺服器時,會將接在模組板上的DHT11數位式溫/濕度感測器所量測到的溫度與濕度訊息回傳給連線客戶端顯示在瀏覽器的螢幕上。

4如果客戶端裝置持續的連線則系統會以固定的時間(在此為3秒)重新測量溫度感測器所量測到的溫/濕度值並主動傳送給客戶端裝置


圖六、6-4_3  DHT11數位式溫/濕度感測器客戶端瀏覽器連線後預期畫面


  上面的【圖六、6-4_3】是本範例程式在客戶端瀏覽器連線後預期出現的畫面,和前面幾個範例都很類似,差別只在標記1實習名稱的提示訊息部分改成了『DHT11數位式溫/濕度測量實習』而已。而標記2的內容則是DHT11數位式溫/濕度感測器所量測到的溫度與濕度的結果為了方便使用者閱讀所以同時以中英文的方式呈現出來;在此還是加上了一個量測次數計數器(Count)好讓使用者可以得知目前已經量測過多少次了。


電路圖

圖六、6-4_4 數位式DHT11溫/濕度感測器測量電路


在【圖六、6-4_4】的電路中,DHT11的正電源腳接在ESP8266模組板的5V電源上(在NodeMCU模組上為Vin腳);因為DHT11的資料介面腳(Data)具有雙向性,可以同時並接許多個元件,只是在使用時必須在外面並接上一個共用的提升電阻,一般這個電阻的大小以4.7K為宜。基本上這支資料介面腳只要接在ESP8266上具有雙向的數位腳即可不過GPIO15這隻腳在開機時如果有信號出現在上面的話會造成開機啟動失敗因此在此就比照目前市面上常可看到的ESP-01/DHT11模組(【圖六、6-4_5】)的方式還是接在GPIO02這隻腳上這樣當DHT11在傳輸料時便可看見那顆內建在ESP8266模組上的LED在閃爍。

圖六、6-4_5 ESP-01/DHT11模組外觀圖


程式列表與說明

 

  1. #include <ESP8266WiFi.h>

  2. #include "index.h"

  3. #include "DHT.h"

  4.  

  5. #define DHTPIN  2

  6. #define DHTTYPE DHT11

  7. //#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

  8. DHT dht(DHTPIN,DHTTYPE);

  9.  

  10. String softSsid = "ESP_softAP01";

  11. //String softSsid = "ESP"+String(ESP.getChipId());

  12. const char* softPassword = "12345678";

  13.  

  14. WiFiServer server(80);

  15.  

  16. String tmpString = "";    // html網頁程式字串變數

  17. unsigned int count = 0;   // 測輛次數值

  18. int rTime=3;              // 網頁更新時間

  19.  

  20.   // 初始化程式區setup()開始 :

  21. void setup() 

  22. {

  23.     Serial.begin(115200);

  24.     Serial.println();

  25.  

  26.   Serial.println("Setting soft-AP Mode... ");

  27.  

  28.   boolean result=WiFi.softAP(softSsid);

  29.   if(result==true)

  30.   {

  31.     Serial.println("soft-AP ready!");

  32.     Serial.print("softAP = ");

  33.     Serial.println(softSsid);

  34.     Serial.print("softIP = ");

  35.     Serial.println(WiFi.softAPIP());

  36.   server.begin();

  37.   }  

  38.   else

  39.     Serial.println("soft-AP failed"); 

  40.   dht.begin();

  41.  

  42. } // setup()結束

  43.  

  44. // 主迴圈 loop()開始 :

  45. void loop() 

  46. {

  47.     // Check if a client has connected

  48.     WiFiClient client = server.available();

  49.     if (!client)    

  50.       return;  

  51.   count++;

  52.     tmpString = MAIN_page;    // 取出html網頁回應程式

  53.     tmpString.replace("%rTime%", String(rTime) ); // 帶入測量的時間值到網頁html程式中

  54.  

  55.   float h=dht.readHumidity();

  56.   float t=dht.readTemperature();

  57.   Serial.print("Humidity = ");

  58.   Serial.print(h);

  59.   Serial.print("%\t");

  60.   Serial.print("Temperature = ");

  61.   Serial.print(t);

  62.   Serial.println("*C");

  63.     tmpString.replace("%temper%", String(t) );    // 帶入測量的溫度值到網頁html程式中

  64.     tmpString.replace("%humidity%", String(h) );  // 帶入測量的溼度值

  65.     tmpString.replace("%count%", String(count) ); // 帶入測量次數

  66.  

  67.     client.flush();

  68.     client.print( tmpString );

  69.       

  70.     delay(5);

  71. } // loop() 結束

  72.  

  73. const char MAIN_page[] PROGMEM = R"=====(

  74. HTTP/1.1 200 OK

  75. Content-Type:text/html

  76. Connection: close

  77.  

  78. <!DOCTYPE html>

  79. <html>

  80.  <head>

  81.  <meta name='viewport' content='width=device-width, initial-scale=1.0'/>

  82.  <meta charset='utf-8'>

  83.  <meta http-equiv='refresh' content='%rTime%'>

  84.  <style>

  85.    body {font-size:100%;} 

  86.    #main {display: table; margin: auto;  padding: 0 10px 0 10px; } 

  87.  </style>

  88.    <title>Soft AP模式-DHT11溫/濕度測量</title>

  89.  </head>

  90.  

  91.  <body> 

  92.    <div id='main'>

  93.      <h2><center>[Soft AP模式] <br>

  94.          DHT11溫/濕度測量實習<br></center><br>

  95.        溫度 =  %temper% 'C<br>

  96.        濕度 =  %humidity% %<br>

  97.        Temperature =  %temper% 'C<br>

  98.        Humidity =  %humidity% %<br>

  99.       Count = %count%<br>

  100.       </h2>

  101.    </div> 

  102.  </body>

  103. </html>

  104. )=====";



程式名稱:ESP_CH6_6_4_DHT11.ino


由於DHT11在Arduino中並不是標準的內建元件所以必須另外加裝相關的函示庫之後才能引用下面程式中第3行是使用DHT11時必須因引用到的函式庫(即”DHT.h”)而第5行則是宣告DHT11的Dada腳使用的腳位在此為GPIO2。至於第6行是定義程式所使用的DHT系列種類如果要改用DHT22只要把這行註解掉然後取消第7行的註解即可!至於第8行則是宣告程式中DHT11所使用的物件變數名稱(即”dht”)


3. #include "DHT.h"

4.

5. #define DHTPIN  2

6. #define DHTTYPE DHT11

7. //#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

8. DHT dht(DHTPIN,DHTTYPE);


要按裝”DHT.h”這個函示庫請先在Arduino IDE中點選上方的【草稿碼】🡺【匯入程式庫】🡺【管理程式庫】,在看到下面的【圖六、6-4_5】程式庫管理員視窗後在標記1的欄位輸入『dht』搜尋字串便可以找到標記2的目標函式庫然後在標記3的地方選擇所需的版本(一般都會選擇最新的版本)並按下[安裝]鍵便可安裝成功。

圖六、6-4_5 『DHT.h』函式庫安裝畫面


有些較舊版本的Arduino IDE可能還會需要「Adafruit_Sensor.h」這個Adafruit公司所有感測器都必須用到的通用函式庫可以到下列這個網址去下載後再到Arduino IDE中點選上方的【草稿碼】🡺【匯入程式庫】🡺【加入 .ZIP程式庫】後,把下載的函式庫加入Arduino IDE即可。


 “Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor”


本範例程式的初始化程式區(setup())內容和前面幾個幾乎一模一樣差別只在多了下面這行用來初始化DHT11的指令而已


40.   dht.begin();


在主迴圈(loop())程式中一開始是在等待客戶端連線(48~50行),當有客戶端裝置連線之後,便把網頁首頁程式MAIN_page[]傳送到tmpString這個字串變數中同時也把測量的時間值(即'rTime')帶入到網頁html程式中:


52.    tmpString = MAIN_page;    // 取出html網頁回應程式

53.    tmpString.replace("%rTime%", String(rTime) ); 


接著我們用下面這兩行程式分別取讀取DHT11的濕度(h)與溫度(t)轉換值


55.  float h=dht.readHumidity();

56.  float t=dht.readTemperature();


至於57~62行程式會把溫溼度轉換的結果顯示在Arduino IDE的序列監控視窗中,以便我們偵錯之用


63.    tmpString.replace("%temper%", String(t) );    // 帶入測量的溫度值到網頁html程式中

64.    tmpString.replace("%humidity%", String(h) );  // 帶入測量的溼度值

65.    tmpString.replace("%count%", String(count) ); // 帶入測量次數


上面的3行程式會把溫度的轉換結果(t)濕度(h)與量測次數值(count)分別帶入tmpString這個字串變數中的「temper」、「humidity」、「count」3個變數中,最後執行下列程式,便可以把從DHT11的溫/溼度測量結果回應給連線的客戶端瀏覽器。


69.    client.println( tmpString );  


程式列表的74~103行是ESP8266內建伺服器的網頁首頁程式碼,是放在Arduino程式中的「index.h」分頁上,整個html程式的字串變數名稱跟之前一樣命名為「MAIN_page[]」為了能讓客戶端的瀏覽器能更快的自動定時讀取更新的量測結果在行程式中一樣把更新時間加快到3秒鐘不過為了能讓程式更有彈性所以在此是以參數(即'%rTime%')的方式去定義這樣我們在主程式中或者說使用者就可以更方便的去更改系統測量刷新時間了


83. <meta http-equiv='refresh' content='%rTime%'>


【圖六、6-4_3】的中標記1也就是本實習名稱的提示訊息部分事由下面兩行程式完成:


93.     <h2><center>[Soft AP模式] <br>

94.         DHT11溫/濕度測量實習<br></center><br>


而網頁中溫度和濕度顯示的部分則是由下面幾行程式去實現:


95.       溫度 =  %temper% 'C<br>

96.       濕度 =  %humidity% %<br>

97.       Temperature =  %temper% 'C<br>

98.       Humidity =  %humidity% %<br>

99.      Count = %count%<br>

其中的「temper」代表溫度的測量結果而「humidity」則是濕度的置換變數「count」則一樣代表DHT11測量的結果與網頁刷新的次數這三個字串置換變數都是由前面63~65行的程式所傳送過來的。


執行結果:

圖六、6-3_6  使用DHT11的溫/溼度感測器客戶端瀏覽器連線後量測畫面


【圖六、6-3_6】是客戶端瀏覽器與系統連線後系統上DHT11的溫/溼度開始量測的畫面,一般我們周遭溫度改變的速度本來就很慢,至於濕度那就更不用說了!當我們設計了一些感測器電路時,最麻煩的部分就是測試的信號來源如何取得﹖以本範例來說最簡單的方法就是對著DHT11吹氣,這時可以升高量測的濕度與溫度是吹得過程中要注意嘴巴不要太靠近DHT11以免口水噴到了DHT11內部的感測材料造成元件的失常或故障


沒有留言:

張貼留言