SKU:RB-02S035 TCS3200颜色传感器
目录 |
产品概述
TCS3200颜色传感器是全彩的颜色检测器,是一款简单易用、小巧轻便、性价比较高的颜色识别、检测传感器。包括了一块TAOS公司最新退出的颜色到频率转换芯片 TCS3200D RGB感应芯片和4个白色LED灯,TCS3200能在一定的范围内检测和测量几乎所有的可见光。TCS3200有大量的光检测器,每个都有红绿蓝和清除4种滤光器。每6种颜色滤光器均匀地按数组分布来清除颜色中偏移位置的颜色分量。内置的振荡器能输出方波,其频率与所选择的光的强度成比例关系。
产品参数
- 颜色识别芯片:TCS3200D
- 输出频率范围:10kHz - 12kHz,占空比50%
- 工作电压:+2.7v - +5.5v
- 工作电流:1.4 mA
- 检测状态:静态检测
- 最佳检测距离:10mm
- 工作温度:-40°C - +85°C
- 尺寸大小:35.8mm * 35.8mm * 10.8mm
- 重量大小:4.7g
- 固定孔:3mm * 4个
- 对角固定孔间距:16.60 mm
- 相邻固定孔间距:11.74 mm
- 发光颜色:高亮白光
14.接口定义
- S0:输出频率选择输入脚
- S1:输出频率选择输入脚
- OE:低电压使能端
- GND:接电源地
- Vcc:接电源正
- OUT:输出端
- S2:输出频率选择输入脚
- S3:输出频率选择输入脚
工作原理
三原色感应原理
- 通常所看到的物体的颜色,实际上是物体表面吸收了照射到它上面的白光(日光)中的一部分有色成分,而反射出的另一部分有色光在人眼中的反应。白色是由各种频率的可见光混合在一起构成的,也就是说白光中包含着各种颜色的色光(如红R、黄Y、绿G、青V、蓝B、紫P)。根据德国物理学家赫姆霍兹(Helinholtz)的三原色理论可知,各种颜色是由不同比例的三原色(红、绿、蓝)混合而成的。所以,如果知道构成各种颜色的三原色的值,就能够知道所测试物体的颜色。
TCS3200 颜色识别原理
- 对于TCS3200 来说,当选定一个颜色滤波器时,它只允许某种特定的原色通过,阻止其它原色的通过。例如:当选择红色滤波器时,入射光中只有红色可以通过,蓝色和绿色都被阻止,这样就可以得到红色光的光强;同理,选择蓝色滤波器或绿色滤波器时,就可以得到蓝色光和绿色光的光强。通过这三个值,就可以分析投射到 TCS3200 传感器上的光的颜色。
白平衡原理
- 白平衡就是告诉系统什么是白色。从理论上讲,白色是由等量的红色、绿色和蓝色混合而成的;但实际上,白色中的三原色并不完全相等,并且对于 TCS3200 的光传感器来说,它对这三种基本色的敏感性是不相同的,导致TCS3200 的 RGB 输出并不相等,因此在测试前必须进行白平衡调整,使得 TCS3200 对所检测的“白色”中的三原色是相等的。进行白平衡调整是为后续的颜色识别作准备。
在本装置中,白平衡调整的具体步骤和方法如下:
- 将传感器至于一张白纸上,使用产品上的发光二极管照射到白纸上,使入射光能够通过反射传到 TCS3200 上,然后根据前面所介绍的方法,依次选通红色、绿色和蓝色滤波器,分别测得红色、绿色和蓝色的值,然后就可计算出需要的三个调整参数。
当用 TCS3200 识别颜色时,就用这三个参数对所测颜色的R 、G 和B 进行调整。这里有两种方法来计算调整参数:
- 依次选通三种颜色的滤波器,然后对 TCS230的输出脉冲依次进行计数。当计数到255 时停止计数,分别计算每个通道所用的时间。这些时间对应于实际测试时 TCS3200 每种滤波器所采用的时间基准,在这段时间内所测得的脉冲数就是所对应的 R 、G 和 B 的值。
- 设置定时器为一固定时间( 例如10ms ),然后选通三种颜色的滤波器,计算这段时间内 TCS3200 的输出脉冲数,计算出一个比例因子,通过这个比例因子可以把这些脉冲数变为255。在实际测试时,使用同样的时间进行计数,把测得的脉冲数再乘以求得的比例因子,然后就可以得到所对应的 R 、G 和B 的值。
编程原理
TCS3200 模块与 Arduino UNO 的实验接线如下图所示。TCS3200 颜色传感器能读取三种基本色(RGB),但 RGB 输出并不相等,因此在测试前必须进行白平衡的调整,使 TCS3200 对所检测的白色中的三原色相等。进行白平衡调整是为后续的颜色识别作准备。因此在本例程中,首先需要点亮 LED 灯,延时 4s,通过白平衡测试,计算得到白色物体的 RGB 值 255 与 1s 内三色光脉冲数的 RGB 比例因子,那么:
- 红、绿、蓝三色光分别对应的 1s 内 TCS3200 输出脉冲数 * 相应的比例因子 = RGB 标准值
然后,通过调用定时器中断函数,每 1s 产生中断后,计算出该时间内的红、绿、蓝三种光线通过滤波器时产生的脉冲数,再将 TCS3200 输出的信号脉冲个数分别存储到相应的颜色的数组变量中,本例程设置了输出该数组的值,其代表了 RGB 三种颜色的值。
使用方法
example1_Arduino
- 硬件接线图
- 接线说明
- 颜色传感器 S0 连接 Arduino UNO 控制器 D6(数字接口6号)
- 颜色传感器 S1 连接 Arduino UNO 控制器 D5(数字接口5号)
- 颜色传感器 S2 连接 Arduino UNO 控制器 D4(数字接口4号)
- 颜色传感器 S3 连接 Arduino UNO 控制器 D3(数字接口3号)
- 颜色传感器 OUT 连接 Arduino UNO 控制器 D2(数字接口2号)
- 颜色传感器 OE、GND 连接 Arduino UNO 控制器电源地(GND)
- 颜色传感器 +5v 连接 Arduino UNO 控制器电源正(Vcc)
- 示例程序
* 说明:颜色传感器使用了 Arduino 的外部中断功能,所以此程序适用于 Arduino UNO 控制器(外部中断 0 为数字引脚 2 号),如果要使用其他型号的 Arduino 控制器,只需对应修改中断标号或者连接的引脚即可。
例:结合 Leonardo 控制器来使用 TCS3200 颜色传感器,则需要将 setup 中的外部中断语句修改,其他接线方法一致
原语句为:attachInterrupt(0, TSC_Count, RISING);//外部中断口初始0
修改后语句为:attachInterrupt(1, TSC_Count, RISING);//外部中断口初始1
原因: Leonardo 的数字 2 号接口为外部中断 1,而 UNO 控制器的数字 2 号接口为外部中断 0,具体可以查阅Arduino官网相应产品说明:https://www.arduino.cc/
#include <TimerOne.h> // 引用 TimerOne.h 库文件 #define S0 6 // 定义 S0为引脚6 #define S1 5 // 定义 S1为引脚5 #define S2 4 // 定义 S2为引脚4 #define S3 3 // 定义 S3为引脚3 #define OUT 2 // 定义 OUT为引脚2 int g_count = 0; //定义整型变量 g_count并赋初值为0,用于存储计数频率 int g_array[3]; //定义整型数组变量 g_array[3],用于存储RGB的值 int g_flag = 0; //定义整形变量 g_flag 并赋初值为0,用于过滤器排列 float g_SF[3]; //定义浮点型数组变量g_SF[3],用于存储RGB比例因子 int value[3]; //定义定义整型数组变量value[3],用于判断颜色 // 初始化 tsc3200 和设置内置振荡器方波频率与其输出信号频率的比例因子为2% void TSC_Init() { pinMode(S0, OUTPUT); // 定义S0为输出状态 pinMode(S1, OUTPUT); // 定义S1为输出状态 pinMode(S2, OUTPUT); // 定义S2为输出状态 pinMode(S3, OUTPUT); // 定义S3为输出状态 pinMode(OUT, INPUT); // 定义OUT为输入状态 digitalWrite(S0, LOW); //定义S0为低电平 digitalWrite(S1, HIGH); // 定义 S1为高电平 //输出频率缩放 2% } // 选择滤波模式,决定让红、绿、蓝哪一种光线通过滤波器 void TSC_FilterColor(int Level01, int Level02) { if(Level01 != 0) // 如果Level01 不等于0 Level01 = HIGH; //则Level01 为高电平 if(Level02 != 0) // 如果Level02 不等于0 Level02 = HIGH; //则Level02 为高电平 digitalWrite(S2, Level01); // 将Level01值送给S2 digitalWrite(S3, Level02); // 将Level02值送给S3 // 选择过滤器颜色 } //中断函数,计算 TCS3200 输出信号的脉冲数 void TSC_Count() { g_count ++ ; } /*定时器中断函数,每 1s 中断后,把该时间内的红、绿、蓝三种广信通过滤波器时, * TCS3200 输出信号脉冲个数分别储存到数组 g_array[3] 的相应元素变量中 */ void TSC_Callback() { switch(g_flag) { case 0: Serial.println("->WB Start");// 串口打印字符串"->WB Start" TSC_WB(LOW, LOW);// 选择让红色光线通过滤波器的模式 break; case 1: Serial.print("->Frequency R="); // 串口打印字符串"->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="); // 串口打印字符串"->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="); // 串口打印字符串"->Frequency B=" Serial.println(g_count);// 串口打印 1s 内的蓝光通过滤波器时,TCS3200 输出的脉冲个数 Serial.println("->WB End"); // 串口打印字符串"->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) { g_count = 0;//计数值清零 g_flag ++;//输出信号计数标志 TSC_FilterColor(Level0, Level1);//滤波器模式 Timer1.setPeriod(1000000);//设置输出信号脉冲计数时长为 1s } //初始化 void setup() { TSC_Init(); Serial.begin(9600);//打开串口并设置通信波特率为 9600 Timer1.initialize();//定时器初始化,默认触发值为 1s Timer1.attachInterrupt(TSC_Callback); // 设置定时器1的中断,中断调用函数为 TSC_Callback() //设置 TCS3200 输出信号的上升沿触发中断,中断调用函数为 TSC_Count() attachInterrupt(0, TSC_Count, RISING);//外部中断口初始0 delay(4000);// 延迟 4s ,以等待被测试物体红、绿、蓝三色在 1s 内的 TCS3200 输出信号脉冲计数 //通过白平衡测试,计算得到白色物体 RGB 值 255 与 1s 内三色光脉冲数的 RGB 比例因子 for(int i=0; i<3; i++) Serial.println(g_array[i]); //串口打印 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],5); Serial.println(g_SF[1],5); Serial.println(g_SF[2],5); //红、绿、蓝三色光分别对应的1s内TCS3200输出脉冲数乘以相应的比例因子就是RGB标准值 //打印被测物体的RGB值 for(int i=0; i<3; i++) Serial.println(int(g_array[i] * g_SF[i])); } //主程序 void loop() { g_flag = 0; //每获得一次被测物体RGB颜色值需时4s delay(4000); //打印出被测物体RGB颜色值 for(int i=0; i<3; i++) Serial.println(int(g_array[i] * g_SF[i])); }
- 程序效果
如果程序编译正常,并且正确上传到 Arduino UNO 控制器中,就可以通过串口监视器可以查看当前检测的 RGB 值,从而判断颜色。白平衡效果如下图所示:
example2_Arduino
- 硬件设备
- Carduino UNO R3 控制器 * 1个
- Arduino 传感器扩展板V5.0 * 1个
- Color Sensor颜色传感器模块 * 1个
- 3P传感器连接线 * 5个
- 4P传感器连接线 * 2个
- IR&LED Modue * 5个 (红、白、蓝、黄、绿色各一个)
- USB 数据通信线 * 1个
- 色板 * 1个
- 接线说明
- 颜色传感器与 Arduino UNO 控制器的连接同例子程序相同
- 将各种颜色食人鱼灯连接到 Arduino传感器扩展板上,连接方式:
(1)红色食人鱼灯接数字口 8号
(2)黄色灯接数字口 9号
(3)绿色灯接数字口10号
(4)蓝色灯接数字口 11号
(5)白色灯接数字口 12号
- 示例程序
#include <TimerOne.h> // 引用 TimerOne.h 库文件 #define S0 6 // 定义 S0为引脚6 #define S1 5 // 定义 S1为引脚5 #define S2 4 // 定义 S2为引脚4 #define S3 3 // 定义 S3为引脚3 #define OUT 2 // 定义 OUT为引脚2 #define Rs 8 // 定义 Rs为引脚8 #define Ys 9 // 定义 Ys为引脚9 #define Gs 10 // 定义 Gs为引脚10 #define Bs 11 // 定义 Bs为引脚11 #define Ws 12 // 定义 Ws为引脚12 int g_count = 0; //定义整型变量 g_count并赋初值为0,用于存储计数频率 int g_array[3]; //定义整型数组变量 g_array[3],用于存储RGB的值 int g_flag = 0; //定义整形变量 g_flag 并赋初值为0,用于过滤器排列 float g_SF[3]; //定义浮点型数组变量g_SF[3],用于存储RGB比例因子 int value[3]; //定义定义整型数组变量value[3],用于判断颜色 // 初始化tsc230 和设置频率 void TSC_Init() { pinMode(S0, OUTPUT); // 定义S0为输出状态 pinMode(S1, OUTPUT); // 定义S1为输出状态 pinMode(S2, OUTPUT); // 定义S2为输出状态 pinMode(S3, OUTPUT); // 定义S3为输出状态 pinMode(OUT, INPUT); // 定义OUT为输入状态 digitalWrite(S0, LOW); //定义S0为低电平 digitalWrite(S1, HIGH); // 定义 S1为高电平 //输出频率缩放 2% } // 选择过滤器的颜色 void TSC_FilterColor(int Level01, int Level02) { if(Level01 != 0) // 如果Level01 不等于0 Level01 = HIGH; //则Level01 为高电平 if(Level02 != 0) // 如果Level02 不等于0 Level02 = HIGH; //则Level02 为高电平 digitalWrite(S2, Level01); // 将Level01值送给S2 digitalWrite(S3, Level02); // 将Level02值送给S3 // 选择过滤器颜色 } void TSC_Count() { g_count ++ ; // 自动计算频率 } void TSC_Callback() { switch(g_flag) { case 0: Serial.println("->WB Start"); // 串口打印字符串"->WB Start" TSC_WB(LOW, LOW); // 没有过滤红色 break; case 1: Serial.print("->Frequency R="); // 串口打印字符串"->Frequency R=" Serial.println(g_count); // 串口打印 g_count变量值 g_array[0] = g_count; TSC_WB(HIGH, HIGH); // 没有过滤绿色 break; case 2: Serial.print("->Frequency G="); // 串口打印字符串"->Frequency G=" Serial.println(g_count); // 串口打印 g_count变量值 g_array[1] = g_count; TSC_WB(LOW, HIGH); // 没有过滤蓝色 break; case 3: Serial.print("->Frequency B="); // 串口打印字符串"->Frequency B=" Serial.println(g_count); // 串口打印 g_count变量值 Serial.println("->WB End"); // 串口打印字符串"->WB End" g_array[2] = g_count; TSC_WB(HIGH, LOW); // 清除(无过滤) break; default: g_count = 0; break; } } void TSC_WB(int Level0, int Level1) // 白平衡 { g_count = 0; g_flag ++; TSC_FilterColor(Level0, Level1); Timer1.setPeriod(1000000); //设置一秒周期 } void setup() { pinMode(Rs,OUTPUT); //设定Rs引脚为输出状态 pinMode(Ys,OUTPUT); //设定Ys引脚为输出状态 pinMode(Gs,OUTPUT); //设定Gs引脚为输出状态 pinMode(Bs,OUTPUT); //设定Bs引脚为输出状态 pinMode(Ws,OUTPUT); //设定Ws引脚为输出状态 TSC_Init(); //初始化tcs230 Serial.begin(9600); //打开串口并设置通信波特率为 9600 Timer1.initialize(); //初始化默认是一秒 Timer1.attachInterrupt(TSC_Callback); // 外部中断为一秒 attachInterrupt(0, TSC_Count, RISING); //外部中断口初始0 delay(4000); // 延迟4 秒 for(int i=0; i<3; i++) Serial.println(g_array[i]); //串口打印 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] ; // 蓝色的比例因子 Serial.println(g_SF[0]); // 串口打印 g_SF[0]变量值 Serial.println(g_SF[1]); // 串口打印 g_SF[1]变量值 Serial.println(g_SF[2]); // 串口打印 g_SF[2]变量值 } void loop() { g_flag = 0; for(int i=0; i<3; i++) {Serial.println(int(g_array[i] * g_SF[i])); //串口打印g_array[i] * g_SF[i]变量值 value[i]=int(g_array[i] * g_SF[i]); //将g_array[i] * g_SF[i]值赋值给value[i] } if (((value[0]>168) && (value[0]<208)) && ((value[1]>66) && (value[1]<106)) && ((value[2]>67) && (value[2]<107))) // 如果变量 value[i]数值满足为红色值范围则执行下面语句 { Serial.println("->Red"); //串口打印字符串"->Red" digitalWrite(Rs,HIGH); //Rs定义为高电平 digitalWrite(Ys,LOW); //Ys定义为低电平 digitalWrite(Gs,LOW); //Gs定义为低电平 digitalWrite(Bs,LOW); //Bs 定义为低电平 digitalWrite(Ws,LOW); //Ws定义为低电平 } else if (((value[0]>235) && (value[0]<275)) && ((value[1]> 198) && (value[1]<238)) && ((value[2]>96) && (value[2]<136))) //如果变量 value[i]数值满足为黄色值范围则执行下面语句 { Serial.println("->Yellow"); //串口打印字符串"->Yellow" digitalWrite(Rs,LOW); //Rs 定义为低电平 digitalWrite(Ys,HIGH); //Ys 定义为高电平 digitalWrite(Gs,LOW); //Gs 定义为低电平 digitalWrite(Bs,LOW); //Bs 定义为低电平 digitalWrite(Ws,LOW); //Ws 定义为低电平 } else if (((value[0]>74) && (value[0]<114)) && ((value[1]>119) && (value[1]<159)) && ((value[2]>76) && (value[2]<116))) //如果变量 value[i]数值满足为绿色值范围则执行下面语句 { Serial.println("->Green"); //串口打印字符串"->Green" digitalWrite(Rs,LOW); //Rs 定义为低电平 digitalWrite(Ys,LOW); //Ys定义为低电平 digitalWrite(Gs,HIGH); //Gs 定义为高电平 digitalWrite(Bs,LOW); //Bs 定义为低电平 digitalWrite(Ws,LOW); //Ws 定义为低电平 } else if(((value[0]>46) && (value[0]<86)) && ((value[1]>71) && (value[1]<111)) && ((value[2]>117) && (value[2]<157))) //如果变量 value[i]数值满足为蓝色值范围则执行下面语句 { Serial.println("->Blue"); //串口打印字符串"->Blue" digitalWrite(Rs,LOW); //Rs 定义为低电平 digitalWrite(Ys,LOW); //Ys 定义为低电平 digitalWrite(Gs,LOW); //Gs 定义为低电平 digitalWrite(Bs,HIGH); //Bs定义为高电平 digitalWrite(Ws,LOW); //Ws定义为低电平 } else if (((value[0]>230) && (value[0]<280)) && ((value[1]> 230) && (value[1]<280)) && ((value[2]>230) && (value[2]<280))) //如果变量 value[i]数值满足为白色值范围则执行下面语句 { Serial.println("->White"); //串口打印字符串"->White" digitalWrite(Rs,LOW); //Rs 定义为低电平 digitalWrite(Ys,LOW); //Ys定义为低电平 digitalWrite(Gs,LOW); //Gs 定义为低电平 digitalWrite(Bs,LOW); //Bs 定义为低电平 digitalWrite(Ws,HIGH); //Ws 定义为高电平 } else if (value[0]>0 && value[1]>0 && value[2]>0) //如果变量 value[i]数值不满足上述颜色值范围则执行下面语句 { Serial.println("->Other Color"); //串口打印字符串"->Other Color" digitalWrite(Rs,LOW); //Rs 定义为低电平 digitalWrite(Ys,LOW); //Ys 定义为低电平 digitalWrite(Gs,LOW); //Gs 定义为低电平 digitalWrite(Bs,LOW); //Bs 定义为低电平 digitalWrite(Ws,LOW); //Ws 定义为低电平 } delay(4000);} //延迟4 秒
- 程序效果
- 在以上步骤完成后,我们首先需要在其程序启动后白平衡(白平衡在上文中已介绍),下图为Arduino实验代码的白平衡实验现象:
- 在完成白平衡后(上图实验现象即白色食人鱼灯亮起,也是其系统在检测到白色后的现象)就可以检测其他颜色了。白平衡只是系统对白色的一种数值反馈(即告诉系统什么是白色),本模块识别、检测后读出的只是 R 、G、B 的值,对应其检测到的颜色R、G、B 值,该测试程序编写者特编写了一段应用五种颜色食人鱼灯来显示其检测到的颜色。判断语句中的范围为程序编写者在实验室环境下所测得的R 、G、B 值。更换环境后应予以更改其对应颜色判断的R、G、B 值范围。测试程序( 颜色检测程序)中涉及到了红、黄、绿、蓝、白五种颜色,而色板上为六种颜色,多出一种颜色黑色是为了做出对比 :在检测中遇到非该检测颜色时(即不满足判断语句的条件时)应只在串口打印"->Other Color" ,而无其他现象产生。下图为Arduino实验代码在检测到其他颜色时的实验现象
视频演示
资料下载
- 产品资料
下载链接:https://pan.baidu.com/s/11PXJOobOvOubcp1-bpTbbg 提取码:72bg