【雕爺學編程】Arduino動手做(63)---TCS3200D顏色識別傳感器


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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM