我一共有三個溫度感測元件,分別是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 。
刪除張貼留言