37款傳感器與執行器的提法,在網絡上廣泛流傳,其實Arduino能夠兼容的傳感器模塊肯定是不止這37種的。鑒於本人手頭積累了一些傳感器和執行器模塊,依照實踐出真知(一定要動手做)的理念,以學習和交流為目的,這里准備逐一動手嘗試系列實驗,不管成功(程序走通)與否,都會記錄下來---小小的進步或是搞不掂的問題,希望能夠拋磚引玉。
【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
實驗六十三: TCS3200D顏色識別傳感器(可編程彩色光頻識別轉換器模塊)

TCS3200D
是TAOS(Texas Advanced Optoelectronic Solutions)公司推出的可編程彩色光到頻率的轉換器。它把可配置的硅光電二極管與電流頻率轉換器集成在一個單一的CMOS電路上,同時在單一芯片上還集成了紅綠藍(RGB)三種濾光器,是業界第一個有數字兼容接口的RGB彩色傳感器。TCS3200D的輸出信號是數字量,可以驅動標准的TTL或CMOS邏輯輸入,因此可直接與微處理器或其它邏輯電路相連接。由於輸出的是數字量,並且能夠實現每個彩色信道10位以上的轉換精度,因而不再需要A/D轉換電路,使電路變得更簡單。該顏色傳感器主要可用於尿液分析儀,生化分析儀,驗鈔機等需要檢測顏色的產品上。

三原色
三原色指色彩中不能再分解的三種基本顏色,我們通常說的三原色,即品紅、黃、青(是青不是藍,藍是品紅和青混合的顏色) 。三原色可以混合出所有的顏色,同時相加為黑色,黑白灰屬於無色系。色光三原色是指紅、綠、藍三色,各自對應的波長分別為700nm,546.1nm,435.8nm,光的三原色和物體的三原色是不同的。光的三原色,按一定比例混合可以呈現各種光色。根據托馬斯·楊和赫爾姆豪茲的研究結果.這三種原色確定為紅、綠、藍(相當於顏料中的大紅、中綠、群青(紫藍)的色彩感覺)。彩色電視屏幕就是由這紅、綠、藍三種發光的顏色小點組成的。由這三原色按照不同比例和強弱混合.可以產生自然界的各種色彩變化。顏料和其他不發光物體的三原色是品紅(相當於玫瑰紅、桃紅)、品青(相當於較深的天藍、湖藍)、淺黃(相當於檸檬黃)。由英國化學家富勃斯特(1781—1868)研究選定的這三原色可以混合出多種多樣的顏色,不過不能調配出黑色,只能混合出深灰色。

色相
是色彩的首要特征,是區別各種不同色彩的最准確的標准。事實上任何黑白灰以外的顏色都有色相的屬性,而色相也就是由原色、間色和復色來構成的。色相,色彩可呈現出來的質地面貌。自然界中各個不同的色相是無限豐富的,如紫紅、銀灰、橙黃等。色相即各類色彩的相貌稱謂。
色相環(color circle)
是指一種圓形排列的色相光譜(SPECTRUM),色彩是按照光譜在自然中出現的順序來排列的。暖色(WARM COLOR)位於包含紅色和黃色的半圓之內,冷色則包含在綠色和紫色的那個半圓內。互補色(COMPLEMENTARY COLOR)出現在彼此相對的位置上。


三原色原理
人眼對紅、綠、藍最為敏感,人的眼睛像一個三色接收器的體系,大多數的顏色可以通過紅、綠、藍三色按照不同的比例合成產生。同樣,絕大多數單色光也可以分解成紅、綠、藍三種色光,這是色度學的最基本的原理,也稱三原色原理。白光通過棱鏡后被分解成多種顏色逐漸過渡的色譜,顏色依次為紅、橙、黃、綠、青、藍、紫,這就是可見光譜。其中人眼對紅、綠、藍最為敏感,人的眼睛就像一個三色接收器的體系,大多數的顏色可以通過紅、綠、藍三色按照不同的比例合成產生。同樣絕大多數單色光也可以分解成紅綠藍三種色光。這是色度學的最基本原理,即三基色原理。三種基色是相互獨立的,任何一種基色都不能有其它兩種顏色合成。紅綠藍是三基色,這三種顏色合成的顏色范圍最為廣泛。紅綠藍三基色按照不同的比例相加合成混色稱為相加混色。
紅色+綠色=黃色
綠色+藍色=青色
紅色+藍色=品紅
紅色+綠色+藍色=白色

TCS3200是TAOS公司推出的可編程彩色光到頻率的轉換器,它把可配置的硅光電二極管與電流頻率轉換器集成在一個單一的CMOS電路上,同時在單一芯片上集成了紅綠藍(RGB)三種濾光器,是業界第一個有數字兼容接口的RGB彩色傳感器,TCS3200的輸出信號是數字量,可以驅動標准的TTL或CMOS邏輯輸入,因此可直接與微處理器或其他邏輯電路相連接,由於輸出的是數字量,並且能夠實現每個彩色信道10位以上的轉換精度,因而不再需要A/D轉換電路,使電路變得更簡單,TCS3200的引腳圖


TCS3200采用8引腳的SOIC表面貼裝式封裝,在單一芯片上集成有64個光電二極管,這些二極管分為四種類型,其16個光電二極管帶有紅色濾波器;16個光電二極管帶有綠色濾波器;16個光電二極管帶有藍色濾波器,其余16個不帶有任何濾波器,可以透過全部的光信息,這些光電二極管在芯片內是交叉排列的,能夠最大限度地減少入射光輻射的不均勻性,從而增加顏色識別的精確度;另一方面,相同顏色的16個光電二極管是並聯連接的,均勻分布在二極管陣列中,可以消除顏色的位置誤差。工作時,通過兩個可編程的引腳來動態選擇所需要的濾波器,該傳感器的典型輸出頻率范圍從2Hz-500kHz,用戶還可以通過兩個可編程引腳來選擇100%、20%或2%的輸出比例因子,或電源關斷模式。輸出比例因子使傳感器的輸出能夠適應不同的測量范圍,提高了它的適應能力。例如,當使用低速的頻率計數器時,就可以選擇小的定標值,使TCS3200的輸出頻率和計數器相匹配。


TCS3200識別顏色的原理
由上面的三原色感應原理可知,如果知道構成各種顏色的三原色的值,就能夠知道所測試物體的顏色。對於TCS3200 來說,當選定一個顏色濾波器時,它只允許某種特定的原色通過,阻止其它原色的通過。例如:當選擇紅色濾波器時,入射光中只有紅色可以通過,藍色和綠色都被阻止,這樣就可以得到紅色光的光強;同理,選擇其它的濾波器,就可以得到藍色光和綠色光的光強。通過這三個值,就可以分析投射到TCS3200 傳感器上的光的顏色。TCS3200這種可編程的彩色光到頻率轉換器適合於色度計測量應用領域,如彩色打印、醫療診斷、計算機彩色監視器校准以及油漆、紡織品、化妝品和印刷材料的過程控制和色彩配合。
白平衡和顏色識別原理
白平衡就是告訴系統什么是白色。從理論上講,白色是由等量的紅色、綠色和藍色混合而成的;但實際上,白色中的三原色並不完全相等,並且對於 TCS3200 的光傳感器來說,它對這三種基本色的敏感性是不相同的,導致TCS3200 的RGB 輸出並不相等,因此在測試前必須進行白平衡調整,使得TCS3200 對所檢測的“白色”中的三原色是相等的。進行白平衡調整是為后續的顏色識別作准備。在本裝置中,白平衡調整的具體步驟和方法如下:將空的試管放置在傳感器的上方,試管的上方放置一個白色的光源,使入射光能夠穿過試管照射到TCS3200 上;根據前面所介紹的方法,依次選通紅色、綠色和藍色濾波器,分別測得紅色、綠色和藍色的值,然后就可計算出需要的三個調整參數。

TCS3200D顏色識別傳感器(可編程彩色光頻識別轉換器模塊)
主要參數
- 尺寸:37*37mm
- 固定孔:3mm
- 孔距:22.6*22.6mm
- 電壓:5V
- 芯片:TCS3200D
- 端口:數字量
- 輸出:10-12KHz,占空比50%
- 檢測距離:10mm
- 平台:Arduino 單片機
主要特點
- 輸出占空比50%
- 所有的引腳全部引出
- 采用TCS3200D,性能優於TCS230D
- 所有IO全部引出,可控式LED補光燈
- 通過程序可以讀取顏色的RGB值
- 適用於靜態物體顏色的檢測
- 注意:不能檢測燈光的顏色
- 檢測距離1厘米最佳
- 檢測有效距離小於等於5厘米
- 可直接和單片機連接
- 采用高亮白色LED燈反射光
- 靜態識別物體顏色,不同顏色輸出不同頻率

模塊電原理圖


模塊接線
Arduino Uno <-----> TSC3200顏色傳感器
Pin 6 <-----> S0
Pin 5 <-----> S1
Pin 4 <-----> S2
Pin 3 <-----> S3
Pin 2 <-----> OUT
5V <-----> VCC
GND <-----> GND

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顏色傳感器之下,兩者相距10mm左右,點亮傳感器上的4個白光LED燈,用Arduino控制器的定時器設置一固定時間1s,然后選通三原色的濾波器,讓被測物體反射光中紅、綠、藍三色光分別通過濾波器,計算1s時間內三色光對應的TCS3200傳感器OUT輸出信號脈沖數(單位時間的脈沖數包含了輸出信號的頻率信息),再通過正比算式得到白色物體RGB值255與三色光脈沖數的比例因子。有了白平衡校正得到的RGB比例因子,則其它顏色物體反射光中紅、綠、藍三色光對應的TCS3200輸出信號1s內脈沖數乘以R、G、B比例因子,就可換算出了被測物體的RGB標准值了。

安裝程序中的TimerOne.h庫文件的二種辦法
1、請下載:
https://github.com/PaulStoffregen/TimerOne

2、安裝TimerOne庫:IDE—工具—管理庫—搜索TimerOne—安裝

/*
【Arduino】168種傳感器模塊系列實驗(63)
實驗六十三: TCS3200D顏色識別傳感器(可編程彩色光頻識別轉換器模塊)
安裝TimerOne庫:IDE—工具—管理庫—搜索TimerOne—安裝
*/
#include <TimerOne.h>//申明庫文件
//把TCS3200顏色識別傳感器各控制引腳連到Arduino數字端口
#define S0 6 //物體表面的反射光越強,TCS3200內置震盪器產生的方波頻率越高,
#define S1 5 //SO和S1的組合決定輸出信號頻率比例因子,比例因子為2%
//比例因子為TCS3200傳感器OUT引腳輸出信號頻率與其內置振盪器頻率之比
#define S2 4 //S2和S3的組合決定讓紅、綠、藍,哪種光線通過濾波器
#define S3 3
#define OUT 2 //TCS3200顏色傳感器輸出信號
//在中斷函數中紀錄TCS3200輸出信號的脈沖個數
int g_count = 0; // 計算與反射光相對應TCS3200顏色傳感器輸出信號的脈沖數
int g_array[3]; // 存儲RGB值
int g_flag = 0; // 濾波器模式選擇順序標志
float g_SF[3]; // 從TCS3200輸出信號的脈沖數轉換為RGB標准值的RGB比例因子
//初始化TSC3200各控制引腳的輸入輸出模式
//設置TCS3200的內置振盪器方波頻率與其輸出信號頻率的比例因子為2%
void TSC_Init()
{
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(OUT, INPUT);
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) //White Balance
{
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缺省是1秒
Timer1.attachInterrupt(TSC_Callback); //設置定時器1的中斷,中斷調用函數為TSC_Callbace()
//設置TCS3200輸出信號的上跳沿觸發中斷,中斷調用函數為TSC_Count()
attachInterrupt(0, TSC_Count, RISING);
delay(4000); //延時4s,以等待被測物體紅、綠、藍三色在1s內的TCS3200輸出信號脈沖計數
//通過白平衡測試,計算得到白色物體RGB值255與1s內三色光脈沖數的RGB比例因子
for(int i=0; i<3; i++)
Serial.println(g_array);
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]);
Serial.println(g_SF[1]);
Serial.println(g_SF[2]);
}
//紅、綠、藍三色光分別對應的1s內TCS3200輸出脈沖數乘以相應的比例因子就是RGB標准值
//打印被測物體的RGB值
void loop()
{
g_flag = 0;//每獲得一次被測物體的RGB顏色值時需要4s
for(int i=0; i<3; i++) //打印被測物體的RGB值
Serial.println(int(g_array * g_SF));
delay(4000);
}
識別接近灰白色的串口輸出數據

白色的串口數據






實驗仿真編程(linkboy3.6)

三種原色的波形,都是255一條線的是白色

在具體項目中,您所檢測的是某種特定顏色的物體,可能就像前面圖片展示的幾種顏色類似,絕不會有連續變化顏色的物體。於是,應該以上述程序獲得的被測物體顏色R、G、B值為中心,設置一個距離中心值±20的范圍值,在任何環境光條件下,再次檢測被測物體的RGB值,只要RGB值落在范圍內,就可以認為被測物體是那種特定顏色的物體。這樣設定顏色值范圍的方法,可以有效提高物體顏色的識別率。
/*
【Arduino】168種傳感器模塊系列實驗(64)
實驗六十四: TCS3200D顏色識別傳感器(可編程彩色光頻識別轉換器模塊)
實驗程序之二:實現簡單顏色感應
實驗模塊接線
Arduino Uno <-----> TSC3200顏色傳感器
Pin 6 <-----> S0
Pin 5 <-----> S1
Pin 4 <-----> S2
Pin 3 <-----> S3
Pin 2 <-----> OUT
5V <-----> VCC
GND <-----> GND
*/
#define S0 6
#define S1 5
#define S2 4
#define S3 3
#define sensorOut 2
int frequency = 0;
void setup() {
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(sensorOut, INPUT);
// 將頻率縮放設置為20%
digitalWrite(S0, HIGH);
digitalWrite(S1, LOW);
Serial.begin(9600);
}
void loop() {
// 設置要讀取的紅色濾波光電二極管
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
// 讀取輸出頻率
frequency = pulseIn(sensorOut, LOW);
frequency = map(frequency,-10, -49, 255, 0);
// 在串行監視器上打印值
Serial.print("R= ");//打印名稱
Serial.print(frequency);//打印紅色頻率
Serial.print(" ");
delay(2000);
// 設置要讀取的綠色過濾光電二極管
digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
// 讀取輸出頻率
frequency = pulseIn(sensorOut, LOW);
frequency = map(frequency,-10, -50, 255, 0);
//在串行監視器上打印值
Serial.print("G= ");//打印名稱
Serial.print(frequency);//打印綠色頻率
Serial.print(" ");
delay(2000);
// 設置要讀取的藍色濾光光電二極管
digitalWrite(S2, LOW);
digitalWrite(S3, HIGH);
// 讀取輸出頻率
frequency = pulseIn(sensorOut, LOW);
frequency = map(frequency,-10, -41, 255, 0);
// 在串行監視器上打印值
Serial.print("B= ");//打印名稱
Serial.print(frequency);//打印藍色頻率
Serial.println(" ");
delay(2000);
}


/*
【Arduino】168種傳感器模塊系列實驗(64)
實驗六十四: TCS3200D顏色識別傳感器(可編程彩色光頻識別轉換器模塊)
實驗程序之三:顏色識別感應
實驗模塊接線
Arduino Uno <-----> TSC3200顏色傳感器
Pin 6 <-----> S0
Pin 5 <-----> S1
Pin 4 <-----> S2
Pin 3 <-----> S3
Pin 2 <-----> OUT
5V <-----> VCC
GND <-----> GND
*/
int s0 = 6, s1 = 5, s2 = 4, s3 = 3;
int out = 2;
int flag = 0;
byte counter = 0;
byte countR = 0, countG = 0, countB = 0;
void setup()
{
Serial.begin(115200);
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);
}
void TCS()
{
flag = 0;
digitalWrite(s1, HIGH);
digitalWrite(s0, HIGH);
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
attachInterrupt(0, ISR_INTO, CHANGE);
timer0_init();
}
void ISR_INTO()
{
counter++;
}
void timer0_init(void)
{
TCCR2A = 0x00;
TCCR2B = 0x07; //時鍾頻率源1024點
TCNT2 = 100; //10毫秒再次溢出
TIMSK2 = 0x01; //允許中斷
}
int i = 0;
ISR(TIMER2_OVF_vect)
//計時器2,10ms再次中斷溢出,內部溢出中斷執行功能
{
TCNT2 = 100;
flag++;
if (flag == 1)
{
countR = counter;
Serial.print("red=");
Serial.println(countR, DEC);
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
}
else if (flag == 2)
{
countG = counter;
Serial.print("green=");
Serial.println(countG, DEC);
digitalWrite(s2, LOW);
digitalWrite(s3, HIGH);
}
else if (flag == 3)
{
countB = counter;
Serial.print("blue=");
Serial.println(countB, DEC);
Serial.println("\n");
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
}
else if (flag == 4)
{
flag = 0;
}
counter = 0;
}
void loop()
{
TCS();
while (1);
}



