找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 37330|回复: 45
收起左侧

基于51单片机的颜色识别系统(完结)

  [复制链接]
ID:105099 发表于 2016-2-5 16:16 | 显示全部楼层 |阅读模式
本文作者:薛 二 炜

背景:
       随着现代工业生产向高速化、自动化方向的发展,生产过程中长期以来由人眼起主导作用的颜色识别工作将越来越多地被相应的颜色传感器所替代。例如:图书馆使用颜色区分对文献进行分类,能够极大地提高排架管理和统计等工作;在包装行业,产生包装利用不同的颜色和装潢来表示其不同的性质或用途。目前的颜色传感器通常是在独立的光电二极管上覆盖经过修正的红、绿、蓝滤波片,然后对输出信号进行相应的处理,才能将颜色信号识别出来;有的将两者集合起来,但是输出模拟信号,需要一个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  转载请注明出处 

评分

参与人数 5黑币 +39 收起 理由
心疯扬 + 10 很给力!
切了 + 7 共享资料的黑币奖励!
咖啡加冰 + 5 很给力!
练氏 + 12
ssfc + 5

查看全部评分

回复

使用道具 举报

ID:79544 发表于 2016-2-17 11:57 | 显示全部楼层
谢谢楼主分享,赞!
回复

使用道具 举报

ID:104637 发表于 2016-3-21 22:05 | 显示全部楼层
哇啊哦,有意思不错
回复

使用道具 举报

ID:105890 发表于 2016-3-22 06:36 | 显示全部楼层
谢谢楼主分享!
回复

使用道具 举报

ID:89596 发表于 2016-4-2 14:06 | 显示全部楼层
看着就爽
回复

使用道具 举报

ID:73852 发表于 2016-4-2 16:53 | 显示全部楼层
楼主厉害,幸苦了!
回复

使用道具 举报

ID:128598 发表于 2016-6-29 19:41 | 显示全部楼层
大神,为什么我按你的程序烧不出来。1602只是亮  什么都没有。引脚定义我改过了
回复

使用道具 举报

ID:129840 发表于 2016-8-2 22:00 | 显示全部楼层
没用啊 lcd  没有显示
回复

使用道具 举报

ID:141936 发表于 2016-11-23 10:25 | 显示全部楼层
学习下。
回复

使用道具 举报

ID:141936 发表于 2016-11-23 10:25 | 显示全部楼层
谢谢楼主,我想学习下。
回复

使用道具 举报

ID:99612 发表于 2016-12-30 22:01 | 显示全部楼层
楼主!能发一份上位机软件吗
回复

使用道具 举报

ID:99612 发表于 2016-12-30 22:02 | 显示全部楼层

楼主!能发一份上位机软件吗  1433189411@qq.com
回复

使用道具 举报

ID:99612 发表于 2016-12-30 22:09 | 显示全部楼层
楼主!那个上位机是用什么软件编写的
回复

使用道具 举报

ID:158734 发表于 2017-1-9 12:11 | 显示全部楼层
请问 是用什么软件编写的?
回复

使用道具 举报

ID:145256 发表于 2017-4-13 09:07 | 显示全部楼层
5314039 发表于 2016-12-30 22:02
楼主!能发一份上位机软件吗

请问你有上位机的软件了吗?有的话帮忙给我发一份吧,谢谢1542113651@qq.com
回复

使用道具 举报

ID:198687 发表于 2017-5-9 16:16 | 显示全部楼层
楼主可以把你上面用的软件发给我吗?谢谢,邮箱758759506@qq.com
回复

使用道具 举报

ID:198687 发表于 2017-5-9 16:18 | 显示全部楼层
楼主,可以把你所用的软件发给我吗?邮箱758759506@qq.com
回复

使用道具 举报

ID:218021 发表于 2017-7-8 07:12 来自手机 | 显示全部楼层
楼主,求上位机软件,谢谢2317375052@qq.com
回复

使用道具 举报

ID:136460 发表于 2017-7-12 13:03 | 显示全部楼层
看着就爽
回复

使用道具 举报

ID:218386 发表于 2017-8-1 14:06 | 显示全部楼层
楼主,能发一份上位机吗?想试完它,谢谢~117432208@qq.com
回复

使用道具 举报

ID:227184 发表于 2017-8-12 10:05 | 显示全部楼层
楼主  求加qq通过一下    942678663
回复

使用道具 举报

ID:146874 发表于 2017-9-19 11:58 | 显示全部楼层
非常不错的材料,谢谢楼主分享
回复

使用道具 举报

ID:237327 发表于 2017-10-5 11:23 | 显示全部楼层
5314039 发表于 2016-12-30 22:02
楼主!能发一份上位机软件吗

请问你有上位机软件了吗
回复

使用道具 举报

ID:237327 发表于 2017-10-5 11:24 | 显示全部楼层
哪位大神有楼主的上位机软件可不可以发给我一份,拜托了
回复

使用道具 举报

ID:240690 发表于 2017-10-18 18:43 | 显示全部楼层
各位大神,上位机软件可否分享一下给我?邮箱:1822830507@qq.com       麻烦了O(∩_∩)O谢谢
回复

使用道具 举报

ID:240604 发表于 2017-10-18 19:49 | 显示全部楼层
楼主 这个检测不出来 没有数值是怎么回事呢??
回复

使用道具 举报

ID:253345 发表于 2017-11-25 10:53 | 显示全部楼层
楼主能发一份上位机的软件吗?906276645@qq.com
回复

使用道具 举报

ID:229732 发表于 2017-12-6 13:20 | 显示全部楼层
谢谢楼主分享,赞!赞!赞!赞!
回复

使用道具 举报

ID:268001 发表于 2017-12-27 20:54 | 显示全部楼层
很不错
回复

使用道具 举报

ID:285387 发表于 2018-2-25 14:17 | 显示全部楼层
楼主好! 你的设计很好。 我希望能跟你进一步沟通, 把产品优化以后运用到塑料行业的颜色采集和色差控制中。 同时 我公司也愿意付费来请你进一步的研发。 我的电话: 13322444740 ,也是我的微信号。 希望能早日收到楼主的回音
回复

使用道具 举报

ID:188183 发表于 2018-3-30 19:59 | 显示全部楼层
很厉害
回复

使用道具 举报

ID:232734 发表于 2018-9-12 10:52 | 显示全部楼层
为什么我的一直卡在白平衡的三个255那里
回复

使用道具 举报

ID:282520 发表于 2018-11-30 19:09 | 显示全部楼层
为什么我LCD1602显示不出来啊
回复

使用道具 举报

ID:454903 发表于 2018-12-25 21:33 | 显示全部楼层
请问白平衡程序中,为什么要用到定时器T1的计数功能呀?
回复

使用道具 举报

ID:446674 发表于 2018-12-26 11:38 | 显示全部楼层
不错,感觉应用方面也不会差太多,希望继续加油
回复

使用道具 举报

ID:455289 发表于 2018-12-26 12:24 | 显示全部楼层
很不错,学习一下
回复

使用道具 举报

ID:399179 发表于 2019-3-26 09:06 来自手机 | 显示全部楼层
这个真好啊!
回复

使用道具 举报

ID:513153 发表于 2019-4-15 22:14 | 显示全部楼层
您好,我是一个52单片机初学者,今天浏览到了你的帖子,感觉很倾佩,复制了您的程序,也想自己试验一下,可以分享一下您的上位机软件及源程序吗,我想进一步学习下,Thank you very much!我的邮箱1770608467@qq.com
回复

使用道具 举报

ID:31287 发表于 2019-4-24 21:31 | 显示全部楼层
谢谢楼主分享,赞!
回复

使用道具 举报

ID:668168 发表于 2019-12-20 12:37 | 显示全部楼层
很好哈哈,学到了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表