我一共有三個溫度感測元件,分別是DHT11 (可測溫度跟濕度)、LM35及 DB18B20。如果在同一地點測這三個元件的溫度,不知測得的溫度會一樣嗎?如果跟家裡有顯示溫度量測的時鐘或溫濕度計比較,不知哪個比較準?
以下是我們家有溫度顯示的時鐘、溫濕度計及三個元件讀取數值的照片。我們來看一下比較的結果如何?
在 loop() 中,從LM35讀取數值開始,然後將該讀數除以 9.31。除以 9.31的原因是類比讀數範圍為1024,參考電壓設定為1.1V,計算每一刻度的電壓值為 1.1/1024 = 0.001074V,即1.0742毫V。
LM35的技術規格中提到壓差每10毫V為1攝氏度,若將 10毫V / 1.0742毫V = 9.31,亦即將LM35 讀取的數值除以9.31,就是我們要的攝氏溫度讀數。
LM35有多種不同封裝型式。在常溫下,LM35 不需要額外的校準處理即可達到 ±1/4℃的準確率。靈敏度:10mV/℃,精度:0.5℃ (在+25℃時),測量溫度範圍:0℃ ~ 100℃。
白色溫濕度計:22.8 ~ 23.0 度
指針式溫濕度計:大約 23度
DHT11、LM35及DB18B20執行結果畫面如下:
由以上結果可以得到以下結論:
以下是我們家有溫度顯示的時鐘、溫濕度計及三個元件讀取數值的照片。我們來看一下比較的結果如何?
[材料]
- Arduino Uno x 1
- DS18B20 IC x1
- TM35 IC x1
- DHT11 x1
- 4.7K 電阻 x1
- 麵包板 x1
- 連接線 x n條
- 不同廠牌時鐘或溫濕度計 x3個
[接線圖]
本次檢測的主角照片:最左邊為DHT11、中間為LM35,最右邊為 DB18B20。
[LM35]
在執行程式時,我們使用 analogReference() INTERNAL的方法,來設定 Arduino 的參考電壓 (即用作輸入範圍最高的值)。使用這個設定的原因是 LM35只產生 0 到+ 1V的電壓,而將參考電壓設置為INTERNAL會將其設置為1.1V,也顯著提高了精確度。在 loop() 中,從LM35讀取數值開始,然後將該讀數除以 9.31。除以 9.31的原因是類比讀數範圍為1024,參考電壓設定為1.1V,計算每一刻度的電壓值為 1.1/1024 = 0.001074V,即1.0742毫V。
LM35的技術規格中提到壓差每10毫V為1攝氏度,若將 10毫V / 1.0742毫V = 9.31,亦即將LM35 讀取的數值除以9.31,就是我們要的攝氏溫度讀數。
LM35有多種不同封裝型式。在常溫下,LM35 不需要額外的校準處理即可達到 ±1/4℃的準確率。靈敏度:10mV/℃,精度:0.5℃ (在+25℃時),測量溫度範圍:0℃ ~ 100℃。
[程式]
註:程式參考Onewire DS18x20 範例進行修改,加入LM35及DHT11測得的結果。#include <onewire.h> #include <dht11.h> int DHTPin=5; float DHT11temp, DHT11humi, LM35temp; int LM35Pin = 0; int reading; DHT11 dht11(DHTPin); // Pin 4 連接 DS18B20 (4.7K resistor is necessary) OneWire ds(4); void setup(void) { Serial.begin(9600); analogReference(INTERNAL); Serial.println("DHT11 LM35 DS18B20 "); Serial.println("================================"); } void loop(void) { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float DS18B20temp, fahrenheit; if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; } ds.reset(); ds.select(addr); // 開始轉換 ds.write(0x44, 1); delay(1000); present = ds.reset(); ds.select(addr); ds.write(0xBE); // 需要9個位元 for ( i = 0; i < 9; i++) { data[i] = ds.read(); } // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { // 預設 9 bit 解析度 raw = raw << 3; if (data[7] == 0x10) { // "count remain" 有完整的12 bit 解析度 raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // 在低解析度時,low bits沒有定義,因此設定為0 // 9 bit 解析度, 93.75 ms if (cfg == 0x00) raw = raw & ~7; // 10 bit 解析度, 187.5 ms else if (cfg == 0x20) raw = raw & ~3; // 11 bit 解析度, 375 ms else if (cfg == 0x40) raw = raw & ~1; // 預設為12 bit 解析度, 750 ms conversion time } DS18B20temp = (float)raw / 16.0; // DHT11 int chk = dht11.read(DHT11humi, DHT11temp); Serial.print(DHT11temp, 2); Serial.print(" C "); //LM35 reading = analogRead(LM35Pin); LM35temp = reading / 9.31; Serial.print(LM35temp); Serial.print(" C "); // DS18B20 Serial.print(DS18B20temp); Serial.println(" C "); }
[執行結果]
紅色鬧鐘:維持在 23.9 - 24.0度白色溫濕度計:22.8 ~ 23.0 度
指針式溫濕度計:大約 23度
DHT11、LM35及DB18B20執行結果畫面如下:
由以上結果可以得到以下結論:
- 沒有傳統水銀式的溫度計做比較,無法得知傳統溫度計跟數位溫度計的比較。
- 白色溫濕度計跟指針式的結果比較接近。但與其他四個數值差異較大,無法得知其採用的晶片,就將該值當作參考。
- 看一下DHT11的規格表,溫度測量精度:±2℃、濕度測量精度:±5%RH、溫濕靈敏度:1℃ / 1%RH,從程式測得的結果,無法精確到小數點1至2位數。
- LM35從類比訊號取得溫度值,經過 analogReference() 換算後,提高溫度的精確度,結果跟DS18B20差不多,因為是類比數值換算,不會像DS18B20幾乎是固定的溫度值。
- DS18B20 測溫度穩且精確度高。
[參考資料]
- DHT11 library:Arduino Playground
- LM35:Arduino Playground
- PJRC:OneWire Library & DS18x20 Temperature Example
您好,我想要在魚缸做一個 溫度檢測利用手機遠端監控,控制溫度 ,請問建議哪個溫度感測器較好?
回覆刪除您好,可以用防水型的 DS18B20,可以看一下拍賣網站上產品的介紹,https://goods.ruten.com.tw/item/show?21538702351401 。
刪除張貼留言