☛ 功能說明

使用 Arduino 開發板配合DHT11 溫濕度感測器測量環境溫度、濕度,以 Serial Monitor 視窗顯示環境溫度、濕度,當環境溫度大於等於 30°C 時,點亮 LED。

DHT11 溫濕度感測器是一款含有校準數位信號輸出的溫濕度複合感測器。 它應用專用的數位模組採集技術和溫濕度感測技術,確保產品具有極高的可靠性與卓越的長期穩定性。 感測器包括一個電阻式感濕元件和一個NTC測溫元件並與一個高性能8位元單片機相連接。 因此該產品具有品質卓越、超快回應、抗干擾能力強、性價比極高等優點。

每個 DHT11 感測器都在極為精確的濕度校驗室中進行校準。 校準係數以程式的形式儲存在 OTP 記憶體中,感測器內部在檢測信號的處理過程中要調用這些校準係數。 單線制串行介面使系統集成變得簡易快捷。 超小的體積、極低的功耗,信號傳輸距離可達 20 米以上,使其成為各類應用甚至更為苛刻的應用場合的最佳選擇。

產品為四針單排引腳封裝,連接方便,特殊封裝形式可根據使用者需求提供。

☛ 使用材料

Arduino UNO R3 開發板 × 1、溫度感測模組 DHT11 × 1、電阻 220Ω × 1、LED× 1及 DHT11 第三方函式庫

☛ 電路圖及麵包板接線圖

☛ 程式碼

根據 DHT 動作原理來讀取資料的程式碼如下:

const int dataPin=8;                      // DHT11 數據接腳連接 Arduino 的第八個數位接腳
const int led=7;                          // LED 連接 Arduino 第七個數位接腳
int temperature=-1;
int humidity=-1;

void setup()
{
     Serial.begin(115200);                // 設定串列埠傳輸速率為 115200 bps
     pinMode(led,OUTPUT);
}

int readDHT11()
{
    uint8_t recvBuffer[5];                // 從 DHT11 的數據包共有 5 個字節 ( 40 位 )
    uint8_t cnt=7;
    uint8_t idx=0;

    for(int i=0;i<5;i++)
        recvBuffer[i]=0;                  // 將緩衝區初始化為 0
    pinMode(dataPin,OUTPUT);              // 發送低電平脈衝開始通信
    digitalWrite(dataPin,LOW);
    delay(18);
    digitalWrite(dataPin,HIGH);
    delayMicroseconds(40);                // 等待一段時間,讓 DHT11 發送數據
    pinMode(dataPin,INPUT);
    pulseIn(dataPin,HIGH);                // 接收 DHT11 的回應信號

    unsigned int timeout=10000;           // 循環迭代
    for(int i=0;i<40;i++)                 // 循環地處理40位數據中的每一位數據
    {
        timeout=10000;
        while(digitalRead(dataPin)==LOW)
        {
              if(timeout==0)
                 return -1;
              timeout--;
        }

        unsigned long t=micros();          // 以 ms 為單位的運行時間。 儲存了測量脈衝的持續時間。
        timeout=10000;
        while(digitalRead(dataPin)==HIGH)  // 循環測量脈衝
        {
              if(timeout==0)
                 return -1;
              timeout--;
        }
        if((micros()-t)>40)                //如果脈衝超過 40ms, 那麼該位等於 1, 否則該位保持其初始化的零值。
            recvBuffer[idx]|=(1<<cnt);
        if(cnt==0)                         // 是下一個字節嗎 ?
        {
            cnt=7;                         // 從 MSB 開始
            idx++;                         // 下一個字節
        }
        else
            cnt--;
    }
    
    humidity=recvBuffer[0];                // 濕度位於數據包中的第一個字節
    temperature=recvBuffer[2];             // 溫度位於數據包中的第三個字節
    uint8_t sum=recvBuffer[0]+recvBuffer[2];
    if(recvBuffer[4]!=sum)                 // 校驗和 ( 第五個字節 ) 是溫度與濕度的和
       return -2;
    return 0;
}
void loop()
{
     int ret=readDHT11();
     if(ret!=0)
        Serial.println(ret);
     Serial.print("Humidity: ");
     Serial.print(humidity);
     Serial.println(" %");
     Serial.print("Temperature: ");
     Serial.print(temperature);
     Serial.println(" ℃");
     if(temperature>=30)
        digitalWrite(led,HIGH);
     else
        digitalWrite(led,LOW);
     delay(2000);                          // 延遲2秒
}

使用 DHT 程式庫的程序碼如下:

#include "DHT.h"

DHT dht;                                                         // 產生一個 dht 物件
int led=7;                                                       // LED 連接數位接腳 7

void setup()
{
  Serial.begin(9600);                                            // 設定串列埠傳輸速率為9600bps
  pinMode(led,OUTPUT);                                           // 設定數位接腳 7 為輸出模式
  Serial.println();
  Serial.println("Status\tHumidity (%)\tTemperature (C)\t(F)");

  dht.setup(8);                                                  // DHT11 數據接腳連接數位接腳 8
}

void loop()
{
  delay(dht.getMinimumSamplingPeriod());                        // 根據溫濕度感測器型號來選取取樣時間

  float humidity = dht.getHumidity();                           // 讀取感測器的濕度值
  float temperature = dht.getTemperature();                     // 讀取感測器的溫度值

  if(temperature>=30)
     digitalWrite(led,HIGH);
  else
     digitalWrite(led,LOW);

  Serial.print(dht.getStatusString());
  Serial.print("\t");
  Serial.print(humidity, 1);
  Serial.print("\t\t");
  Serial.print(temperature, 1);
  Serial.print("\t\t");
  Serial.println(dht.toFahrenheit(temperature), 1);
}