作者:Bird
在一些 maker project 中,常常會有感應物體色彩的需求。要讓我們的 project「看」東西,最直接的方法當然是幫它裝個 CMOS image sensor,但如果我們只需要簡單識別物體的色彩,而不需要真的做影像識別等高階的功能,用 CMOS image sensor 反而把事情複雜化了。這時候,簡單的色彩感測器就可以幫我們解決問題。這次我們就來聊聊色彩感測器的原理,以及它的應用。
顔色怎麽來的
嚴格來說,是要讓機器看到「人眼看到的顔色」,所以必須要先知道人眼看到的顔色是怎麽來的。地球上確實有些其它的動物,看到的顔色跟人看到的不一樣。人類是所謂的「三色視覺」動物,也就是說我們的彩色視覺由三種顔色所支配。寫到這,應該有很多讀者已經猜到這三種顔色就是我們一天到晚在講的 R、G、B。
沒錯,在人眼的視網膜上,有兩種細胞,一種是可以感應顏色的視錐細胞(cone cell),而另一種是無法感應顔色但對光線較爲敏感、可以在低照度時工作的視桿細胞(rod cell)。視錐細胞又分成三種,分別稱之爲 S、M、L 視錐細胞,而這裡的 S、M、L,指的就是不同的視錐細胞對不同波長的光有不同的感度。

三種視錐細胞所能感應的光波波長和最敏感的峰值波長
如果在光譜上來看的話,三種視錐細胞的感度是這樣的:

光譜上三種視錐細胞的感度
不同波長的光進入人類的眼睛後,在不同的視錐細胞上會產生不同強度的訊號,這些訊號經由神經系統傳送到大腦,再經過大腦的處理,就變成我們看到的顏色了。
比如,有個東西它只反射 600 nm 的紅光,這個光線進到人眼之後,只會讓 L 視錐細胞感應到。因此,大腦只收到來自 L 視錐細胞的訊號,判定這個顔色是紅色;如果只有 M 視錐細胞有訊號,大腦就會知道是綠色;如果 L 和 M 視錐細胞都同時有訊號,大腦就知道這是介於兩者之間的黃色。
問題來了,大腦怎麽知道眼睛看到的黃色,是一個波長 600 nm 左右的黃色光,還是兩個分別爲 620 nm 的紅光和 560 nm 的綠光混出來的呢?這兩個組合都會同時刺激 L 和 M 視錐細胞。
「它不知道。」對,人類的眼睛的確無法分辨這個黃色到底是單一波長的黃光,還是由紅色和綠色混在一起所產生的黃光。這個現象叫「同色異譜」,意思就是說不同的光譜組成,但是在人眼看起來是一樣的顔色。
雖然人的眼睛看起來是一樣的顔色,但如果用光譜儀去測量的話,還是可以分得出來它們的光譜組成是不一樣的。
這個機制常常被用來欺騙人類的眼睛。舉例來説,如果你需要一個白的的光,通常需要用紅、藍、綠三種顔色的光去混出來,因爲對人類的大腦來説,只要 S、M、L 三種視錐細胞都有訊號,就代表這是白光。但就如我們前面説的,某個波長的黃光可以同時刺激 L 和 M 視錐細胞,因此如果你用藍光和黃光去混,也會讓大腦覺得這是白光。
現在的白光 LED,用的多半是這種方法:先發個藍光,再用藍光去激發黃色的螢光粉發出黃光,一藍一黃就混出了我們看起來是白光的光。但這樣的白光有一個問題,就是它裡面其實沒什麽紅光,如果你用它去照射只會反射紅光、顔色看起來應該要非常紅的物體,它看起來就會不夠紅,因爲它本來就沒有紅光可供反射。這是色彩學上所説的「演色性」問題。
這邊只能簡單地説明一下人眼看到顔色的機制,以上這些如果要仔細説明,每個主題大概都可以寫個五萬字。
讓機器看到光
要讓機器看到光,最常用的就是所謂的光電轉換元件。
十九世紀物理學大爆發的時候,物理學家觀察到,當光照射在某些金屬上時,會產生電流,這就是所謂的光電效應(photoelectric effect)。但一直到 1905 年愛因斯坦發表了關於光電效應的論文「Concerning an Heuristic Point of View Toward the Emission and Transformation of Light」,套用了普朗克對於光粒子性的假設,解釋了光電效應與光波長之間的關係,才確立了光電效應的量化基礎。愛因斯坦也因為這篇論文得到了 1921 年的諾貝爾物理學獎。
雖然愛因斯坦對近代物理的貢獻絕對值得好幾座諾貝爾獎,但他得到的唯一一座諾貝爾獎卻不是因爲相對論,而是跟光電效應有關。光電效應告訴我們,每個光子攜帶的能量只與它的波長有關,與光的強度無關。而不同的物質要在光電效應之下產生訊號,它所能感應的波長範圍,也只和該物質的電子組態有關。換句話説,有些物質就是只對某些波長的光有反應,在此波長之外它就是瞎的。
這裡有一個美麗的巧合。二十世紀半導體技術大爆發之後,我們最常用的半導體材料就是矽,而矽的電子組態剛好讓用它做成的光電二極體可以感應波長 400 nm – 1100 nm 的光,差不多涵蓋了整個人眼可見的可見光波長,再附贈一點點近紅外線。這個美麗的巧合讓我們可以用矽半導體做成各式各樣的感光元件,而不用另尋其它特殊的材料與製程。
我們來看看實際的零件吧。
TCS 3200 色彩感測器
TAOS(Texas Advanced Optoelectronic Solutions)公司的色彩感測器 TCS 3200 是一顆很常用的色彩感測器,市面上也很容易買到它的 Arduino 模組。(TAOS 已於 2011 年被奧地利微電子 AMS 收購,成爲其中一條產品線,但習慣上仍稱之爲 TAOS)。

基本款的 TC 3200
也有另一種不帶遮光罩的型式,長這樣:

不帶遮光罩的 TC 3200
沒有遮光罩的板子可以讓我們看清楚 TCS 3200 長什麽樣子。它就是一顆亮晶晶的、透明的 IC,就像水族館裡看到道的透明魚一樣,肚子裡有什麽都被看的一清二楚。
TCS 3200 的感測核心是一個 8×8 的光電二極體陣列。這 64 顆光電二極體又被分成四組:其中 16 顆感應紅光、16 顆感應綠光、16 顆感應藍光、最後 16 顆則全波長都有反應。
原廠的規格書上有畫出它的感應頻譜:

TCS 3200 的感應頻譜
這張圖告訴我們,TCS 3200 裡的四種光電二極體對不同波長光的反應。如果不看 700 nm 以上的區域,這個曲線看起來是不是和前面説的,人眼的感應光譜有幾分相似呢?
如果我們只看黑色的那條曲線,它代表的就是矽光電二極體對不同波長光線的反應。可以看到它大概從 350 nm 開始對光有反應,一直延伸到 1100 nm 左右的近紅外線。我們只要在光電二極體上加上只透過長波長的紅色濾光鏡,就可以讓光電二極體只感應長波長的光,於是就得到了圖上的紅色曲線。綠色和藍色的曲線亦然。
由於常用的彩色濾光片材料都無法濾掉紅外線,而且矽光電二極體又對近紅外線有反應,因此可以看到不管是感應哪個顏色的光電二極體,到了 700 nm 以上的感度都會迅速增加。
如果待測的光線中含有 700 nm 以上的近紅外線,爲了避免它干擾顔色的判斷,實務上都要另外加一片濾光鏡將 700 nm 以上的近紅外線濾掉,否則只要有這個波長的光出現,它就會讓三種二極體都有訊號。在大部分的數位相機中,都有這樣一片濾光鏡,稱之爲 IR-cut filter。
這三種光電二極體的感應波長安排,就是爲了模擬人眼對不同波長光線的感應能力。由於我們常用的 R、G、B 數位色彩系統是依照人眼色三色視覺模式設計的,只要有了 R、G、B 的數值,就很容易做後續的計算了。
光電二極體的輸出是電流,但電流不方便數位電路測量,因此TCS 3200 很貼心地内建了一個電流對頻率的轉換電路。

TCS 3200 有内建一個電流對頻率的轉換電路
在不飽和的狀況下,TCS 3200 輸出的最大頻率是 600 KHz。由於數百 KHz 左右的頻率測量對一些較慢的 MCU 來說其實有相當的困難,因此 TCS 3200 内部也提供了除頻的功能,藉由 S0/S1 兩隻腳的設定,可以讓輸出頻率除以 5(S0 = H, S1 = L)或除以 50(S0 = L, S1 = H),以方便速度較慢的 MCU 測量頻率。
而 S2/S3 這兩隻腳則是用來選擇現在輸出的訊號來自哪一組光電二極體:

S2/S3 用來選擇輸出的訊號來自哪一組光電二極體
在 Arduino 上要測量頻率,有個常用的 library 叫做 FreuCount。在 ATmega 328 的 Arduino 平台上,它在 1KHz 到 8MHz 這個區間的效果最好,因此拿來測量 TCS 3200 的輸出是沒有問題的。
實戰
我們實際來把 TCS 3200 模組接上 Arduino 試試看。常見的 TCS 3200 模組上有這些接腳:

TCS 3200 模組上常見的接腳,分別負責特定的功能
與 Arduino 的連接非常簡單。以 Arduino UNO 爲例,電路是這樣:

Arduino UNO 電路示意圖
這邊要注意的是,其它的腳如 S0-S3 或 OE 接到哪個 digital I/O 都可以,只要在程式中做對應的設定就好,但 OUT 腳一定要接到 D5,因爲 Arduino 硬體上的限制, FreqCount 這個 library 只能用這隻腳測量頻率。
簡單的範例程式碼如下:
void setup() {
pinMode(0, OUTPUT); // S0
pinMode(1, OUTPUT); // S1
pinMode(2, OUTPUT); // S2
pinMode(3, OUTPUT); // S3
pinMode(4, OUTPUT); // OE
pinMode(5, INPUT); // OUT, should be input on Arduino
pinMode(6, OUTPUT); // LED
digitalWrite(0, HIGH); // S0 = high
digitalWrite(1, HIGH); // S1 = high
digitalWrite(4, HIGH); // OE = low
digitalWrite(6, HIGH); // turn on illumination LED
Serial.begin(57600);
FreqCount.begin(1000);
}
void loop() {
// measuring green channel
digitalWrite(2, HIGH); // S2 = high
digitalWrite(3, HIGH); // S3 = high
if (FreqCount.available()) {
unsigned long count = FreqCount.read(); //frequency measurement
Serial.println(count);
}
這段程式碼做的事很簡單:先把對應的 GPIO 接腳設定好,並將 S0/S1 設成 100% 頻率輸出,然後將照明的 LED 打開。
接下來就將 S2/S3 設定到紅光的 channel,然後用 FreqCount 測量 pin5 上輸入的頻率,並將結果顯示在 UART 上。
只要改變 S2/S3 的狀態,並重複這個過程,就可以讀取藍色、綠色通道的輸出。有了三個通道的數值,也就是 R、G、B 值,就可以計算目標物的顏色了。
小結
這次介紹的範例,只是讓各位知道 TCS 3200 色彩感測器要如何與 Arduino 連接、如何從它讀取跟顔色有關的數值。接下來要怎麽應用,用在什麽樣的 project,就留待各位 maker 發揮了。
(責任編輯:葉于甄)
- 【Maker電子學】Flash 記憶體的原理與應用—PART22 - 2025/02/27
- 【Maker電子學】Flash 記憶體的原理與應用—PART21 - 2025/02/21
- 【Maker電子學】Flash 記憶體的原理與應用—PART20 - 2025/01/24
訂閱MakerPRO知識充電報
與40000位開發者一同掌握科技創新的技術資訊!
2019/05/28
感謝您的熱心分享光電色彩感應知識,原本我是在了解變色龍的變色原理,想以仿生的思維來應用此生物機能於可能的領域。