背景:
隨著現代工業生產向高速化、自動化方向的發展,生產過程中長期以來由人眼起主導作用的顏色識別工作將越來越多地被相應的顏色傳感器所替代。例如:圖書館使用顏色區分對文獻進行分類,能夠極大地提高排架管理和統計等工作;在包裝行業,產生包裝利用不同的顏色和裝潢來表示其不同的性質或用途。目前的顏色傳感器通常是在獨立的光電二極管上覆蓋經過修正的紅、綠、藍濾波片,然后對輸出信號進行相應的處理,才能將顏色信號識別出來;有的將兩者集合起來,但是輸出模擬信號,需要一個A/D電路進行采集,對該信號進一步處理,才能進行識別,增加了電路的復雜性,并且存在較大的識別誤差,影響了識別的效果。TAOS(TexasAdvancedOptoelectronicSolutions)公司最新推出的顏色傳感器TCS3200,不僅能夠實現顏色的識別與檢測,與以前的顏色傳感器相比,還具有許多優良的新特性。
最近在網上淘了一片TCS3200模塊,從官方的介紹中看的出這片TCS3200功能好強大,閑來沒事就做了一實驗,想看看這個TCS3200的性能、檢測能力到底怎樣;
需要的器件和材料:
1.51最小系統(12T 時鐘:11.0592MHz)
2.TCS3200顏色識別模塊
3.各種顏色的物料
4.1602液晶屏
TCS3200接口定義:
S0、S1接VCC
EO接GND(或用IO口控制)
S2接P1.0
S3接P1.1
OUT接P3.5(必須)
(測試程序貼在后面,實物測試通過!)
(TCS3200顏色識別模塊)
(自己做的TCS3200模塊轉接板,方便連線,方便檢測顏色)
(模塊和轉接板連接完成)
(最小系統)
(1602液晶屏)
(連接好1602液晶屏)
(為了方便檢測小物料和白平衡檢測,需要自己做一個小平臺,倆飲料瓶蓋子,一顆自攻螺絲即可搞定!)
(做好的平臺,為了方便白平衡,需要在上面蓋子上劃倆口子,只要能卡住一張白紙即可!)
(最終效果)
(全家福)
(連接好TCS3200模塊)
(白平衡測試,注意:上電前必須白平衡檢測,不然后面檢測的顏色都不會準確的;檢測方法:白紙放在TCS3200模塊前面1公分處,然后單片機上電,只要第一次讀出的值為255,255,255即可,否則請重新進行白平衡!)
(白平衡的結果,現在就可以進行顏色識別了)
(識別到綠色娃娃的顏色,上位機上面的顏色為識別到的顏色,同時液晶上會顯示RGB值)
(識別到黃色娃娃的顏色值)
(識別到粉紅色娃娃的顏色值)
(上位機顯示粉紅色娃娃的顏色)
(上位機界面)

(這倆高爾夫球的識別,但是結果不準確,估計是這倆高爾夫球的反光能力太強烈了,只要表面不是很光滑的物體檢測出來誤差都是很小的,另外,有網友說要放在黑盒子里檢測,我感覺沒必要,只要白平衡做好了基本就沒什么問題了,至于表面特別光滑的物體,只能去尋找其他方法去進行檢測了!)
========================= 測 試 程 序 ======================== #include "reg52.h"
#define _data P2 //LCD1602數據接口
/******************************************************************
- 說明:端口定義
- 備注:無
******************************************************************/
sbit EN =P0^5; //讀寫使能,高電平有效,下降沿鎖定數據。
sbit RW =P0^6; //讀/寫選擇:高電平為讀數據,低電平為寫數據。
sbit RS =P0^7; //數據/指令選擇:高電平為數據,低電平為指令。
sbit tcs230_s2=P1^0; //TCS3200 S2 P1.0
sbit tcs230_s3=P1^1; //TCS3200 S3 P1.1
//TCS3200 OUT 接P3.5
/******************************************************************
- 說明:變量定義
- 備注:無
******************************************************************/
unsigned int Ryz,Gyz,Byz; //分別定義紅色因子 綠色因子 藍色因子
unsigned int Rzhi,Gzhi,Bzhi; //RGB值
unsigned char code num[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/******************************************************************
- 功能描述:延時子程序
- 入口參數:長整數型
- 參 數 值:0-65535
- 返回說明:無
- 備 注:無
******************************************************************/
void delay1ms(unsigned int ms)//延時1毫秒(不夠精確的)
{
unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<100;j++);
}
void delay600ms(void)
{
unsigned char a,b,c;
for(c=89;c>0;c--)
for(b=230;b>0;b--)
for(a=12;a>0;a--);
}
/******************************************************************
- 功能描述:寫數據子程序
- 入口參數:數據
- 參 數 值:字節型
- 返回說明:無
- 備 注:無
******************************************************************/
void wdat(unsigned char dat)
{
delay1ms(1);
RS=1;
RW=0;
EN=0;
_data=dat;
delay1ms(1);
EN=1;
delay1ms(1);
EN=0;
}
/******************************************************************
- 功能描述:寫命令子程序
- 入口參數:數據
- 參 數 值:字節型
- 返回說明:無
- 備 注:無
******************************************************************/
void wcmd(unsigned char com)
{
delay1ms(1);
RS=0;
RW=0;
EN=0;
_data=com;
delay1ms(1);
EN=1;
delay1ms(1);
EN=0;
}
/******************************************************************
- 功能描述:初始化子程序
- 入口參數:無
- 參 數 值:無
- 返回說明:無
- 備 注:無
******************************************************************/
void init_1602(void)
{
delay1ms(15);
wcmd(0x38);delay1ms(5); //功能設置 8位總線 2行顯示 5*7點陣
wcmd(0x06);delay1ms(5); //設置輸入模式 光標右移 整體不移
wcmd(0x08);delay1ms(5); //設置顯示方式 顯示關
wcmd(0x01);delay1ms(5); //清除顯示
wcmd(0x0c);delay1ms(5); //設置顯示方式 顯示開 無光標 光標不閃爍
}
/******************************************************************
- 功能描述:指定位置寫字符函數
- 入口參數:行,列,字符
- 參 數 值:無
- 返回說明:無
- 備 注:無
******************************************************************/
void DisplayOneChar( unsigned char X, unsigned char Y, unsigned char in)
{
X &= 0x1; //限制X值為 0 和 1
Y &= 0xF; //限制Y值為 0 - 15
if (X)
{Y|=0x40;} //當要顯示第二行時地址碼+0x40;
Y |= 0x80; //得出列位置
wcmd(Y); //寫地址
wdat(in); //寫數據
}
/******************************************************************
- 功能描述:發送數據到上位機
- 入口參數:數據1,數據2,數據3
- 參 數 值:無
- 返回說明:無
- 備 注:無
******************************************************************/
void SendOneByte(unsigned char ina,unsigned char inb,unsigned char inc)
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
SBUF = ina;
while(!TI);
TI = 0;
SBUF = inb;
while(!TI);
TI = 0;
SBUF = inc;
while(!TI);
TI = 0;
}
/******************************************************************
- 功能描述:白平衡函數
- 入口參數:無
- 參 數 值:無
- 返回說明:無
- 備 注:無
******************************************************************/
void baipingheng(void)
{
TMOD=0x51; //設定T0以工作方式1定時10毫秒
TH0=(65536-10000)/256; //取紅色因子
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=0;
tcs230_s3=0; //選擇紅色濾光器
TR0=1; //10毫秒開始計時
TR1=1; //開始計數
while(TF0==0); //等待定時器溢出
TF0=0; //清除定時器0溢出標志
TR0=0; //關閉定時0
TR1=0;
Ryz=TH1*256+TL1; //其實這里的比例因子應該為255/(TH1*256+TL1)
TH0=(65536-10000)/256; //取藍色因子
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=0;
tcs230_s3=1; //選擇藍色濾光器
TR0=1; //10毫秒開始計時
TR1=1; //開始計數
while(TF0==0); //等待定時器溢出
TF0=0; //清除定時器0溢出標志
TR0=0; //關閉定時0
TR1=0;
Byz=TH1*256+TL1; //其實這里的比例因子應該為255/(TH1*256+TL1)
TH0=(65536-10000)/256; //求綠色因子
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=1;
tcs230_s3=1; //選擇綠色濾光器
TR0=1; //10毫秒開始計時
TR1=1; //開始計數
while(TF0==0); //等待定時器溢出
TF0=0; //清除定時器0溢出標志
TR0=0; //關閉定時0
TR1=0;
Gyz=TH1*256+TL1; //其實這里的比例因子應該為255/(TH1*256+TL1)
}
/******************************************************************
- 功能描述:測量顏色值
- 入口參數:無
- 參 數 值:無
- 返回說明:無
- 備 注:無
******************************************************************/
void ceyanse(void)
{
TMOD=0x51; //設定T0以工作方式1定時10毫秒
TH0=(65536-10000)/256; //求R值
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=0; //選擇紅色濾光器
tcs230_s3=0;
TR0=1; //10毫秒開始計時
TR1=1; //開始計數
while(TF0==0); //等待定時器溢出
TF0=0; //清除定時器0溢出標志
TR0=0; //關閉定時0
TR1=0;
Rzhi=(unsigned long)(TH1*256+TL1)*255/Ryz;
if(Rzhi>255)Rzhi=255; //判斷RGB值是否合法
TH0=(65536-10000)/256; //求B值
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=0;
tcs230_s3=1; //選擇藍色濾光器
TR0=1; //10毫秒開始計時
TR1=1; //開始計數
while(TF0==0); //等待定時器溢出
TF0=0; //清除定時器0溢出標志
TR0=0; //關閉定時0
TR1=0;
Bzhi=(unsigned long)(TH1*256+TL1)*255/Byz;
if(Bzhi>255)Bzhi=255; //判斷RGB值是否合法
TH0=(65536-10000)/256; //求G值
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=1;
tcs230_s3=1; //選擇綠色濾光器
TR0=1; //10毫秒開始計時
TR1=1; //開始計數
while(TF0==0); //等待定時器溢出
TF0=0; //清除定時器0溢出標志
TR0=0; //關閉定時0
TR1=0;
Gzhi=(unsigned long)(TH1*256+TL1)*255/Gyz;
if(Gzhi>255)Gzhi=255; //判斷RGB值是否合法
}
void main(void)
{
init_1602();//LCD初始
baipingheng();//上電時先白平衡一次
while(1)
{
ceyanse(); //顏色測試
DisplayOneChar(0, 0,'R');//以十進制顯示RGB中紅色的分值
DisplayOneChar(0, 1, Rzhi/100+0x30); //顯示百位數據
DisplayOneChar(0, 2, Rzhi/10%10+0x30);//顯示十位數據
DisplayOneChar(0, 3, Rzhi%10+0x30);//顯示個位數據
DisplayOneChar(0, 5,'G');//以十進制顯示RGB中綠色的分值
DisplayOneChar(0, 6, Gzhi/100+0x30); //顯示百位數據
DisplayOneChar(0, 7, Gzhi/10%10+0x30);
DisplayOneChar(0, 8, Gzhi%10+0x30);
DisplayOneChar(0, 10,'B');//以十進制顯示RGB中藍色的分值
DisplayOneChar(0, 11, Bzhi/100+0x30);
DisplayOneChar(0, 12, Bzhi/10%10+0x30);
DisplayOneChar(0, 13, Bzhi%10+0x30);
//*****在LCD1602的第二行以16進制顯示RGB*******************
DisplayOneChar(1, 1, num[Rzhi/16]);
DisplayOneChar(1, 2, num[Rzhi%16]);
DisplayOneChar(1, 3, 'H');
DisplayOneChar(1, 6, num[Gzhi/16]);
DisplayOneChar(1, 7, num[Gzhi%16]);
DisplayOneChar(1, 8, 'H');
DisplayOneChar(1, 11,num[Bzhi/16]);
DisplayOneChar(1, 12,num[Bzhi%16]);
DisplayOneChar(1, 13,'H');
SendOneByte(Rzhi,Gzhi,Bzhi); //發送數據到上位機
delay600ms(); //每隔0.6秒測試一次顏色
}
}
=========================== 《 完 》 ==========================
薛 二 煒 于江蘇·無錫
2015 年 05 月 19 日
smhacker@126.com 轉載請注明出處