2017年8月3日 星期四

使用MCU讀取熱敏電阻量來測溫度

你想用熱敏電阻偵測溫度嗎?你想用微控制器做熱敏電阻的讀取並顯示溫度嗎?
由於Edison在出社會第一份從事電子的工作的公司就是專門生產體溫計的公司,既然了解其中一點東西,出社會這麼久了,也該分享一些東西讓有需要的人可以取得資訊的來源,加速學習過程,本篇文章幫大家介紹如何使用微控制器讀取熱敏電阻並顯示溫度,本文參考維基百科中熱敏電阻的介紹,說明了熱敏電阻的基本原理,不懂的地方可以詳讀之後再開始進行設計的工作!

熱敏電阻英語:thermistor)是一種傳感器電阻,電阻值隨著溫度的變化而改變,且體積隨溫度的變化較一般的固定電阻要大很多。熱敏電阻的英文「thermistor」是由Thermal(熱)及resistor(電阻)兩詞組成的混成詞。熱敏電阻屬可變電阻的一類,廣泛應用於各種電子元件中,例如湧流電流限制器溫度傳感器可復式保險絲、及自動調節的加熱器等。
不同於電阻溫度計使用純金屬,在熱敏電阻器中使用的材料通常是陶瓷聚合物。兩者也有不同的溫度響應性質,電阻溫度計適用於較大的溫度範圍;而熱敏電阻通常在有限的溫度範圍內實現較高的精度,通常是-90℃〜130℃。
負溫度係數(NTC)熱敏電阻器,珠型,絕緣電線

基本特性

熱敏電阻最基本的特性是其阻值隨溫度的變化有極為顯著的變化,以及伏安曲線呈非線性。若電子和空穴的濃度分別為,遷移率分別為,則半導體的電導為:
  
因為都是依賴溫度T的函數,所以電導是溫度的函數,因此可由測量電導而推算出溫度的高低,並能做出電阻-溫度特性曲線。這就是半導體熱敏電阻的工作原理。
假設,電阻和溫度之間的關係是線性的,則: :
 = 電阻變化
 = 溫度變化
 = 一階的電阻溫度係數
熱敏電阻可以依值大致分為兩類:
  • 為正值,電阻隨溫度上昇而增加,稱為正溫度係數PTCPositive Temperature Coefficient)熱敏電阻。
  • 為負值,電阻隨溫度上昇而減少,稱為負溫度係數NTCNegative Temperature Coefficient)熱敏電阻。
此外還有一種臨界溫度熱敏電阻(CTRCritical Temperature Resistance),在一定溫度範圍內,其電阻會有大幅的變化[2]
非熱敏電阻的一般電阻,其一般都相當接近零,因此在一定的溫度範圍內其電阻值可以接近一定值。
有時熱敏電阻不用溫度係數k來描述,而是用電阻溫度係數來描述,其定義為[3]
此處的係數和以下的參數是不同的。

斯坦哈特-哈特公式

在實務上,上述的線性近似只在很小溫度範圍下適用,若要考慮精密的溫度量測,需要更詳細的描述溫度-電阻曲線。斯坦哈特-哈特公式是廣為使用的三階近似式:
其中abc稱為斯坦哈特-哈特參數,每個熱敏電阻有不同的參數,T是以開爾文表示的溫度,R是電阻,單位是歐姆,若要電阻以溫度的函數表示,可以整理為下式:
其中
在二百度的範圍內,斯坦哈特-哈特公式的誤差多半小於0.02 °C[4]。例如,室溫下(25 °C = 298.15 K)電阻值為3000 Ω的熱敏電阻,其參數為

NTC熱敏電阻的參數

NTC熱敏電阻的電阻值隨溫度的上昇而下降,也可以用B(或β)參數來描述其特性,其實就是參數為斯坦哈特-哈特公式
其中
  • T:溫度,單位為K
  • R0:為溫度T0 (25 °C = 298.15 K)時的電阻
求解R可得
或者
其中.
因此可以求解溫度為
B參數的方程也可以表示為,可以得熱敏電阻溫度及電阻的方程式轉換為的線性方程式。由其平均斜率可以得到B參數的估計值。

上述截錄了維基百科對熱敏電阻的說明,一般熱敏電阻廠商在提供熱敏電阻給設計者時,會順便提供RT Table,簡單來說RT Table就是電阻對應溫度的表格,用來在MCU的程式記憶體內建立查表資訊,至於如何用來讀取溫度需先懂得如何使用微控制器的ADC,由於愛迪生常用的MCU為Microchip PIC16系列,關於ADC的詳細設定可以詳讀原廠的datasheet,並可上網至台灣Microchip的網站上的討論區搜尋相關資料,Microchip的MCU討論區上很多高手可以詢問,在此不多做說明!

首先要設計必須取得的資料或零件有
(1) NTC(負溫度係數熱敏電阻)
(2) NTC RT Table(請廠商提供)
(2) Microchip MCU 開發板(手焊或購買皆可,要有辦法動)
(3) Microchip MCU發展工具(ICD3/PICKIT3等...)

下圖為103 NTC的RT Table,所謂103就是攝氏25度時的電阻值為10k歐姆,我們可以很清楚的看到表格為每5度建立一筆,假設您要量測的範圍是攝氏20~100度,那就必須將17筆經過計算後的資料建立在MCU的程式記憶體,注意是"程式記憶體"喔,表格資料屬於常數,加上微控制器都是資料記憶體比較小,而程式記憶體比較大,當然會把不會變更的表格放在Program Memory裡面!



有了表格之後還必須要把MCU相關工具建立起來,板子開發工具都有需要,在硬體設計上不多談其他電源或周邊電路,只針對溫度讀取的部分提供設計概念,簡單的偵測電路如下,以一個NTC跟固定電阻做分壓,然後將VOUT進入ADC做讀取,固定電阻的阻值跟建表有關,假設ADC是10-bits解析度,也就是0~1023,並假設我們使用的是10k電阻!

計算分壓之後必須再轉換成ADC Code,也就是要查表的表格,分壓的計算不多做說明,假設VREF為5V, ADC Coder = VOUT / 5 * 1024;(註 : 10-bits ADC為1024)



由上圖可以看出曲線並非線性的,因此建表在MCU內是有必要的,因此我們可以將上圖的ADC Code的數值經過四捨五入之後建立在MCU的Program Memory,建立方式不難,假設您用C來寫程式的話則採用陣列的形式來建立表格!
const unsigned int TABLE[17] = {461, 512, 563, 611, 657, 699, 737, 772, 803, 830, 854, 875, 894, 910, 924, 936, 947}; 

而MCU在寫程式的流程大概是
(1)Initialize MCU(IO/ADC etc..)
(2)進行Analog to Digital,然後查表
(3)判定或顯示溫度,做出對應工作

假設ADC得到500這個數值,如何轉換成溫度? 要如何讓溫度顯示解析度為0.1度?
(1)要知道500在哪個範圍內 : 程式設計的觀點來看,TABLE[0] <= 500 <= TABLE[1]
(2)要懂得使用片段線性內插法 : 由於是每5度建立一個表,因此可以透過計算Slope的方式來進行內插,不懂片段線性內插法可以參考Piecewise Linear Interpolation on PIC12/14/16 Series Microcontrollers
連結路徑為http://application-notes.digchip.com/022/22-19220.pdf


計算方式如下:
a. (512 - 461) / 5 = 10.2
b. 500 - 461 = 39 counts
c. 39 / 10.2 = 3.8
d. 20 + 3.8 = 23.8度

當然上述的計算方式會有小數點,對於MCU來說是很龐大的運算,不建議使用浮點運算,因此可以將數值放大來計算,然後在顯示時自動將小數點補上去即可
a. (500 -461) * 100 / (512 - 461) * 5 = 382
b. 382 / 10 = 38
c. 38 / 10 = 3, 38 % 10 = 8 

顯示的部分可以使用七段顯示器或者LCD做顯示,網路上很多這樣的東西,找一下應該不難!

Pseudo Code如下~
const unsigned int TABLE[17] = {461, 512, 563, 611, 657, 699, 737, 772, 803, 830, 854, 875, 894, 910, 924, 936, 947}; 
void main(void)
{
    Init_MCU();
    Init_ADC();

    while(1)
   {
        ADC();
        LookUpTable();
        CalculateTemperature();
        Display();
    }
    return;
}



STM32於IAR 9.3以後的版本將uart導向至printf

首先,請先參考如以下IAR提供的"在IAR Embedded Workbench中实现打印输出技術資料" https://www.iar.com/cn/knowledge/support/technical-notes/general/implementing-printf-ou...