【Maker電子學】溫度測量 IC 的原理與應用

作者:Bird

上回我們介紹了利用電阻的溫度係數做成的溫度測量元件 NTC / PTC 熱敏電阻,用來測量溫度。但實務上由於這些元件的非線性特性,以及它們的類比輸出,讓它們與小型 MCU 連接時有點麻煩。這次我們就來介紹一些用起來更簡單、更方便的專用溫度測量 IC。

類比輸出溫度測量 IC

首先要介紹的是類比輸出的溫度測量 IC。這一類的溫度測量 IC 存在市場上的時間很久了,而且已經有了統一的工業化標準腳位。這種 IC 通常是三隻腳:兩隻電源、一隻訊號輸出,而輸出的訊號通常是電壓,與溫度呈線性負相關(注意不是反比喔)

我們來看個實際的例子好了。

(圖片來源:Bird提供)

LM50 是 TI 出品的一顆類比式溫度測量 IC。它可以接受 4.5V 到 10V 的供電範圍,而它的輸出是一個與溫度呈負相關的電壓:溫度越高,電壓就越低,而且非常線性。

除了線性之外,這顆 IC 還很貼心低把輸出電壓的斜率調整成 10mV /℃,讓你很好計算。這是 LM50 輸出電壓與溫度的關係:

LM50 輸出電壓與溫度的關係。(圖片來源:Bird提供)

它在 0℃ 時的輸出電壓是 0.5V 或 500mV,每往上加一度就增加 10mV;每往下減一度就減少 10mV。寫成算式就是:

VO (mV) = 500 + T (℃) * 10

把 T 解出來,就變成:

T (℃)= (VO (mV) – 500) / 10

如果我們要把 LM50 接到 Arduino UNO 上,可以這樣接:

(圖片來源:Bird提供)

我們可以直接用 Arduino 上的 5V 供電給 LM50,再把 Vout 接到 Arduino 的任何一個 analog input。以這張圖為例,我們將它接到 Arduino 的 A0。接著我們就可以用這行指令讀取 A0 上的電壓:

ReadValue = analogRead(A0);

Arduino 的 ADC 是 10-bit 的,測量的參考電壓是 5V,因此它就是將 0 – 5V 的輸入電壓轉換到 0 – 1023 的數值。假設我們讀回來的 ReadValut 是 300,我們可以算一下在 A0 腳上的電壓是多少:

VA0 = 5 * (ReadValue / 1023) = 5 * (300 / 1023) =  1.466V

再根據前面從 LM50 的輸出電壓計算溫度的算式,我們就可以知道 LM50 量到什麼溫度:

T (℃)= (VO (mV) – 500) / 10 = (1466 – 500) / 10 = 96.6 (℃)

嗯,有點熱…

類比數位轉換器的原罪

上面說明的這個做法有一個先天的問題:它的精確度受到 Arduino 本身 ADC 的準確度限制。

任何的 ADC 都需要一個參考電壓,做為數位世界和真實世界連結的基準。以 Arduino 來說,它的 ADC 參考電壓是 5V,而這個 5V 其實來自於 Arduino 板子上的 5V 電源。

但是當 Aruino 用 USB 供電時,它的 5V 是直接來自 USB 的 VBUS,沒有經過任何的穩壓 (你無法把 5V 穩壓成 5V,穩壓電路需要一些壓差才能工作),因此它到底是不是 5V,完全看你電腦上 USB 電源的設計以及同一串 USB 連線上其它裝置吃電的狀況。如果同一串 USB hub 上有人吃特別兇,或是 USB 的線接很長,VBUS 就有可能略低於 5V。根據 USB 的官方規格,在裝置端測量到的 VBUS 從 4.4V – 5.25V 都在規範內。

假設上面那片 Arduino UNO 收到的 VBUS 電壓只有 4.9V,但我們以為它還是 5V,而 A0 上的電壓仍是 1.466V 時,我們來看看會有多大的測量誤差。

用 4.9V 當參考電壓來測量 1.466V 時,ADC 的讀值會是:

(1.466 / 4.9) * 1023 = 306

但我們以為參考電壓是 5V,所以以此來計算電壓,會變成:

(306 / 1023) * 5 = 1.495V

如果用這個錯誤的電壓結果去推算溫度,會得到:

T (℃)= (VO (mV) – 500) / 10 = (1495 – 500) / 10 = 99.5 (℃)

換句話說,參考電壓偏了 0.1V,會導致測量結果偏移 3℃ 之多。更糟的是,VBUS 的電壓有時候會隨著時間變化,當同一個 USB 供電系統中有人一下吃電一下不吃電,一下吃很多又一下吃很少時,就有可能讓 VBUS 的電壓忽高忽低,進而影響 ADC 的測量準確度。

這個問題不只發生在讀取溫度感測器,事實上只要使用 Arduino 內建的 ADC 而且使用 5V 當參考電壓,都要注意這個問題。

Arduino 的設計者當然也有想到這個問題,因此 Aruino 的環境中提供了 analogReference() 這個函式讓使用者選擇 5V 電源以外的參考電壓供 ADC 使用。

在 Arduino UNO 上,如果執行:

analogReference(INTERNAL);

就會讓 Arduino UNO 改用一個晶片內部的 1.1V 電壓源當作 ADC 的參考電壓,而這個電壓是不會受到電源電壓的影響的,因此轉換的精確度可以提升很多。但由於這個參考電壓只有 1.1V,它能偵測的電壓上限就是 1.1V,以 LM50 來說,就只能測量到 (1.1-0.5) / 0.01 = 60 (℃)。嗯,其實有點不夠用。

還有另一個辦法。 在 Arduino UNO 上執行:

analogReference(INTERNAL);

就會讓 Arduino UNO 選擇使用 AREF 這隻腳上的電壓當作 ADC 的參考電壓。你可以另外做個精確一點、耐干擾、抗雜訊的參考電壓產生電路,餵給 AREF。如果不想這麼麻煩,最簡單的方法就是用 Arduino 上的 3.3V 當參考電壓:

(圖片來源:Bird提供)

雖然 Arduino 上的 3.3V 是從 5V 經過一個 3.3V 的 LDO 穩壓器轉出來的,而且沒什麼零件在使用,相當乾淨,很適合拿來當 ADC 的參考電壓。

數位介面溫度測量 IC

除了類比輸出的溫度測量 IC 外,數位介面的溫度測量 IC 也是我們很常用的,而這其中又以 I2C 介面的產品最常用。因為 I2C 介面只需要兩條線,而且在這兩條線上可以連結很多個裝置,非常方便。雖然 I2C 介面的速度遠不及 SPI 或其它的同步介面,但 “溫度測量” 這件工作本身就不是速度太快的事,溫度這個物理量先天上就不太可能需要一秒鐘測量幾千次,就算用 I2C bus 最慢的 100KHz 速度,仍然非常足夠。

我們來看個實際的例子。

TI 的 LM73 是一個數位介面的溫度測量 IC,它的 SMBus 介面是一種跟 I2C 相容但是又略有不同的匯流排介面。

(圖片來源:Bird提供)

I2C bus 上的每個裝置都要有獨一無二的位址。LM73 有一隻腳叫做 ADDR,根據它是接到 Vdd、GND、或是空接,LM73 可以被設定成三個不同的 address:

(圖片來源:Bird提供)

因此你最多可以在同一個 I2C bus 上接三顆 LM73。如果你真的生意做很大,要在同一個 I2C bus 上放超過三顆 LM73,它還有另一個 part number 叫 LM73-1,有另一組三個不同的 I2C device addres,這樣就可以在同一個 bus 上連接最多六顆 LM73。

LM73 裡面共有 6 個暫存器,再加上一個用來指定要存取哪一個暫存器的指標暫存器。它的讀寫方式跟一般 8-bit word address 的 I2C EEPROM(如 24C16 之類的) 很像:要先指定 word address (就是指標暫存器),再進行讀寫。

舉例來說,LM73 的第 0 號暫存器是一個 16-bit 的暫存器,裡面的值就是最後一次測量到的溫度。如果我們要讀取這個暫存器的值,就要用以下的 I2C 存取程序:

(圖片來源:Bird提供)

其實它就是個有正負號的 13-bit 二進位數字,精度到二進位的小數點後 5 位,或是 1/32 = 0.03125,單位就是 ℃。為什麼要有正負號呢?因為溫度可以是負的呀。

1℃ 的 bit 在 D7,因此 正 1℃ 的讀值就會是 0000 0000 1000 0000,或是十六進位的 0080h。而由於它是二補數的有號二進位系統, -1℃ 的讀值就會是 1111 1111 1000 0000,或是 FF80h。

實務上,將這個 16-bit 暫存器的值當作有號整數,再用單精度或雙精度除法除以 80h,就會得到單位是 ℃ 的單精度或雙精度溫度值。

LM73 還可以設定測量的精確度,從 10-bit 到 13-bit。當精確度小於 13-bit 時,溫度讀值暫存器中沒有用到的 LSB 就永遠是 0。比方說我們把精度設定為 11-bit 的話,D3 和 D2 的讀值就永遠會是 0。

之所以要讓使用者決定它的轉換精確度,是因為不同精確度時,每次轉換所需要的時間不一樣。根據 LM73 的 datasheet,在 10-bit 精確度時,每次轉換所需要的時間最長是 14ms,但 13-bit 時,最長的轉換時間要 112ms,換句話說 LM73 在最高精度時可能一秒做不到 10 次溫度測量。因此它把精度或速度這個問題留給使用者自己決定。

如果我們要把 LM73 連接到 Arduino UNO 上,可以這樣接:

(圖片來源:Bird提供)

Arduino 的 I2C 通訊函式庫叫做 Wire,大部分跟 I2C 有關的通訊功能都在這個 library 裡面。Arduino 的 I2C 接腳是固定的,SCK 在 A5、SDA 在 A4,不能更改,因此要用 I2C 就只能照著圖上這樣接。

我們來寫一個簡單的程式讀取它的溫度暫存器。首先要在 setup() 裡告訴 Wire library,我們要使用 I2C 介面。

接下來就能用 Wire 裡面的功能對 LM37 下指令及讀取暫存器。

執行完上面那段程式後,reading 這個變數裡的值就會是 LM73 溫度暫存器的值。如我們前面說的,把這個值除以 0x80 (記得要用單精度或雙精度除法,不能用整數除法),就會得到單位為 ℃ 的溫度讀值。

從 LM73 的暫存器讀回來的值已經是結結實實的數字,它在 LM73 內部已經由 LM73 內建的 ADC 轉換完成了,而且 LM73 內部也有精確度非常好的 ADC 參考電壓,因此使用 LM73 來測量溫度時完全不會有收到電源電壓偏移、ADC 受到干擾等問題。你從它讀回來的數字就已經是溫度,乾淨俐落。這是這種數位介面溫度感測 IC 最大的好處。

溫度測量的注意事項

不管用哪種溫度測量 IC,你一定要記得,它的溫度測量裝置 (通常是一個類似二極體的元件) 都是在晶片上,而這個晶片則埋在 IC 的環氧樹脂封裝中。當環境溫度變化時,熱會在 IC 的封裝材料中流動,直到達到熱平衡為止,但在平衡之前,你可能會量到不正確的溫度。

比如說現在 IC 處在 25℃ 的熱平衡狀態,因此你會讀到 25℃。但如果你突然把溫度測量 IC 放到 100℃ 的環境中,雖然 IC 表面的溫度已經迅速變成 100℃,熱還來不及從外面傳到 IC 裡面,因此晶片上的溫度可能還離 100℃ 有一段距離。如果此時讀取 IC 的溫度,就不會讀到環境的正確溫度。

記住,你讀的永遠都是 IC 裡面晶片上的溫度,而不是 IC 表面的溫度。

小結

溫度感測 IC 是一個很常使用也非常成熟的產品,因此市場上可以選擇的產品非常多樣化。我們這次只是舉出兩個比較具有代表性的例子,向大家介紹不同介面的使用方法以及他們的優缺點。有興趣的讀者可以更深入地去研究這些 IC 的 datasheet 及相關的 application note,選擇最適合你設計的溫度感測 IC。

(責任編輯:謝長霖)

Bird

在外商圈電子業中闖蕩多年,經歷過 NXP、Sony、Crossmatch 等企業,從事無線通訊、影像系統、手機、液晶面板、半導體、生物辨識等不同領域產品開發。熱愛學習新事物,協助新創團隊解決技術問題。台大農機系、台科大電子所畢業,熱愛賞鳥、演奏管風琴、大提琴、法國號,亦是不折不扣的熱血 maker。
Bird

Author: Bird

在外商圈電子業中闖蕩多年,經歷過 NXP、Sony、Crossmatch 等企業,從事無線通訊、影像系統、手機、液晶面板、半導體、生物辨識等不同領域產品開發。熱愛學習新事物,協助新創團隊解決技術問題。台大農機系、台科大電子所畢業,熱愛賞鳥、演奏管風琴、大提琴、法國號,亦是不折不扣的熱血 maker。

Share This Post On
468 ad

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *