基礎教程8 Arduino溫度計與參考電壓精度
來自專欄 Arduino 魔法書5 人贊了文章
我是潘,曾經是個工程師。這是為 http://Ardui.Co 製作的 「Arduino 公開課」 系列的入門教程。第8課我們會用溫度感測器實驗,來介紹 ADC 的解析度,同時會學到怎樣利用 Arduino 內部參考電壓提高測量精度。有任何疑問請在評論區提出,我會逐一回答。
LM35 是美國國家半導體(現被 TI 收購)推出的精密溫度感測,其信號輸出為模擬量:電壓值與溫度(攝氏)呈正比。不僅體積非常小(常見TO-92封裝),而且不需額外的校正,就能獲得較高的精度。
其主要特性:
供電電壓:4~35V工作範圍:與晶元有關,LM35A為-55~150°C 常見 LM35D 為 0~100°C測量範圍:與封裝和電路有關,常用 TO-92為 2 ~150°C測量精度:與晶元有關,LM35A 性能最優,這次實驗用的 LM35D最差,其典型值為 ±0.8°C,最大值 ±2°C
電壓與溫度的關係: Vout = Temperature × 10mV/°C
想了解更多,可以參考官方 DataSheet。接線方式如下:
電壓轉換方式:
Vin為輸入(被測量)電壓;Vref 是參考電壓,若不設置就是供電電壓,Arduino UNO 為 5V;resolution 是模擬埠的 ADC bit,Uno 模擬埠為10bit,Result 為 模擬埠的測量結果,數值為0~1023。程序如下:
/* 作者:Ardui.Co 效果:LM35 簡單溫度測量 版本:1.0 更新時間:2017年1月9日*/int LM35 = A0; //指定A0埠讀取LM35float Vin; //存儲感測器電壓float temperature; //存儲溫度測量結果 void setup(){ Serial.begin(9600); //初始化串口連接}void loop(){ Vin = analogRead(LM35) * 5.0 / 1024; //計算出A0的電壓,單位為V temperature = Vin * 1000.0 / 10.0; //將A0電壓要轉換成mV,根據LM35轉換係數10mV/°C,除以10,得出溫度 Serial.print("Temperature: "); //在串口監視器輸出結果 Serial.print(temperature); Serial.println(" *C"); delay(500); //延時0.5s}
ADC 測量精度問題:
對於 5V 參考電壓來說,每級為 5V / 1024 = 4.88mV,轉化為溫度,每級解析度就是 0.488 °C。如果環境溫度為 T ,Arduino Uno 的測量結果是 0.488 Result ,但 Result 是 0 ~ 1023 的正整數,誤差 τ 就是
τ = T mod 0.488 (mod 為求余運算)
Arduino Uno 內置了1.1v 參考電壓,使用這個參考電壓,每級為 1.1V / 1024 = 1.07mV,每級解析度提高到 0.107°C。
如果環境溫度為10°C,取5V參考電壓的解析度為 0.24°C,取1.1V 參考電壓則為 0.049°C;如果環境溫度為25°C,取5V參考電壓的誤差為 0.112°C,取1.1V 參考電壓則為 0.069°C。
接線不變,調整一下程序,引入Arduino 的內部參考電壓:
/* 作者:Ardui.Co 效果:LM35 使用1.1內部參考電壓提高解析度 版本:1.0 更新時間:2017年1月9日*/int LM35 = A0; //指定A0埠讀取LM35float Vin; //存儲感測器電壓float temperature; //存儲溫度測量結果 void setup(){ analogReference(INTERNAL); //使用內部參考電壓 Serial.begin(9600); }void loop(){ Vin = analogRead(LM35) * 1.1 / 1024; //計算出A0的電壓,單位為V temperature = Vin * 1000.0 / 10.0; //將A0電壓要轉換成mV,根據LM35轉換係數10mV/°C,除以10,得出溫度 Serial.print("Temperature: "); //在串口監視器輸出結果 Serial.print(temperature); Serial.println(" *C"); delay(500);}
參考電壓穩定性:
由於參考電壓跟 Vin 和溫度成正比,實際中的電源電壓往往十分不穩定,電池電壓會隨著電量變化(比如:單個鋰離子放電電壓約為 4.25V ~ 2.95V),開關電源會有 50 ~ 200mV 紋波,常見的USB電源在不同負載上約有 ±4% 的變化。
但別以為用 Arduino Uno 內部參考電壓就萬事大吉,其誤差更高達 5%。因此,使用內部基準源在提高分辨能力的同時,也引入了額外的測量誤差,所以要用穩定性高的參考電壓。
其實,也有一個折中的方案。Arduino Uno 內部提供了一塊 LDO(低壓差穩壓IC),為 3.3V 埠供電。LDO 一般為德州儀器的 LP2985-33DBVR,其誤差小於 1.5%,用它來做外部參考電壓,相對5V來說解析度更高,相對 1.1V 內部參考電壓來說,測量誤差更小。
要使用外部參考電壓,將 Aref 連接到 3.3V 埠:
我們將 3.3V 的埠跟 Aref 鏈接,並在內部程序中聲明:
/* 作者:Ardui.Co 效果:LM35 使用3.3外部參考電壓提高解析度 版本:1.0 更新時間:2017年1月10日*/int LM35 = A0; //指定A0埠讀取LM35float Vin; //存儲感測器電壓float temperature; //存儲溫度測量結果 void setup(){ analogReference(EXTERNAL); //使用內部參考電壓 Serial.begin(9600); }void loop(){ Vin = analogRead(LM35) * 3.3 / 1024; //計算出A0的電壓,單位為V temperature = Vin * 1000.0 / 10.0; //將A0電壓要轉換成mV,根據LM35轉換係數10mV/°C,除以10,得出溫度 Serial.print("Temperature: "); //在串口監視器輸出結果 Serial.print(temperature); Serial.println(" *C"); delay(500);}
我們還可以 Aref 連接到 Arduino 開發板之外的參考源上,以獲取更精確的測量結果。
另外,要提高的解析度,除了改變參考電壓,也可以採用高位數的 ADC 晶元,不少精密 ADC 可達16bit 以上解析度,我們會在提高篇中來講解。
練習6.1:嘗試結合第6課的內容,根據溫度來控制風扇的速度。
推薦閱讀:
※使用TFT LCD製作Arduino觸摸屏計算器
※Arduino簡介
※手動搭建你的高擴展C++神經網路框架
※使用Arduino開發板自製簡易歐姆表
※如何使用 Arduino 製作一個繪圖儀