Semorphe

溫濕度

讀一個有單位、而且會失敗的感測器。 · ⏱ 約 25 分鐘

你會學到三件事

  1. 有些感測器自己會換算,直接給你攝氏度
  2. 讀失敗的時候它給你 NaN,而 NaN 不是 0
  3. 為什麼這顆感測器不能一直讀

開始之前

第 5 課的光敏電阻給你一個 0~1023 的數字,意義要你自己賦予

DHT11 不一樣——它裡面有一顆小晶片,已經幫你換算好了。

接線:DHT11 的資料腳接 2 號腳VCC 接 5V、GND 接 GND。

一、宣告要說兩件事

DHT dht(2, DHT11);
意思
2 接在哪一支腳
DHT11 哪一型——DHT11 和 DHT22 的通訊時序不同

⚠️ 型號寫錯的話讀出來全是失敗,而不會報錯。

dht.begin();      // setup 裡

二、讀

float t = dht.readTemperature();     // 攝氏度
float h = dht.readHumidity();        // 相對濕度 %

⚠️ float 不用 int——溫度是 25.3 這種帶小數的值。 存進 int 會變成 25,而那是無聲的資料遺失(C++ 入門第 2 課那件事)。

三、NaN:讀失敗的樣子

執行看看——如果沒有真的接感測器,你會看到:

NaN
NaN

NaNNot a Number(不是一個數字)。 它是浮點數專用的一個特殊值,意思是「這裡沒有有效的答案」。

NaN 不是 0,而這一點很重要。

如果失敗時回傳 0,那 0 度和「讀失敗」就分不出來了—— 而在冬天那是兩件完全不同的事。

⚠️ NaN 有一個很怪的性質

if (t == t) { ... }      // NaN 的話這是【不成立】的

NaN 不等於自己。這是浮點數標準規定的。

所以判斷讀失敗要用 isnan(t)

if (isnan(t)) {
    Serial.println("讀失敗");
    return;
}

每次讀完都該檢查一次——DHT11 偶爾會失敗,那是正常的。

四、⚠️ 它讀得很慢

DHT11 每 2 秒才能讀一次(DHT22 是 1 秒)。 讀太快的話它回你上一次的舊值,或直接失敗。

delay(2000);

這是感測器的物理限制,不是程式的問題。 有些東西你就是不能一直問它。

(正式的專案裡,這個 delay 應該換成第 10 課的 millis() 寫法。)

完成的樣子

DHT dht(2, DHT11);

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

void loop() {
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    Serial.println(t);
    Serial.println(h);
    delay(2000);
}

換你了

加上 isnan 檢查,讀失敗就印「讀失敗」而不是印 NaN

再進階:接上第 12 課的 LCD,做一個桌上型溫濕度計。

這一課你做了什麼

如果卡住了

你看到 多半是因為
一直是 NaN 沒接感測器、接錯腳,或型號寫錯(DHT11 vs DHT22)
溫度沒有小數 存進 int 了。要用 float
讀得到但值不動 讀太快了。DHT11 要間隔 2 秒
if (t == t) 判不出失敗 NaN 不等於自己也不等於別的。要用 isnan
在編輯器打開這一課 →