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

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


[材料]


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

[接線]

DHT11共有四隻腳,左邊第一隻腳接+5V,第二隻腳接Arduino Pin2,第四隻腳接地,比較特別的是第一、二隻腳還要用一個4.7K的電阻連接,



[程式一]


#include <dht11.h>
dht11 DHT11;  
#define DHT11PIN 7   //定義讀取資料的 Pin腳 
void setup() 
{
  Serial.begin(9600);
}

void loop()  
{
  Serial.println("\n");
  int chk = DHT11.read(DHT11PIN);
  Serial.print("Read sensor: ");
  switch (chk)
  {
    case 0: Serial.println("OK"); break;
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    default: Serial.println("Unknown error"); break;
  }

  Serial.print("Humidity (%): ");
  Serial.println((float)DHT11.humidity, 2);

  Serial.print("Temperature (oC): ");
  Serial.println((float)DHT11.temperature, 2);

  Serial.print("Temperature (oF): ");
  Serial.println(Fahrenheit(DHT11.temperature), 2);

  Serial.print("Temperature (K): ");
  Serial.println(Kelvin(DHT11.temperature), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(dewPoint(DHT11.temperature, DHT11.humidity));

  Serial.print("Dew PointFast (oC): ");
  Serial.println(dewPointFast(DHT11.temperature, DHT11.humidity));

  delay(2000);
}

/*-----( Declare User-written Functions )-----*/
//
// 計算轉換為華式
double Fahrenheit(double celsius)
{
        return 1.8 * celsius + 32;
}

//轉換為蘭式
double Kelvin(double celsius)
{
        return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
        double A0= 373.15/(273.15 + celsius);
        double SUM = -7.90298 * (A0-1);
        SUM += 5.02808 * log10(A0);
        SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
        SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM-3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558-T);
}

// 轉換為露點溫度

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point

double dewPointFast(double celsius, double humidity)
{
        double a = 17.271;
        double b = 237.7;
        double temp = (a * celsius) / (b + celsius) + log(humidity/100);
        double Td = (b * temp) / (a - temp);
        return Td;
}

[執行結果]




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



[材料]

• 麵包板 x 1
• Arduino Uno x 1
• DHT11溫濕度感應器 x1
• HD44780 相容 LCD x 1 (本實驗使用 16 pin 有背光 LCD)
• 旋轉式可變電阻 x 1
• 4.7K電阻 x 1
• 220K電阻 x 1
• 連接線 x N條


[程式二]


/*    將DHT11測得的溫濕度顯示在LCD顯示器 */ 

#include <liquidcrystal.h>    //使用LiquidCrystal Library 
#include <dht11.h>                 //使用DHT11 Library
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  //初始設定LCD顯示器的介面 
dht11 DHT11;     //定義DHT11 物件
#define DHT11PIN 7  //定義讀取資料的 Pin腳 

void setup() {     
   lcd.begin(16, 2);  // 設定LCD有2列16欄  
      Serial.begin(9600);  
} 

void loop() {  
   lcd.setCursor(0, 0); //將游標設定在第一行第一個位置(column 0, line 1)  
   int chk = DHT11.read(DHT11PIN);  //檢查DHT感測器的回應  

      switch (chk) {     
   case 0:       
     lcd.print("Humidity:");       
     lcd.print((float)DHT11.humidity, 1);       
     lcd.print("%");       
     lcd.setCursor(0, 1);       
     lcd.print("Tempure:");       
     lcd.print((float)DHT11.temperature, 1);       
     lcd.print("oC");     // 無法顯示度,只好用小寫的O表示       
           break;     
   case -1:       
     lcd.print("Checksum error"); 
     break;     
   case -2:       
     lcd.print("Time out error"); 
     break;     
   default:       
     lcd.print("Unknown error"); 
     break;   
   }  
   delay(1000); 
} 

[參考資料]

• http://arduino-info.wikispaces.com/DHT11-Humidity-TempSensor
Share on Google Plus

31 意見 :

  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. 我第一個直覺就是有可能這個光電耦合繼電器壞了,兩種繼電器接法應該類似,看看是否能借另一個試試?

      刪除