2019年12月14日 星期六

Arduino 控制 DHT11 濕度及溫度感應器模組

最近天氣開始轉冷,打算因應天氣,調整室內溫度才開關恆溫裝置,還可以減少電力損耗及電費
(暫時未有能力直接控制恆溫裝置,但可以提醒再手動開關)
又尋找手頭上有沒有一些零件工具能做到目標效果……

若果閣下購買 Arduino Starter Kit ,套件中包含一件 DHT模組
若果閣下購買 Arduino Sensor Kit ,套件中包含一件 KY-015版本DHT模組
Arduino Starter Kit 的 DHT模組 會比較長窄,Arduino Sensor Kit 的 KY-015版本DHT模組 則比較短闊
DHT 全名是 Digital Humidity and Temperature Sensor 是一種數碼濕度及溫度感應器
感應誤差 濕度大約5%正負差 及 溫度大約3度正負差

感應器外觀

見下文
見下文
DHT模組 側面

見下文
DHT模組 背面
背面有引腳通孔,有需要可以焊接額外引腳連接

見下文
見下文
KY-015版本DHT模組 側面

見下文
KY-015版本DHT模組 背面
(KY-015 製作比較參差)

見下文
DHT模組 正面, 3支引腳由左至右分別為
  1. 電源引腳 (+)
  2. 訊號引腳 (out)
  3. 接地引腳 (-)

見下文
KY-015版本DHT模組 正面, 3支引腳由左至右分別為
  1. 訊號引腳 (S)
  2. 電源引腳
  3. 接地引腳 (-)

見下文
DHT模組 及 KY-015版本DHT模組 並排比較

雖然兩種模組的引腳排列有些微分別,但操作上是相同
原本的 DHT 實際有 4支引腳,由左至右分別為
  1. 電源引腳
  2. 訊號引腳
  3. 無效引腳
  4. 接地引腳

引腳用途

編號引腳方向用途
1電源接受 2.0V 至 5.5V
2訊號輸入/輸出發送指令訊號週期 及 接收資料訊號週期
3無效沒有電子功用,輔助零件穩定地安裝在電路板上
4接地

接駁方法

見下文
Arduino 接駁 DHT 的方法

見下文
Arduino 實際接駁 DHT 線路

見下文
Arduino 實際接駁 KY-015版本DHT 線路

見下文
又是在下的懶惰接駁方法,直接將 DHT 引腳接駁到 Arduino 引腳
其中一支引腳為電源引腳、另一支引腳為接地引腳、最後一支引腳為訊號引腳

見下文
見下文
在下將 2個 DHT 都接駁到 Arduino

訊號資料

由於 DHT 只使用一支訊號引腳 發送指令訊號接收資料訊號

引腳發送指令訊號週期ACL接收資料訊號週期完成
延遲20毫秒40微秒不固定時間,但不少於40微秒2秒
SIG高或低

訊號波紋時序圖
SIG

引腳ACL接收位元訊號週期 (共5次)
第7第6第5第4第3第2第1第0
延遲不固定時間,但不少於40微秒
SIG

訊號波紋時序圖
SIG

  1. 設定 SIG引腳 為 輸出,以 發送指令訊號
    1. SIG引腳 發出低電壓訊號
    2. 延遲 20毫秒
    3. SIG引腳 發出高電壓訊號
    4. 延遲 40微秒
  2. 設定 SIG引腳 為 輸入,以 接收資料訊號
    1. ACL
      1. 等待低電壓訊號完結
      2. 等待高電壓訊號完結
    2. 接收 5次 資料訊號週期
      1. 接收 8次 位元 (1位元組) 訊號
        1. 偵測是否低電壓訊號
        2. 偵測是否高電壓訊號
        3. 如果低電壓訊號與高電壓訊號超過 40微秒,讀取位元資料 (由 最高有效位 (MSB) 開始)
  3. 延遲 2秒

資料說明

DHT 傳回的的 5組 8位元 資料分別是
  1. 濕度 (整數位值)
  2. 濕度 (小數位值)
  3. 溫度 (整數位值)
  4. 溫度 (小數位值)
  5. 校對總和前4組數值的總和 並只取 前8位元資料

測試程式

在下的測試程式
byte SIG_PIN = 2;
byte data[5];

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

void loop() {
    updateDHT();
    if (((data[0] + data[1] + data[2] + data[3]) & 0xFF) == data[4]) {
        Serial.println();
        Serial.print("Humidity (%): ");
        Serial.print(data[0]);
        Serial.print(".");
        Serial.print(data[1]);
        Serial.println();
        Serial.print("Temperature (C): ");
        Serial.print(data[2]);
        Serial.print(".");
        Serial.print(data[3]);
        Serial.println();
    }
}

void updateDHT() {
    pinMode(SIG_PIN, OUTPUT);
    digitalWrite(SIG_PIN, LOW);
    delay(20);
    digitalWrite(SIG_PIN, HIGH);
    delayMicroseconds(40);
    pinMode(SIG_PIN, INPUT);
    wait(LOW);
    wait(HIGH);
    const byte LENGTH = sizeof(data) / sizeof(byte);
    for (byte i = 0; i < LENGTH; i++) {
        data[i] = readData();
    }
    delay(2000);
}

byte readData() {
    byte data = 0;
    for (byte i = 0x80; i > 0; i >>= 1) {
        wait(LOW);
        unsigned long microseconds = micros();
        wait(HIGH);
        if ((micros() - microseconds) > 40) {
            data |= i;
        }
    }
    return data;
}

void wait(byte signal) {
    unsigned int retry = 0xFFFF;
    while (digitalRead(SIG_PIN) == signal) {
        if (retry-- == 0) {
            return;
        }
    }
}

總結

濕度及溫度感應器操作上算是比較麻煩
由於只使用一支訊號引腳,需要不斷切換 輸入模式 及 輸出模式 來 發送指令訊號 及 接收資料訊號
而且還需要等待 接收資料訊號 的電壓狀態 來辨識資料訊號,比過往的元件不同
雖然向 DHT 發送指令號訊 操作的延遲時間會固定,但 接收資料資訊 卻不固定
由於讀取訊號的時間並不固定,因此需要使用 迴圈 (Loop) 不斷嘗試偵測訊號變化

在下將濕度及溫度感應器製作成函式庫方便使用
可以到 https://create.arduino.cc/editor/hkgoldenmra/fda824d2-a842-4757-9dc9-9bb68578bf1d/preview
https://bitbucket.org/hkgoldenmra/dhtmodule
或在 Terminal 輸入
git clone "https://bitbucket.org/hkgoldenmra/dhtmodule.git" --depth=1
下載

沒有留言 :

張貼留言