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); }