码迷,mamicode.com
首页 > 其他好文 > 详细

颜色传感器 TCS34725 识别颜色应用

时间:2020-07-03 21:47:52      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:oca   表示   mic   功能   while   cdata   border   tar   P20   

      最近在做一个识别区域颜色的应用,做了一半做不下去了,器件参数不达标,要改换传感器,问题出在器件选型时没有跟客户那边足够多的沟通。
      先看看这款传感器,AMS 的TCS34725,客户要求响应在1ms以内,受到传感积分时间器性能限制(2.4ms),以及I2C通信速率的限制,勉强在10ms以内。

      先简单了解下该传感器的原理:

技术图片技术图片
   简单讲就是通过4种硅光电二极管分别测量光红色成分,蓝色,绿色,以及整个的亮度,以数字的形式将各成分亮度以数值输出。
    我使用了赛元微SC92F8462B mcu 对数据做处理,为啥用用他,因为它集成了32位乘除法器,可以加快MCU运算的能力,而且使用工业品质的1T 8051内核,稳定高效。

     简单介绍下,颜色传感器数值转换位RGB表示的方法,我们可以直接从传感器得到cdata,rdata,gdata,bdata三种数据,分别使用rdata,gdata,bdata于cdata相除得到一个比例值,与255相乘,得RGB数值,再取白光读取计算的RGB,把它调校到255:255:255,得到各分量的校准参数。

     怎样从个颜色RGB值中取特定颜色这也是一个值得讨论的话题。因被测物体亮度差异,通常是取主颜色数值,计算一个比例的其他颜色数值,比如我要识别红色,就取主色值,得到一个2/3的色值,与其他颜色绿色,蓝色相比,其他颜色值小于2/3就可以认为是红色,具体还得看应用。还有一个钟可以事先设定要识别的颜色,将数值存储在eeprom中,然后,将这个数值加上一个1%~5%的误差做比较,在范围则认为识别成功。

      不过我遇到最重要问题是,在提高传感器积分速率时伴随传感器精度下降,以至于得各色值数据过小,无法做正常计算,最终选择停止继续优化。

#include "H/Function_Init.H"
#include "iic_p.h"

unsigned int c_val = 0;
unsigned int r_val = 0;
unsigned int g_val = 0;
unsigned int b_val = 0;

unsigned char rgb_rval = 0;
unsigned char rgb_gval = 0;
unsigned char rgb_bval = 0;

unsigned char temp = 0;
unsigned char calation0 = 0;
unsigned char calation1 = 0;

//void Multiplier_Divider_Test(void);
/*************************************************************
说明:
1、Options for Target‘Target1’:BL51 Locate->Code Range:0x100,烧录选项请选择DISRST,复位脚作为普通IO使用;
2、改变TEST的定义,可以分别测试对应的功能;
3、注意:先在Function.H里面选择测试型号
***************************************************************/
//#define Test  2    //BTM:0 EXTI:1 Timer:2 LCD:3 PWM:4 Uart0:5 SSI:6 ADC:7 IAP:8 Multiplier_Divider:9

void main(void)
{
     P2CON = 0x33; //P20,P21,P24,P25 OUTPUT MODE  ,scl,sda,led
     P2 = 0x00;
     P0CON = 0x18;    //p03(g),p04(r) output
     P0 = 0x00;
    
     i2c_wtdata(0x81,0xff);
     i2c_wtdata(0x8f,0x03);
     i2c_wtdata(0x80,0x01);
     delayus(255);
     i2c_wtdata(0x80,0x03);
    
     while(1)
     {
         //get rgbc light value
         //i2c_rddata(0x92,&sensor_id);
         i2c_rddata(0x94,&temp);
         c_val = temp;
         i2c_rddata(0x95,&temp);
         c_val = c_val + (((unsigned int)(temp)) << 8);
        
         i2c_rddata(0x96,&temp);
         r_val = temp;
         i2c_rddata(0x97,&temp);
         r_val = r_val + (((unsigned int)(temp)) << 8);
        
         i2c_rddata(0x98,&temp);
         g_val = temp;
         i2c_rddata(0x99,&temp);
         g_val = g_val + (((unsigned int)(temp)) << 8);
        
         i2c_rddata(0x9a,&temp);
         b_val = temp;
         i2c_rddata(0x9b,&temp);
         b_val = b_val + (((unsigned int)(temp)) << 8);
        
         if(c_val > 0x40)
         {
         //delayus(255);
         //coculate rgb_val
         //rgb_rval
         OPERCON = 0x00;
         EXA0 = (unsigned char)(r_val);
         EXA1 = (unsigned char)(r_val >> 8);
         EXA2 = 0x00;
         EXA3 = 0x00;
         EXBL = 0xff;
         EXBH = 0x00;
         OPERCON = 0x80;
         while((OPERCON & 0x80) != 0);
         //calation0 = EXA0;
         //calation1 = EXA1;
         //calation2 = EXA2;
         //calation3 = EXA3;
         OPERCON = 0x60;
         EXA3 = 0x00;    //bu qi 32bit
         EXBL = (unsigned char)(c_val);
         EXBH = (unsigned char)(c_val >> 8);
         OPERCON = OPERCON | 0x80;
         while((OPERCON & 0x80) != 0);
         rgb_rval = EXA0;
        
         //coculate rgb_val
         //rgb_gval
         OPERCON = 0x00;
         EXA0 = (unsigned char)(g_val);
         EXA1 = (unsigned char)(g_val >> 8);
         EXA2 = 0x00;
         EXA3 = 0x00;
         EXBL = 0xff;
         EXBH = 0x00;
         OPERCON = 0x80;
         while((OPERCON & 0x80) != 0);
         OPERCON = 0x60;
         EXA3 = 0x00;    //bu qi 32bit
         EXBL = (unsigned char)(c_val);
         EXBH = (unsigned char)(c_val >> 8);
         OPERCON = OPERCON | 0x80;
         while((OPERCON & 0x80) != 0);
         rgb_gval = EXA0;
        
         //coculate rgb_val
         //rgb_bval
         OPERCON = 0x00;
         EXA0 = (unsigned char)(b_val);
         EXA1 = (unsigned char)(b_val >> 8);
         EXA2 = 0x00;
         EXA3 = 0x00;
         EXBL = 0xff;
         EXBH = 0x00;
         OPERCON = 0x80;
         while((OPERCON & 0x80) != 0);
         OPERCON = 0x60;
         EXA3 = 0x00;    //bu qi 32bit
         EXBL = (unsigned char)(c_val);
         EXBH = (unsigned char)(c_val >> 8);
         OPERCON = OPERCON | 0x80;
         while((OPERCON & 0x80) != 0);
         rgb_bval = EXA0;
       }
         else
         {
             rgb_rval = 0x00;
             rgb_bval = 0x00;
             rgb_gval = 0x00;
         }
         //colour calcu find table
         //green
         if(rgb_gval > 85)
         {
             //calation0 = (rgb_gval*13)/20;
             OPERCON = 0x00;
             EXA0 = (unsigned char)(rgb_gval);
             EXA1 = 0X00;
             EXA2 = 0x00;
             EXA3 = 0x00;
             EXBL = 0x03;                //*3
             EXBH = 0x00;
             OPERCON = 0x80;
             while((OPERCON & 0x80) != 0);
             OPERCON = 0x60;
             EXA3 = 0x00;    //bu qi 32bit
             EXBL = 0x4;                ///4
             EXBH = 0x00;
             OPERCON = OPERCON | 0x80;
             while((OPERCON & 0x80) != 0);
             calation0 = EXA0;
            
             if((rgb_rval < calation0) && (rgb_bval < calation0))
             {
                 P03 = 1;
             }
             else
             {
                 P03 = 0;
             }
         }
         else
         {
             P03 = 0;
         }
         //colour calcu find table
         //red
         if((rgb_rval > 85)&&(rgb_rval >= rgb_gval + rgb_bval))
         {
             //calation0 = (rgb_bval*6)/5;
             OPERCON = 0x00;
             EXA0 = (unsigned char)(rgb_bval);
             EXA1 = 0X00;
             EXA2 = 0x00;
             EXA3 = 0x00;
             EXBL = 0x06;                //*6
             EXBH = 0x00;
             OPERCON = 0x80;
             while((OPERCON & 0x80) != 0);
             OPERCON = 0x60;
             EXA3 = 0x00;    //bu qi 32bit
             EXBL = 0x05;                ///5
             EXBH = 0x00;
             OPERCON = OPERCON | 0x80;
             while((OPERCON & 0x80) != 0);
             calation0 = EXA0;
             if(rgb_gval < calation0)
             {
                 P04 = 1;
             }
             else
             {
                 P04 = 0;
             }
         }
         else
         {
             P04 = 0;
         }
         //delayus(255);
     }
}

技术图片

商务合作,吹牛,扯淡,交朋友 请联系 18665321219

颜色传感器 TCS34725 识别颜色应用

标签:oca   表示   mic   功能   while   cdata   border   tar   P20   

原文地址:https://www.cnblogs.com/logicexpression/p/13232360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!