溫度是我們經常接觸到的物理量,能夠被我們所直觀的感受得到,例如天氣涼了需要增添衣物,吃的食物太燙需要吹一吹,同時也需要對溫度精確的測量,例如人類的正常體溫是37.5℃,一個大氣壓下純水沸騰時的溫度是100℃,都需要我們去做實驗來找出其中的科學。下面我們將詳細講解幾種常用的溫度傳感器,並利用Arduino來實現溫度的測量,包括熱敏電阻、LM35、DS18B20、DHT11和熱電偶。
1.熱敏電阻
1.1 熱敏電阻簡介
熱敏電阻是電阻值隨溫度變化的半導體傳感器,其典型特點是阻值對溫度非常敏感,在不同的溫度下會表現出不同的電阻值,從而根據表現的電阻值可逆推導得到其所處的環境溫度值。具有靈敏度高、體積小、熱容量小、響應速度快、價格低廉等優點。按照溫度系數不同,可分為正溫度系數熱敏電阻(PTC)、負溫度系數熱敏電阻(NTC)和臨界負溫度系數熱敏電阻(CTR)。PTC隨着溫度升高,表現出的電阻值越大; NTC隨着溫度升高,表現出的電阻值越低;CTR具有負電阻突變特性,在某一溫度下,電阻值隨溫度的增加急劇減小,具有很大的負溫度系數。由於具有不同的特性,熱敏電阻的用途也是不同的。PTC一般用作加熱元件和過熱保護;NTC一般用於溫度測量和溫度補償;CTR一般用於溫控報警等應用。NTC的測溫范圍為-60~+300℃,標稱阻值一般在1Ω至100MΩ之間,采用精密電阻和熱敏電阻組合可擴大測量溫度線性范圍。圖1為NTC實物圖,圖中所示的為NTC 10D-9和NTC 5D-7。NTC表示為負溫度系數的熱敏電阻,10D-9和5D-7代表其型號,10D-9代表了常溫(25攝氏度)阻值10歐姆,直徑9毫米,5D-7代表了常溫(25攝氏度)阻值5歐姆,直徑7毫米。除了圖1所示的形狀之外,熱敏電阻制成的探頭有珠狀、棒桿狀、片狀和薄膜等,封裝外殼有玻璃、鎳和不銹鋼管等套管結構,如圖2所示。
圖1 NTC實物圖
圖2 NTC的各種形式
1.2 NTC的使用方法
NTC的測量溫度和其表現出的電阻值存在一個非線性的已知的關系,那么測量出NTC的電阻值也可以計算得到其測量的溫度值。NTC的電阻值與溫度值的關系如下所示:
Rt = R x e^[B x (1/T1-1/T2)]
式中, Rt 是熱敏電阻在T1溫度下的阻值;R是熱敏電阻在T2常溫下的標稱阻值;B值是熱敏電阻的重要參數;T1和T2指的是K度即開爾文溫度,K度=273.15(絕對溫度) 攝氏度。
逆向計算得到熱敏電阻的溫度值與電阻值的關系如下所示:
T1=1/(ln(Rt/R) /B 1/T2 )
電阻值的測量一般都是利用串聯已知阻值的電阻並施加已知大小的電壓,通過測量已知阻值的電阻上的分壓值,來計算出得到被測電阻的阻值,如圖3所示。設施加的激勵電壓為Eb,熱敏電阻的阻值為Rt,串聯電阻阻值為Rs,則串聯電阻上的分壓值為:
Eout = Eb x Rs/(Rt Rs)
除了串聯測量法之外,還有惠斯登電橋測量法,如圖4所示。設電橋的激勵電壓為Eb,熱敏電阻的阻值為Rt,電橋電阻阻值為R1、R2和R3,則電橋輸出電壓為:
out = Eb x R3/(Rt R3) – Eb x R2/(R1 R2) = Eb x [R3/(Rt R3) – R2/(R1 R2)]
圖3 串聯測量法
圖4 電橋測量法
1.3 使用實例
(1)硬件連接
此處使用串聯測量法來測量來實現熱敏電阻測量實驗,其硬件連接圖如圖5所示,熱敏電阻為NTC 10D-9,串聯電阻的阻值為100Ω。
圖5 NTC測溫硬件連接圖
(2)程序設計
程序設計的主要思路:Arduino Uno控制器通過模擬輸入端口測量串聯電阻上的電壓值,然后通過電流相等的原理計算出熱敏電阻的阻值,最后利用公式計算出溫度值。
#include //包含數學庫void setup(){ Serial.begin(9600); //波特率設置為9600}void loop(){ double Digital_Value=analogRead(0); //讀取串聯電阻上的電壓值(數字量) double Voltage_Value=(Digital_Value/1023)*5.00;//換算成模擬量的電壓值 double Rt_Value=(3.3-Voltage_Value)/Voltage_Value*100; //計算出熱敏電阻的阻值 //計算所感知的溫度並發送Serial.println( 1/(log(Rt_Value/10)/3000 1/( 25 273.15)) - 273.15,2); delay(1000); //一秒刷新一次}
2 LM35
LM35 是美國NS(國家半導體)所生產的的模擬溫度傳感器,其輸出的電壓與攝氏溫度成線性比例關系,在0℃時輸出0V,溫度每升高1℃,輸出電壓增加10mV。測溫范圍l ?55 ~ 150?C,精度為0.75℃,室溫的精度可達0.25℃。常用的TO-92封裝的引腳排列如圖6所示,在2℃~150℃的測溫范圍內的典型應用電路如圖7所示。
圖6 TO-92封裝的引腳排列
圖7 2℃~150℃的典型電路圖
2.3 使用實例
(1)硬件連接
將LM35模擬式溫度傳感器的 Vs和GND分別連接至Arduino Uno控制器的 5V和GND,以給LM35提供工作電源,LM35的Vout引腳接至ArduinoUno控制器模擬輸入端口A0,如圖8所示。
圖8 LM35測溫硬件連接圖
2)程序設計
程序設計的主要思路:Arduino Uno控制器通過模擬輸入端口測量LM35輸出的電壓值,然后通過10mV/℃的比例系數計算出溫度數值。同時,在100℃的時候,LM35輸出電壓值為1000mV,在Arduino Uno控制器的內部參考電壓范圍內,所以采用1.1V內部參考電壓。
int Digital_Value=0;float temp_Value=0;void setup(){ Serial.begin(9600); //波特率設置為9600 //由於測溫范圍為0~100℃,輸出電壓為0~1V,采用內部1.1V參考電壓analogReference(INTERNAL);}void loop(){ Digital_Value=analogRead(A0); //讀取電壓值(數字量) temp_Value=(float)Digital_Value/1023*110.00;//換算成攝氏溫度 Serial.print('Temperature for LM35 is: '); Serial.println(temp_Value,2); //發送溫度數據 delay(1000) //一秒刷新一次}
(3)實驗演示
實際的實驗硬件連接圖如圖9所示,串口接收到的溫度數據如圖10所示。
圖9 實驗硬件連接圖
圖10 串口接收的溫度數據
3 DS18B20
3.1 DS18B20簡介
DS18B20是美國DALLAS半導體公司的數字化單總線智能溫度傳感器,與傳統的熱敏電阻相比,它能夠直接讀出被測溫度,並且可根據實際要求通過簡單的編程實現9~12位的數字值讀數方式。從DS18B20讀出信息或寫入信息僅需要一根線(單總線)讀寫,總線本身也可以向所掛接的設備供電,而無需額外電源。
DS18B20的性能特點如下:
(1) 單線接口方式實現雙向通訊;
(2) 供電電壓范圍: 3.0V~ 5.5V,可用數據線供電;
(3) 測溫范圍:-55~ 125℃,固有測溫分辨率為0.5℃;
(4) 通過編程可實現9~12位的數字讀數方式;
(5) 支持多點的組網功能,多個DS18B20可以並聯在唯一的單總線上,實現多點測溫。
DS18B20的外形及管腳排列如圖11所示,DS18B20引腳定義:(1)DQ為數字信號輸入/輸出端;(2)GND為電源地;(3)VDD為外接供電電源輸入端(在寄生電源接線方式時接地)。
圖11 DS18B20封裝圖
3.2 DS18B20編程與庫的使用
Arduino要實現對DS18B20的操作,需要OneWire和Dallas Temperature Control兩個庫文件,下載地址分別為:http://playground.arduino.cc/Learning/OneWire和https://github.com/milesburton/Arduino-Temperature-Control-Library。Dallas Temperature Control函數庫是基於OneWire函數庫進行開發的,更便於使用,下面講解一下主要函數的功能和用法。
(1) void begin(void):初始化,無輸入參數,無返回參數。
(2) getDeviceCount(void):獲取單總線上所連接器件的總數,無輸入參數,返回參數為器件數目。
(3) validAddress(uint8_t*):驗證指定地址的器件是否存在,輸入參數為器件地址,返回參數為布爾型。
(4) getAddress(uint8_t*, const uint8_t):驗證的器件的地址與索引值是否匹配,輸入參數為器件地址和索引值,返回參數為布爾型。
(5) getResolution(uint8_t*):獲取指定器件的精度,輸入參數為器件地址,返回參數為精度位數。
(6) setResolution(uint8_t*,uint8_t):設置器件的精度,輸入參數為器件地址和精度位數,無返回參數。精度位數有9,10,11和12可供選擇。
(7) requestTemperatures(void):向單總線上所有器件發送溫度轉換的請求,無輸入參數,無返回參數。
(8) requestTemperaturesByAddress(uint8_t*):向單總線上指定地址的器件發送溫度轉換的請求,輸入參數為器件地址,無返回參數。
(9) requestTemperaturesByIndex(uint8_t) :向單總線上指定索引值的器件發送溫度轉換的請求,輸入參數為器件索引值,無返回參數。
(10) getTempC(uint8_t*):通過器件地址獲取攝氏溫度,輸入參數為器件地址,返回參數為攝氏溫度。
(11) getTempF(uint8_t*):通過器件地址獲取華氏溫度,輸入參數為器件地址,返回參數為華氏溫度。
(12) getTempCByIndex(uint8_t):通過索引值來獲取攝氏溫度,輸入參數為器件索引值,返回參數為攝氏溫度。
(13) getTempFByIndex(uint8_t):通過器件索引值來獲取華氏溫度,輸入參數為器件索引值,返回參數為華氏溫度。
3.3 使用實例
由於單總線上可以連接多個DS18B20,而不多占用Arduino控制器的IO口,從而很容易地就可以實現多點測溫,下面分別兩個使用實例來說明DS18B20與Arduino的用法。
3.3.1 一路溫度測量
(1)硬件連接
將DS18B20溫度傳感器的VCC和GND分別連接至Arduino Uno控制器的 5V和GND,以給DS18B20提供電源,DS18B20的DQ引腳接至ArduinoUno控制器數字引腳D2,且並聯4.7kΩ的上拉電阻,如圖12所示。
圖12 一路溫度測量硬件連接圖
(2)程序設計程序設計的主要思路:Arduino Uno控制器通過DallasTemperature函數庫實現單總線的啟動、發送測量溫度的請求、讀取0號傳感器溫度,最后通過串口發送出去。
#include #include #define ONE_WIRE_BUS 2 //定義單總線連接的端口OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);void setup(void){ Serial.begin(9600); Serial.println('Dallas Temperature IC Control Library Demo'); sensors.begin(); //啟動單總線}void loop(void){ Serial.print('Requesting temperatures...'); sensors.requestTemperatures(); //發送溫度測量請求命令 Serial.println('DONE'); Serial.print('Temperature for the device 1 (index 0) is: '); Serial.print(sensors.getTempCByIndex(0)); //獲取0號傳感器溫度數據並發送 Serial.println('℃'); delay(1000); //一秒刷新一次}
3.3.2 多路溫度測量
(1)硬件連接
將兩個DS18B20溫度傳感器的VCC和GND分別連接至Arduino Uno控制器的 5V和GND,以給兩個DS18B20提供電源,兩個DS18B20的DQ引腳接至ArduinoUno控制器數字引腳D2,且並聯4.7kΩ的上拉電阻,如圖13所示。
圖13 多路溫度測量硬件連接圖
(2)程序設計
程序設計的主要思路:Arduino Uno控制器通過DallasTemperature函數庫實現單總線的啟動、發送測量溫度的請求、讀取0號傳感器溫度並串口發送出去,讀取1號傳感器溫度並串口發送出去。
#include #include #define ONE_WIRE_BUS 2 //定義單總線連接端口OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);void setup(void){ Serial.begin(9600) Serial.println('Dallas Temperature IC Control Library Demo'); sensors.begin(); //啟動單總線}void loop(void){ Serial.print('Requesting temperatures...'); sensors.requestTemperatures(); //發送溫度測量請求命令 Serial.println('DONE'); Serial.print('Temperature for the device 1 (index 0) is: '); Serial.println(sensors.getTempCByIndex(0)); //獲取0號傳感器溫度數據並發送Serial.print('Temperature for the device 2 (index 0) is: '); Serial.println(sensors.getTempCByIndex(1)); //獲取1號傳感器溫度數據並發送}
3.3.2 實驗演示
實際的單路實驗硬件連接圖如圖14所示,單路和兩路實驗中串口接收到的溫度數據分別如圖15和16所示。
圖14 單路實驗硬件連接圖
圖15 單路串口接收的溫度數據
圖16 兩路串口接收的溫度數據
4 DHT11
4.1 DHT11簡介
DHT11是一款含有已校准系數的數字信號輸出的溫濕度復合傳感器,采用專用的數字模塊采集技術和溫濕度傳感技術,具有極高的可靠性與卓越的長期穩定性,內部包含一個電阻式感濕元件和一個NTC測溫元件。DHT11傳感器都經過實驗室校准,校准系數以程序的形式儲存在OTP內存中,傳感器內部在檢測信號的處理過程中要調用這些校准系數,采用單線制串行接口,使系統集成變得簡易快捷。超小的體積、極低的功耗,信號傳輸距離可達20米以上。DHT11數字溫濕度傳感器實物圖如17所示。
圖17 DHT11溫濕度傳感器
DHT11的引腳說明如表1所示,供電電壓為3.3~5V,測量范圍為濕度20~90%RH, 溫度0~50℃,測量精度為濕度±5%RH,溫度±2℃,測量分辨率為濕度1%RH,溫度1℃。
4.2 DH11編程與庫的使用
DHT11的Arduino庫文件下載地址:https://github.com/markruys/arduino-DHT。DHT11庫文件有如下幾個函數:dht.setup(int Pin)、dht.getHumidity()、dht.getTemperature()。
dht.setup(int Pin):設置DHT11總線的連接管腳號,輸入參數為所連接的管腳號,無返回參數。
dht.getHumidity():獲取DHT11的濕度值,無輸入參數,返回值為濕度值,double類型。
dht.getTemperature():獲取DHT11的溫度值,無輸入參數,返回值為溫度值,double類型。
4.3 使用實例
下面以DHT11模塊實現溫濕度的測量,並且通過串口輸出。(1)硬件連接將DHT11溫濕度傳感器的VCC、GND分別連接至Arduino Uno控制器的 5V、GND,以給DHT11提供電源,DHT11模塊的DOUT引腳接至ArduinoUno控制器數字引腳D2,且並聯5kΩ的上拉電阻,DHT11模塊的NC引腳也連接至GND,如圖18所示。
圖18 DHT11溫濕度測量硬件連接圖
(2)程序設計程序設計的主要思路:Arduino Uno控制器通過DHT11函數庫獲取濕度和溫度數據,並通過串口發送出去。
#include 'DHT.h'DHT dht;void setup(){ Serial.begin(9600); dht.setup(2); // data pin 2 delay(1000);}void loop(){ float temperature = dht.getTemperature(); float humidity = dht.getHumidity(); Serial.print('temperature is '); Serial.print(temperature, 1); Serial.println(' C'); Serial.print('humidity is '); Serial.print(humidity, 1); Serial.println('%'); delay(3000);}
(3)實驗演示實際的實驗硬件連接圖如圖19所示,實驗中串口接收到的溫濕度數據如圖20所示。
圖19 實驗硬件連接圖
圖20 串口接收的溫濕度數據
5 熱電偶
5.1 熱電偶和MAX6675簡介
將兩種不同材料的導體或半導體A和B焊接起來,構成一個閉合回路,當導體A和B的兩個連接點1和2之間存在溫差時,兩者之間便產生電動勢,因而在回路中形成一個回路電流。這種現象稱為熱電效應,而這種電動勢稱為熱電勢。熱電效應原理圖如圖21所示。
圖21 熱電效應原理圖
熱電偶就是利用熱電原理進行溫度測量的,其中,直接用作測量介質溫度的一端叫做工作端(也稱為測量端),另一端叫做冷端(也稱為補償端)。實際上是一種能量轉換器,它將熱能轉換為電能,用所產生的熱電勢測量溫度。常用的K型熱電偶實物如圖22所示,可以直接測量各種生產中從0℃到1300℃范圍的液體蒸汽和氣體介質以及固體的表面溫度。具有線性度好,熱電動勢較大,靈敏度高,穩定性和均勻性較好,抗氧化性能強,價格便宜等優點。
圖22 K型熱電偶實物圖
根據熱電偶測溫原理,K型熱電偶的輸出熱電勢不僅與測量端的溫度有關,而且與冷端的溫度有關,需要溫度補償電路(如圖23為補償示意圖),同時熱電偶的電壓與溫度之間具有非線性,MAX6675模塊可以對K型熱電偶進行信號放大、冷端補償和非線性校正。MAX6675帶有簡單的3位串行SPI接口;可將溫度信號轉換成12位數字量,溫度分辨率達0.25℃;內含熱電偶斷線檢測電路。冷端補償的溫度范圍-20℃~80℃,可以測量0℃~1023.75℃的溫度,基本符合工業上溫度測量的需要。
5.2 MAX6675編程與庫的使用
MAX6675的Arduino庫文件下載地址:https://github.com/aguegu/ardulibs/tree/master/max6675。MAX6675庫文件有如下幾個函數:getCelsius()、getFahrenheit()、getKelvin()和setOffset(int offset)。?
getCelsius():獲取攝氏溫度,無輸入參數,返回值為攝氏溫度,float類型。 ? getFahrenheit():獲取華氏溫度,無輸入參數,返回值為華氏溫度,float類型。 ? getKelvin():獲取開爾文溫度,無輸入參數,返回值為開爾文溫度,float類型。 setOffset(int offset):設置溫度偏移,輸入參數為偏移值,int類型,最小單位為0.25℃,無返回值。
5.3 使用實例
下面以K型熱電偶與MAX6675模塊實現高溫的測量,並且通過串口輸出。
(1)硬件連接
將MAX6675模塊的VCC和GND分別連接至Arduino Uno控制器的 5V和GND,以給MAX6675提供電源,MAX6675模塊的信號引腳SO、CS和CSK連接至數字引腳5、6、7,K型熱電偶的正負極分別連接至MAX6675模塊的T 和T-,如圖24所示。
圖24 熱電偶測溫硬件連接圖
(2)程序設計
程序設計的主要思路:Arduino Uno控制器通過MAX6675函數庫獲取熱電偶所測量的溫度值,完成了熱電偶輸出電壓的信號放大、冷端補償和非線性化處理,最終通過串口輸出。
#include 'Max6675.h'Max6675 ts(5, 6, 7); //依次定義SO、CS、CSK所連接的引腳號void setup(){ts.setOffset(0); //設置溫度偏移量Serial.begin(9600);}void loop(){ Serial.print('temperature is '); Serial.println(ts.getCelsius(), 2); //獲取攝氏溫度,並通過串口發送 delay(1000); //一秒刷新一次}
(3)實驗演示
實際的實驗硬件連接圖如圖25所示,實驗中串口接收到的溫度數據如圖26所示。
圖25 實驗硬件連接圖
圖26 串口接收的溫度數據
6.總結
本文介紹了溫度測量的幾種常用傳感器,從測溫原理、器件特性、在Arduino中的編程與使用等方面做了詳細的介紹。總結本文,有以下幾點:
1、NTC熱敏電阻價格低廉,但是想要得到很高的測量精度,需要做很多優化工作,難度較大。
2、LM35直接輸出模擬電壓,使用較為方便,精度較高,適合用於熱電偶冷端補償中的環境溫度測量。
3、DS18B20是單總線數字溫度傳感器,性價比較高,測量精度較高,同時可以單個總線掛多個傳感器。
4、DHT11是溫濕度傳感器,單總線,不占用過多的I/O口,而且可以同時輸出濕度數據,適合同時需要溫濕度數據的場合應用。
5、熱電偶和MAX6675配合使用,適合高溫測量,省去了熱電偶的冷端補償、線性化和模數轉換等工作,使用較方面,精度較高,對其數據進行二次擬合標定,可以得到更高的測量精度。
最后對比一下熱電偶 MAX6675模塊和DS18B20的響應速度,如圖27所示是基於Arduino與LabVIEW的實驗平台采集到熱電偶在放進熱水中的數據變化情況,從圖中可以看出,最高溫度約為60℃,熱電偶的響應曲線較為平直,上升速度較快。如圖28所示為基於Arduino與LabVIEW的實驗平台采集到DS18B20對於冷熱變化的響應曲線圖,從圖中可以看出最高溫度超過80℃,DS18B20響應曲線較為平緩,隨着溫差的縮小,溫度響應速度越發放緩。
圖27 熱電偶溫度變化響應曲線圖
圖28 DS18B20溫度變化響應曲線圖