Arduino Uno 使用TCS3200D顏色感測器 分辨顏色
TCS3200顏色感測器
實驗效果
把色紙放在感測器2CM左右高的地方,
可以檢測到該物體的RGB值,
然後我們通過畫板可以檢驗出顏色是否正確
在實際環境中,自然光,燈光都有其色溫,白色也有不同的顏色偏差。
注意測試前,第一個物體必須是白色的,因為程式先執行白平衡測試,測試後程序計算得出比例因子,之後就可以比較正確的測出其他顏色。
BOM表
Arduino Uno *1
TSC3200 顏色感測器 *1
麵包板 *1
跳線若干
白色物體
紅色或各色物體等
接線
Arduino Uno <-----> TSC3200顏色感測器
Pin 6 <-----> S0
Pin 5 <-----> S1
Pin 4 <-----> S2
Pin 3 <-----> S3
Pin 2 <-----> OUT
5V <-----> VCC
GND <-----> GND
原始碼
本例程使用到TimerOne庫,請更新到Arduino的函式庫裡
TimerOne 庫下載 http://download.csdn.net/detail/ling3ye/9762875
備用下載
城通網盤免費下載(會有些廣告,不喜勿點) https://u16460183.ctfile.com/fs/16460183-234375893
#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]));
}
**本示例模組沒有LED控制的引腳,所以LED 可以不用
---------------------
作者:ling3ye
來源:CSDN
原文:https://blog.csdn.net/ling3ye/article/details/56668038
版權宣告:本文為博主原創文章,轉載請附上博文連結!