本次讲解模块TCS3200颜色识别传感器在零知平台上的应用。
模块中S0、S1引脚用于控制输出信号频率与内置振荡器频率的比率:
而S2、S3引脚用于选择滤波器模式:
通过白平衡校准得到RGB比例因子,从而得到被测物体RGB颜色值。
电路中OE可以不连接,其他脚按照上图连接即可。
/**
* 文件: TCS3200颜色识别传感器.ino by 零知实验室([url]www.lingzhilab.com[/url])
* -^^- 零知开源,让电子制作变得更简单! -^^-
* 时间: 2018/10/20 10:45
* 说明:
**/
#include
#define S0 9
#define S1 10
#define S2 11
#define S3 12
#define OUT 2 //TCS3200颜色传感器输出信号
//在中断函数中纪录TCS3200输出信号的脉冲个数
int g_count = 0; // 计算与反射光相对应TCS3200颜色传感器输出信号的脉冲数
int g_array[3]; // 存储RGB值
int g_flag = 0; // 滤波器模式选择顺序标志
float g_SF[3]; // 从TCS3200输出信号的脉冲数转换为RGB标准值的RGB比例因子
//初始化TSC3200各控制引脚的输入输出模式
void TSC_Init()
{
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(OUT, INPUT);
//设置TCS3200的内置振荡器方波频率与其输出信号频率的比例因子为2%
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()
{
Serial.println(g_flag);
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) //White Balance
{
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缺省是1秒
//定时器中断配置
Timer1.pause();
Timer1.setPeriod(1000000);//1s
Timer1.setChannel1Mode(TIMER_OUTPUT_COMPARE);
Timer1.setCompare(TIMER_CH1, 1);
Timer1.attachCompare1Interrupt(TSC_Callback);//中断函数
// 开始
Timer1.refresh();
Timer1.resume();
//设置TCS3200输出信号的上跳沿触发中断,中断调用函数为TSC_Count()
attachInterrupt(2, TSC_Count, RISING);
delay(4000); //延时4s,以等待被测物体红、绿、蓝三色在1s内的TCS3200输出信号脉冲计数
//通过白平衡测试,计算得到白色物体RGB值255与1s内三色光脉冲数的RGB比例因子
for(int i=0; i<3; i++)
Serial.println(g_array[i]);
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]);
Serial.println(g_SF[1]);
Serial.println(g_SF[2]);
}
//红、绿、蓝三色光分别对应的1s内TCS3200输出脉冲数乘以相应的比例因子就是RGB标准值
//打印被测物体的RGB值
void loop()
{
g_flag = 0;//每获得一次被测物体的RGB颜色值时需要4s
Serial.println("RGB:");
for(int i=0; i<3; i++) //打印被测物体的RGB值
Serial.println(int(g_array[i] * g_SF[i]));
delay(4000);
Serial.println();
}
程序中主要用到一个定时器,以及中断的应用
把程序上传到零知-标准板后,打开串口调试器,然后复位一次,再把模块传感器一面对着一张白纸,然后等待白平衡校准后再移动到其他物体颜色上(1cm距离),就可以看到RGB值变化了。