TCS3200顏色感測器測試實驗:
收藏自用,轉自:http://www.eefocus.com/zhang700309/blog/13-08/296390_6c438.html
TCS3200顏色感測器是一款全綵的顏色檢測器,包括了一塊TAOS TCS3200RGB感應晶片和4個白光LED燈,TCS3200能在一定的範圍內檢測和測量幾乎所有的可見光。它適合於色度計測量應用領域。比如彩色列印、醫療診斷、計算機彩色監視器校準以及油漆、紡織品、化妝品和印刷材料的過程控制。
通常所看到的物體顏色,實際上是物體表面吸收了照射到它上面的白光(日光)中的一部分有色成分,而反射出的另一部分有色光在人眼中的反應。白色是由各種頻率的可見光混合在一起構成的,也就是說白光中包含著各種顏色的色光(如紅R、黃Y、綠G、青V、藍B、紫P)。根據德國物理學家赫姆霍茲(Helinholtz)的三原色理論可知,各種顏色是由不同比例的三原色(紅、綠、藍)混合而成的。
由上面的三原色感應原理可知,如果知道構成各種顏色的三原色的值,就能夠知道所測試物體的顏色。對於TCS3200D 來說,當選定一個顏色濾波器時,它只允許某種特定的原色通過,阻止其它原色的通過。例如:當選擇紅色濾波器時,入射光中只有紅色可以通過,藍色和綠色都被阻止,這樣就可以得到紅色光的光強;同理,選擇其它的濾波器,就可以得到藍色光和綠色光的光強。通過這三個光強值,就可以分析出反射到TCS3200D感測器上的光的顏色。
TCS3200D感測器有紅綠藍和清除4種濾光器,可以通過其引腳S2和S3的高低電平來選擇濾波器模式,如下圖。
TCS3200D有可程式設計的彩色光到電訊號頻率的轉換器,當被測物體反射光的紅、綠、藍三色光線分別透過相應濾波器到達TAOS TCS3200RGB感應晶片時,其內建的振盪器會輸出方波,方波頻率與所感應的光強成比例關係,光線越強,內建的振盪器方波頻率越高。TCS3200感測器有一個OUT引腳,它輸出訊號的頻率與內建振盪器的頻率也成比例關係,它們的比率因子可以靠其引腳S0和S1的高低電平來選擇,如下圖。
這個測試實驗,我把TCS3200感測器OUT引腳輸出訊號頻率與其內建振盪器頻率比率因子設為2%,有了輸出頻率比例因子,但是如何通過OUT引腳輸出訊號頻率來換算出被測物體由三原色光強組成的RGB顏色值呢?這還需進行白平衡校正來得到RGB比例因子才行!
白平衡校正方法是:把一個白色物體放置在TCS3200顏色感測器之下,兩者相距10mm左右,點亮感測器上的4個白光LED燈,用Arduino控制器的定時器設定一固定時間1s,然後選通三原色的濾波器,讓被測物體反射光中紅、綠、藍三色光分別通過濾波器,計算1s時間內三色光對應的TCS3200感測器OUT輸出訊號脈衝數(單位時間的脈衝數包含了輸出訊號的頻率資訊),再通過正比算式得到白色物體RGB值255與三色光脈衝數的比例因子。有了白平衡校正得到的RGB比例因子,則其它顏色物體反射光中紅、綠、藍三色光對應的TCS3200輸出訊號1s內脈衝數乘以R、G、B比例因子,就可換算出了被測物體的RGB標準值了。
現在談談,如何進行TCS3200各控制引腳與Arduino控制器的硬體連線問題,下圖分別是TCS3200感測器和其連線圖。
上圖中TCS3200感測器各控制引腳與Arduino控制器數字埠連線的對應關係,我設定為:
#define S0 6
#define S1 5
#define S2 4
#define S3 3
#define OUT 2
#define LED 7
當被測物體為不發光物體時,應該把TCS3200的LED引腳設定為高電平,以點亮TCS3200感測器電路板上的四個白光LED燈。
下文展示了一個帶有白平衡的測試程式,把這個程式下載到Arduino控制器中,同時把一個白色物體放置在TCS3200顏色感測器之下,點亮感測器上的4個白光LED燈,再開啟Arduino IDE的串列埠監視器,會出現下圖監視畫面,可以在該畫面中找到白色物體RGB值255以及RGB比例因子。(可通過QQ截圖來鎖定畫面,以便觀察。)(雙擊圖片,可以放大看!)
把白平衡時放置在TCS3200顏色感測器之下白色物體拿走,放上另一個黃色物體,在Arduino IDE串列埠監視器看到的這個黃色物體RGB值為233、157、56,如下圖所示。
開啟電腦Windows作業系統自帶的畫圖板,點選選單欄“顏色”--->“編輯顏色”--->“規定自定義顏色”-->右下角輸入RGB值,檢視對應的顏色與實際測試的顏色是否相符。實際測試結果是測得的物體顏色與實際顏色有些偏色,但並不影響區分出被測物體是哪種顏色的物體。
介紹完TCS3200感測器顏色識別原理和其與Arduino控制器的硬體連線,以及如何利用串列埠監視器找到白平衡後的比例因子和被測物體的RGB值。下面展示的是Arduino測試程式。注意:下面的#include 《TimerOne.h> 要改為單括號形式。
Arduino程式:
-
#include 《TimerOne.h> //申明庫檔案
-
//把TCS3200顏色感測器各控制引腳連到Arduino數字埠
-
#define S0 6 //物體表面的反射光越強,TCS3002D內建振盪器產生的方波頻率越高,
-
#define S1 5 //S0和S1的組合決定輸出訊號頻率比例因子,比例因子為2%
-
//比率因子為TCS3200感測器OUT引腳輸出訊號頻率與其內建振盪器頻率之比
-
#define S2 4 //S2和S3的組合決定讓紅、綠、藍,哪種光線通過濾波器
-
#define S3 3
-
#define OUT 2 //TCS3200顏色感測器輸出訊號連線到Arduino中斷0引腳,並引發脈衝訊號中斷
-
//在中斷函式中記錄TCS3200輸出訊號的脈衝個數
-
#define LED 7 //控制TCS3200顏色感測器是否點亮LED燈
-
float g_SF[3]; //從TCS3200輸出訊號的脈衝數轉換為RGB標準值的RGB比例因子
-
int g_count = 0; // 計算與反射光強相對應TCS3200顏色感測器輸出訊號的脈衝數
-
// 陣列用於儲存在1s內TCS3200輸出訊號的脈衝數,它乘以RGB比例因子就是RGB標準值
-
int g_array[3];
-
int g_flag = 0; // 濾波器模式選擇順序標誌
-
// 初始化TSC3200各控制引腳的輸入輸出模式
-
//設定TCS3002D的內建振盪器方波頻率與其輸出訊號頻率的比例因子為2%
-
void TSC_Init()
-
{
-
pinMode(S0, OUTPUT);
-
pinMode(S1, OUTPUT);
-
pinMode(S2, OUTPUT);
-
pinMode(S3, OUTPUT);
-
pinMode(OUT, INPUT);
-
pinMode(LED, OUTPUT);
-
digitalWrite(S0, LOW);
-
digitalWrite(S1, HIGH);
-
}
-
//選擇濾波器模式,決定讓紅、綠、藍,哪種光線通過濾波器
-
void TSC_FilterColor(int Level01, int Level02)
-
{
-
if(Level01 != 0)
-
Level01 = HIGH;
-
if(Level02 != 0)
-
Level02 = HIGH;
-
digitalWrite(S2, Level01);
-
digitalWrite(S3, Level02);
-
}
-
//中斷函式,計算TCS3200輸出訊號的脈衝數
-
void TSC_Count()
-
{
-
g_count ++ ;
-
}
-
//定時器中斷函式,每1s中斷後,把該時間內的紅、綠、藍三種光線通過濾波器時,
-
//TCS3200輸出訊號脈衝個數分別儲存到陣列g_array[3]的相應元素變數中
-
void TSC_Callback()
-
{
-
switch(g_flag)
-
{
-
case 0:
-
Serial.println("->WB Start");
-
TSC_WB(LOW, LOW); //選擇讓紅色光線通過濾波器的模式
-
break;
-
case 1:
-
Serial.print("->Frequency R=");
-
Serial.println(g_count); //列印1s內的紅光通過濾波器時,TCS3200輸出的脈衝個數
-
g_array[0] = g_count; //儲存1s內的紅光通過濾波器時,TCS3200輸出的脈衝個數
-
TSC_WB(HIGH, HIGH); //選擇讓綠色光線通過濾波器的模式
-
break;
-
case 2:
-
Serial.print("->Frequency G=");
-
Serial.println(g_count); //列印1s內的綠光通過濾波器時,TCS3200輸出的脈衝個數
-
g_array[1] = g_count; //儲存1s內的綠光通過濾波器時,TCS3200輸出的脈衝個數
-
TSC_WB(LOW, HIGH); //選擇讓藍色光線通過濾波器的模式
-
break;
-
case 3:
-
Serial.print("->Frequency B=");
-
Serial.println(g_count); //列印1s內的藍光通過濾波器時,TCS3200輸出的脈衝個數
-
Serial.println("->WB End");
-
g_array[2] = g_count; //儲存1s內的藍光通過濾波器時,TCS3200輸出的脈衝個數
-
TSC_WB(HIGH, LOW); //選擇無濾波器的模式
-
break;
-
default:
-
g_count = 0; //計數值清零
-
break;
-
}
-
}
-
//設定反射光中紅、綠、藍三色光分別通過濾波器時如何處理資料的標誌
-
//該函式被TSC_Callback( )呼叫
-
void TSC_WB(int Level0, int Level1)
-
{
-
g_count = 0; //計數值清零
-
g_flag ++; //輸出訊號計數標誌
-
TSC_FilterColor(Level0, Level1); //濾波器模式
-
Timer1.setPeriod(1000000); //設定輸出訊號脈衝計數時長1s
-
}
-
//初始化
-
void setup()
-
{
-
TSC_Init();
-
Serial.begin(9600); //啟動序列通訊
-
Timer1.initialize(); // defaulte is 1s
-
Timer1.attachInterrupt(TSC_Callback); //設定定時器1的中斷,中斷呼叫函式為TSC_Callback()
-
//設定TCS3200輸出訊號的上跳沿觸發中斷,中斷呼叫函式為TSC_Count()
-
attachInterrupt(0, TSC_Count, RISING);
-
digitalWrite(LED, HIGH);//點亮LED燈
-
delay(4000); //延時4s,以等待被測物體紅、綠、藍三色在1s內的TCS3200輸出訊號脈衝計數
-
//通過白平衡測試,計算得到白色物體RGB值255與1s內三色光脈衝數的RGB比例因子
-
g_SF[0] = 255.0/ g_array[0]; //紅色光比例因子
-
g_SF[1] = 255.0/ g_array[1] ; //綠色光比例因子
-
g_SF[2] = 255.0/ g_array[2] ; //藍色光比例因子
-
//列印白平衡後的紅、綠、藍三色的RGB比例因子
-
Serial.println(g_SF[0],5);
-
Serial.println(g_SF[1],5);
-
Serial.println(g_SF[2],5);
-
//紅、綠、藍三色光分別對應的1s內TCS3200輸出脈衝數乘以相應的比例因子就是RGB標準值
-
//列印被測物體的RGB值
-
for(int i=0; i<3; i++)
-
Serial.println(int(g_array[i] * g_SF[i]));
-
}
-
//主程式
-
void loop()
-
{
-
g_flag = 0;
-
//每獲得一次被測物體RGB顏色值需時4s
-
delay(4000);
-
//打印出被測物體RGB顏色值
-
for(int i=0; i<3; i++)
-
Serial.println(int(g_array[i] * g_SF[i]));
-
}
程式中的標頭檔案TimerOne.h檔案請下載:https://github.com/PaulStoffregen/TimerOne(文章原連結,這是我找到的)
上面是帶有白平衡的測試程式,對於具體專案的應用程式,要在此基礎上加以變動。
如果TCS3200感測器與被測物體的檢測距離以及周圍環境光線沒有發生大的變化,進行一次白平衡校正後,RGB比例因子就可以確定下來了。於是您一定要把得到的RGB比例因子直接替代掉紅色字型標識程式段中的陣列g_array[3]各元素變數。另外綠色字型標識的程式段也可以註釋掉。
在具體專案中,您所檢測的是某種特定顏色的物體,可能就像文章的第一張圖片展示的5個色塊類似,絕不會有連續變化顏色的物體。於是,應該以上述程式獲得的被測物體顏色R、G、B值為中心,設定一個距離中心值±20的範圍值,在任何環境光條件下,再次檢測被測物體的RGB值,只要RGB值落在範圍內,就可以認為被測物體是那種特定顏色的物體。這樣設定顏色值範圍的方法,可以有效提高物體顏色的識別率。