最近在做一個識別區域顏色的應用,做了一半做不下去了,器件參數不達標,要改換傳感器,問題出在器件選型時沒有跟客戶那邊足夠多的溝通。
先看看這款傳感器,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:9void 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