Arduino筆記(9):DHT11溫濕度感應偵測與LCD顯示

[2020/12/19]
有時看到六、七年前的實作,覺得那時還剛初學,很多技術還不太瞭解,都這個實作用的 DHT11 程式庫至今都已改版了,而我當時拍的照片,以現在的解析度來說,有點模糊,打算利用一些時間進行翻修,重做實作外,同時更新相關資料,提供給需要參考的朋友。這是新的實作照片:

[2013/4/13]
昨天從拍賣網站上購買的 RaspBerry pi 終於寄到了,順便買了測量溫濕度的 DHT11 及一個雙通道光耦合繼電器。利用今天空檔時,找了一下這個元件的 Datasheet,也找了一段程式進行測試。

[安裝DHTlib]

本實作需要安裝以下DHT-11的程式庫:
您可以在 Arduino IDE的介面上的「管理程式庫」輸入「DHT」找到這個程式庫。程式庫(Library)安裝方法請參考另一篇文章:  Arduino筆記:安裝 Arduino IDE 程式庫(Library)

[材料]

  • 麵包板 x1
  • Arduino Uno x1
  • DHT11溫濕度感應器 x1
  • 4.7K電阻 x1
  • 連接線 n條

[線路連接與電路圖]

Arduino UnoDHT-11
GNDGND(正面右邊算起第一隻腳)
+5VVCC(正面左邊算起第一隻腳)
D2Data(正面左邊算起第二隻腳)




[程式一]

這個程式的結果直接輸出到串列埠,顯示目前的濕度與溫度。
#include <dht.h>
#define DHT11_PIN  2
dht DHT;

void setup() {
  Serial.begin(115200);
  Serial.println("Type,\tHumidity (%),\tTemperature (C)");
}

void loop() {
  // 讀取資料
  Serial.print("DHT11, \t");
  int chk = DHT.read11(DHT11_PIN);
 
  // 顯示資料
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t\t");
  Serial.println(DHT.temperature, 1);

  delay(2000);
}



[執行結果]

從串列視窗上看到的結果:

這是七、八年前實作時的照片,還是保存下來留作紀念。


如果每次要開Serial Port的視窗,覺得很麻煩,心想如果把測到溫濕度值顯示在LCD上,那就方便多了,只要接上電源,就可以知道現在溫濕度的狀況,於是將線路與程式改寫,分別說明如下。

[材料]

  • Arduino Uno x 1
  • DHT11溫濕度感應器 x1
  • LCD1602液晶顯示器
  • I2C/介面 LCD1602轉接板 PCF8574
  • 麵包板 x1
  • 4.7K電阻 x 1
  • 連接線 n 條 


[程式二]

/*    將DHT11測得的溫濕度顯示在LCD顯示器 */
#include <LiquidCrystal_I2C.h>   // 引用 LiquidCrystal_I2C Library
#include <dht.h>

// 設定 LCD 位址為 0x27,有 16 個字元 2 列
LiquidCrystal_I2C lcd(0x27,16,2);  
int row=0;

#define DHT11_PIN 2
dht DHT;

void setup() {
  Serial.begin(115200);
  Serial.println("Type,\tHumidity (%),\tTemperature (C)");
  lcd.init();           // 初始化 lcd 
  lcd.backlight();      // 設定背板為亮  
}

void loop() {
  // 讀取資料
  Serial.print("DHT11, \t");
  int chk = DHT.read11(DHT11_PIN);
 
  // 顯示資料
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t\t");
  Serial.println(DHT.temperature, 1);
  lcd.clear();       
  lcd.setCursor(0, 0);
  lcd.print("Temp");
  lcd.setCursor(9, 0);
  lcd.print(DHT.temperature);
  lcd.print(" C");
  lcd.setCursor(0, 1);
  lcd.print("Humidity");
  lcd.setCursor(9, 1);
  lcd.print(DHT.humidity);
  lcd.print(" %");

  delay(2000);
}

[實作結果]

這是當時的舊照片。

[參考資料]

42 留言

  1. 大大你好
    不知道你有沒有研究用 flash 接收DHT11的資料
    覺得如果可以把資料接收到flash
    就可以透過FLASH做出很漂亮的介面了
    可是我自己找了很多資料 都還試不出正確抓到DHT11傳送過去的方法
    如果大大有研究過 想請問大大該怎麼把資料傳進FLASH的方法 感謝大大了

    回覆刪除
  2. Jason你好,
    我沒用過Flash的介面,現在還在努力學習Arduino與周邊傳感的控制,我看過網路有這樣的作法,可是文件很少,我抽空研究看看,如果知道怎麼做再與你分享心得。謝謝留言。

    回覆刪除
  3. 大大您好,我試著按程式二的方式去run但是不知為何lcd總是顯示time out error那行,無法正確顯示,我用的是I2C 1602 LCD,他除了電源兩條外另只有兩條信號接線,不知是否在程式方面有那些地方需要稍做修改,煩請您指點迷津,謝謝您

    回覆刪除
    回覆
    1. 您好, 我沒用過I2C 1602 LCD,但我覺得問題應該不是在LCD,有可能是DHT11的元件接線的問題. DHT11有四隻接腳,除了接正負兩隻外,您可以測試一下另外兩隻腳是哪一隻接到Pin 7. 我剛裝好時,印象中也出現過Time Out Error, 後來是換接腳才好的.

      刪除
  4. 作者已經移除這則留言。

    回覆刪除
  5. 大大您好,看著你的程式 加了判斷溫度大於多少啟動電扇少於多少關掉電扇
    int out_pin = 2;
    int val ;
    void setup()
    {
    Serial.begin(9600);
    pinMode(out_pin,OUTPUT);
    digitalWrite(out_pin,LOW);
    }

    loop
    val = analogRead(chk);

    if(val>31)
    digitalWrite(out_pin,HIGH);
    else if (val <=30)
    digitalWrite(out_pin,LOW);
    加了上面這些 跟用繼電器
    可是不知道為甚麼他會一直恆亮 不會暗掉
    請問是打錯了嗎?

    回覆刪除
    回覆
    1. 您好, 回信慢了, 抱歉!! 我看一下你的程式發現val= analogRead(chk);這行不對,chk傳回是否有錯誤發生,不是溫度。如果要讀取溫度,要將DHT11.temperature指定給val值,應該就可以了,您再試看看!!

      刪除
  6. 我用您給的程式和接交結果顯示 time out error
    我使用的是dht-11 3pin 的
    謝謝

    回覆刪除
  7. 你好,不好意思,可以跟你拿有LCD完成的程式嗎?

    回覆刪除
  8. 就是整個完整的,麻煩您了大大

    回覆刪除
    回覆
    1. 您好, 我有好一段時間沒有用Arduino做實驗了,剛好上週去登山,無法回覆。問一下您要的是含有liquidcrystal.h 及 dht11.h 兩個Library的原始碼嗎?

      刪除
  9. 作者已經移除這則留言。

    回覆刪除
  10. 作者已經移除這則留言。

    回覆刪除
  11. 請問一下 程式2是可用的嗎

    回覆刪除
  12. 請問可變電阻是用多少k的

    回覆刪除
  13. 請問一下 我照樓主的程式 還是有錯誤ㄟ
    int chk = DHT11.read(DHT11PIN); //檢查DHT感測器的回應
    他一直顯示我的這行 不在範圍內 不知道樓主能不能解決

    回覆刪除
    回覆
    1. 看看宣告的地方 是否跟函示庫的名稱一樣

      刪除
  14. 編譯時出現
    do not name a type...

    這如何修正??

    回覆刪除
  15. 作者已經移除這則留言。

    回覆刪除
  16. DHT11PIN 7 //定義讀取資料的 Pin腳 ..
    但是圖面上卻接在pin 2??

    回覆刪除
  17. 作者已經移除這則留言。

    回覆刪除
  18. 您好 方便與您聯絡嗎 我需要溫濕度感測器控制風扇 謝謝

    回覆刪除
  19. 您好 方便與您聯絡嗎 我需要溫濕度感測器控制風扇 謝謝

    回覆刪除
  20. 請問,為什麼會出現C:\Users\Sam\Documents\Arduino\sketch_jul30b\sketch_jul30b.ino:1:19: fatal error: dht11.h: No such file or directory

    compilation terminated.

    exit status 1
    Error compiling for board Arduino/Genuino Uno.

    小弟我是剛接觸arduino,找不到方法解決qq

    回覆刪除
  21. #include
    #include "DHT.h"
    #define HUMTEMP_PIN 2
    #define LED_PIN 8
    DHT dht(HUMTEMP_PIN, DHT11);

    SoftwareSerial BTSerial(4, 5);

    int intRec,temp,humi;
    const int pingPin =9;
    long duration;
    float cm;

    void setup()
    {
    Serial.begin(9600);
    BTSerial.begin(9600);
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN,HIGH);
    Serial.println("Receive Bluetooth Data....");
    Serial.println("Sending Temperature/Humidity Data...... ");
    }

    void loop() {
    temp=((float)dht.readTemperature());
    humi=((float)dht.readHumidity());
    String strTempHum;
    String strD = ",";
    strTempHum = temp + strD + humi;
    Serial.println(strTempHum);
    BTSerial.print(strTempHum);
    delay(1000);
    if (BTSerial.available())
    {
    intRec = BTSerial.read();
    Serial.print("Rec =");
    Serial.println(intRec);
    if (intRec == 0)
    digitalWrite(LED_PIN, LOW);
    if (intRec == 1)
    digitalWrite(LED_PIN, HIGH);
    }
    delay(500);
    {
    pinMode(pingPin, OUTPUT);
    digitalWrite(pingPin,LOW);
    delayMicroseconds(2);
    digitalWrite(pingPin,HIGH);
    delayMicroseconds(5);
    digitalWrite(pingPin,LOW);

    pinMode(pingPin, INPUT);
    duration =pulseIn(pingPin,HIGH);

    cm = microsecondsToInches(duration);
    String strTemp = "Distance:" + String(cm,2);
    Serial.println(strTemp);
    delay(100);
    }
    float microsecondsToInches(long microseconds) {
    return microseconds / 29 / 2;
    }
    }
    不好意思
    剛接觸arduino,不太會用可以幫我看看我錯在哪邊嗎?(謝謝)

    回覆刪除
  22. 請教雙通道光耦合繼電器
    有光耦合與沒有光偶和差別在哪呢?

    回覆刪除
    回覆
    1. 光電耦合器比起早期電磁感應繼電器,有下列優點:
      .壽命較長—因為無機械磨損
      .較高的切換頻率,因為光電耦合器具有較短的開關時間
      .抗震動
      .無實體機械接點
      .開關時無噪音
      .驅動電源消耗較小

      至於如何使用光來啟動或作為傳遞訊號,可參考維基百科說明:https://zh.wikipedia.org/wiki/%E5%85%89%E9%9B%BB%E8%80%A6%E5%90%88%E5%85%83%E4%BB%B6

      刪除
    2. 感謝大大的回覆

      先前我買了光電耦合繼電器,結果按照正常的接法(如電磁感應繼電器接法),結果都無法正常運作
      換成電磁繼電器就OK了

      光看外表光電耦合與電磁繼電器長的幾乎一樣,對外線路連接的介面也一樣,
      請問,這可能是甚麼問題呢?

      刪除
    3. 我第一個直覺就是有可能這個光電耦合繼電器壞了,兩種繼電器接法應該類似,看看是否能借另一個試試?

      刪除
  23. 不好意思請問要怎麼把電池電壓顯示在LCD上面

    回覆刪除
    回覆
    1. 需要有一個測量電壓的模組, 拍賣網站上很容易找到的. 有這個模組後, 將測得的值比照溫度的值於顯示器上顯示即可.

      刪除
  24. 我沒有用DHT11而是用土壤溼度計 YL 69加上ARDUINO偵測土壤濕度
    如何把3個土壤濕度感測器接收值傳到LCD顯示器上
    能幫我解答加上LCD顯示器上程式的部分~或是建議嗎??
    以下是我的程式
    int wet_levela;
    const int sensorPina= A0;
    const int LEDPina= 13;
    int wet_levelb;
    const int sensorPinb= A1;
    const int LEDPinb= 12;
    int wet_levelc;
    const int sensorPinc= A2;
    const int LEDPinc= 11;

    void setup() {
    Serial.begin(9600);
    pinMode(sensorPina, INPUT);
    pinMode(LEDPina, OUTPUT);

    pinMode(sensorPinb, INPUT);
    pinMode(LEDPinb, OUTPUT);

    pinMode(sensorPinc, INPUT);
    pinMode(LEDPinc, OUTPUT);
    }
    void loop() {
    wet_levela= analogRead(sensorPina);
    wet_levelb= analogRead(sensorPinb);
    wet_levelc= analogRead(sensorPinc);

    if (sensorPina >0){
    if(wet_levela > 750){
    digitalWrite(LEDPina, HIGH);
    }
    else{
    digitalWrite(LEDPina, LOW);
    }
    }

    if (sensorPinb >0){
    if(wet_levelb > 750){
    digitalWrite(LEDPinb, HIGH);
    }
    else{
    digitalWrite(LEDPinb, LOW);
    }
    }

    if (sensorPinc >0){
    if(wet_levelc > 750){
    digitalWrite(LEDPinc, HIGH);
    }
    else{
    digitalWrite(LEDPinc, LOW);
    }
    }

    Serial.println(wet_levela);
    Serial.println(wet_levelb);
    Serial.println(wet_levelc);
    delay(2000);

    }

    回覆刪除
    回覆
    1. 上述程式跟LCD有關的是以下幾行:
      要先用include載入函式庫,再用LiquidCrystal定義顯示器 ,再用lcd.print 顯示即可。

      #include //使用LiquidCrystal Library
      LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //初始設定LCD顯示器的介面

      lcd.print("Humidity:");
      lcd.print((float)DHT11.humidity, 1);
      lcd.print("%");
      .....

      刪除
    2. 上述 include後的角刮號內的文字無法顯示,請看Blog本文的程式。

      刪除
  25. 你好 我在做專題溫控風扇
    可是我用你的程式碼 都顯示compilation terminated.
    編譯時發生錯誤耶 這是我的版本問題嗎?

    回覆刪除
    回覆
    1. 你好, compilation terminated. 之前有一些錯誤訊息,是No such file or directory 嗎?還是可以將其他錯誤貼上來,比較好判斷問題。通常是沒有安裝Library,如果是的話,先安裝函式庫進來,再進行編譯試看看。

      刪除
  26. 作者已經移除這則留言。

    回覆刪除
  27. 你好 我試過加入函式庫(LiquidCrystal_I2C和DHT11和Wire) 也是顯示compilation terminated.
    編譯時發生錯誤
    我要在加入高於溫度 就會做動風扇得話 是可以參考上面有人留言那篇嗎
    我參考課本改了一下 下面這樣行得通嗎 還沒加入作動風扇

    #include
    #include
    #define Addr 0x27
    LiquidCrystal_I2C LCD(Addr,16,2);
    #include
    DHT11 dht(4);
    float humi,temp;
    float Fahrenheit;
    float Kelvin;
    int ERR;

    void setup(){
    Serial.begin(9600);
    }

    void loop(){
    dht.read(humi,temp);
    Serial.print(" Humidity: ");
    Serial.println(humi);
    Serial.print("Temperature ");
    Serial.println(temp);
    LCD.home();
    LCD.print("Humidity:");
    LCD.print(humi);
    LCD.setCursor(0,1);
    LCD.print("Tempera:");
    LCD.print(temp);
    delay(10000);
    }

    回覆刪除
  28. 程式執行後發生錯誤,dht11.h標頭檔資料庫該在何處下載?
    sketch_jan06a:4:10: error: dht11.h: No such file or directory

    #include //使用DHT11 Library

    ^~~~~~~~~

    compilation terminated.

    #include //使用DHT11 Library

    ^~~~~~~~~

    compilation terminated.

    "LiquidCrystal.h"找到多個程式庫
    已使用: C:\Program
    exit status 1
    dht11.h: No such file or directory

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.
    +

    回覆刪除
    回覆
    1. 您好, 過了這麼久,我也忘了當時在哪裡下載 DHT-11,我再找時間實做一下並更新本篇內容。先回覆您的問題,我找一下網路上可使用的 DHT11函式庫,可到 https://github.com/adidax/dht11 下載。下載的壓縮檔,如何安裝到 Library,可參考我的文章:https://atceiling.blogspot.com/2019/09/arduino-arduino-ide-library.html。

      刪除

張貼留言

較新的 較舊