颜色传感器(Color Sensor)为复杂的自动化挑战提供更可靠的解决方案。它们用于包括食品和饮料、汽车和制造行业在内的各个行业,用于检测材料、检测零件上的颜色标记、验证制造过程中的步骤等。
虽然在工业应用中使用昂贵的颜色传感器,但TCS230颜色传感器等廉价传感器可用于不太严格的应用。
TCS230颜色传感器(也称为TCS3200)非常受欢迎,价格低廉且易于使用。在我们在Arduino项目中使用此颜色传感器之前,最好先了解一下颜色传感器的实际工作原理。
颜色传感器的工作原理 白光由具有不同波长的三种原色(红、绿、蓝)组成。这些颜色相互结合形成不同的颜色。
当白光落在任何表面上时,某些波长的光会被吸收,而某些波长会被反射,这取决于表面材料的特性。我们看到的颜色是波长反射回我们眼睛的结果。
现在转回到传感器,典型的颜色传感器包括一个高亮度白色LED,将调制光投射到物体上。为了检测反射光的颜色,几乎所有颜色传感器都由一个颜色敏感滤光片网格(也称为“拜耳滤光片,Bayer Filter)”)和下面的光电二极管阵列组成,如下图所示。
一个像素由4个滤镜组成,一个红色、一个蓝色、一个绿色和一个透明滤镜(无滤镜)。这种模式也被称为“拜耳模式(Bayer Pattern)”。每个滤光片仅将一种颜色的光传递到下方的光电二极管,而透明滤光片则按原样传递光,如下所示。这种通过透明滤光片的额外光是弱光条件下的主要优势。
然后处理芯片寻址每个光电二极管(一次一种颜色),并测量光的强度。由于存在光电二极管阵列,因此首先对结果进行平均,然后发送出去进行处理。通过测量红光、绿光和蓝光的相对值,可以确定物体的颜色。
TCS230颜色传感器模块 该模块的核心是来自Texas Advanced Optoelectronic Solutions公司的廉价RGB传感器芯片 - TCS230。TCS230颜色传感器是一款完整的颜色检测器,可以检测和测量几乎无限范围的可见颜色。
传感器本位于在模块的中心位置,被四个白色LED包围。模块通电时LED会亮起,用于照亮被感测的物体。借助这些LED,传感器还可以在完全黑暗的环境中工作,以确定物体的颜色或亮度。
TCS230工作在2.7至5.5伏的电源电压下,并提供TTL逻辑电平输出。
TCS230操作方式 TCS230借助8 x 8光电二极管阵列检测颜色,其中16个光电二极管具有红色滤光片,16个光电二极管具有绿色滤光片,16个光电二极管具有蓝色滤光片,其余16个光电二极管是透明的,没有滤光片。
如果您仔细观察传感器,您实际上可以看到这些过滤器。
每16个光电二极管并联连接,因此使用两个控制引脚S2和S3,您可以选择读取其中的哪个。因此,例如,如果您只想检测红色,您可以根据表格将两个引脚设置为 LOW,从而选择16个红色过滤光电二极管。
同样,您可以通过S2和S3的不同组合来选择不同类型的光电二极管。
内部电流频率转换器将来自光电二极管的读数转换为方波,其频率与所选颜色的强度成正比。典型输出频率范围为2HZ~500KHZ。
传感器还有两个控制引脚 S0 和 S1,用于缩放输出频率。频率可以缩放为2%、20%或100%三个不同的预设值。这种频率缩放功能允许传感器与各种微控制器和其他设备一起使用。您可以通过S0和S1的不同组合获得不同的比例。对于 Arduino,大多数应用程序使用20%缩放。
TCS230颜色传感器模块引脚分配 下图显示了常见TCS230模块的引脚排列。
GND 是接地引脚。 OE 是输出使能引脚。该引脚很少使用,并且在大多数模块上永久启用。如果尚未启用,则将其拉低。 S0和S1 引脚用于选择频率缩放。 S2和S3 引脚用于选择颜色阵列。 OUT 引脚为TTL电平方波。 VCC 引脚为模块供电。将其连接到2.7V至5.5V电源。
将TCS230颜色传感器连接到Arduino UNO开发板 将TCS230连接到Arduino非常简单。除输出启用引脚外,每个引脚都被使用,并且模块由Arduino的5V供电。
Arduino上使用的所有引脚都不是专用的,因为该模块不需要任何引脚特定的功能,因此如果您想使用不同的引脚,您可以直接进行修改。
校准传感器 我们实际上将使用两个草图来处理TCS230颜色传感器。 1. 第一个草图(校准草图代码)将帮助我们从传感器获取原始数据。 2. 第二个草图(主要的Arduino草图)将使用之前收到的原始数据来显示被感知颜色的RGB值。 请注意,两个草图都使用相同的硬件连接。
以下是校准草图。此草图按颜色处理TCS230传感器并读取输出引脚的脉冲宽度。然后将输出显示在串口监视器上。
将草图加载到Arduino并安装传感器,使其面向物体。首先找到白色和黑色的参考物体。这些参考物体将产生所有三种颜色的最大值和最小值的读数。 - // Define color sensor pins
- #define S0 4
- #define S1 5
- #define S2 6
- #define S3 7
- #define sensorOut 8
- // Variables for Color Pulse Width Measurements
- int redPW = 0;
- int greenPW = 0;
- int bluePW = 0;
- void setup() {
- // Set S0 - S3 as outputs
- pinMode(S0, OUTPUT);
- pinMode(S1, OUTPUT);
- pinMode(S2, OUTPUT);
- pinMode(S3, OUTPUT);
- // Set Pulse Width scaling to 20%
- digitalWrite(S0,HIGH);
- digitalWrite(S1,LOW);
- // Set Sensor output as input
- pinMode(sensorOut, INPUT);
- // Setup Serial Monitor
- Serial.begin(9600);
- }
- void loop() {
- // Read Red Pulse Width
- redPW = getRedPW();
- // Delay to stabilize sensor
- delay(200);
- // Read Green Pulse Width
- greenPW = getGreenPW();
- // Delay to stabilize sensor
- delay(200);
- // Read Blue Pulse Width
- bluePW = getBluePW();
- // Delay to stabilize sensor
- delay(200);
- // Print output to Serial Monitor
- Serial.print("Red PW = ");
- Serial.print(redPW);
- Serial.print(" - Green PW = ");
- Serial.print(greenPW);
- Serial.print(" - Blue PW = ");
- Serial.println(bluePW);
- }
- // Function to read Red Pulse Widths
- int getRedPW() {
- // Set sensor to read Red only
- digitalWrite(S2,LOW);
- digitalWrite(S3,LOW);
- // Define integer to represent Pulse Width
- int PW;
- // Read the output Pulse Width
- PW = pulseIn(sensorOut, LOW);
- // Return the value
- return PW;
- }
- // Function to read Green Pulse Widths
- int getGreenPW() {
- // Set sensor to read Green only
- digitalWrite(S2,HIGH);
- digitalWrite(S3,HIGH);
- // Define integer to represent Pulse Width
- int PW;
- // Read the output Pulse Width
- PW = pulseIn(sensorOut, LOW);
- // Return the value
- return PW;
- }
- // Function to read Blue Pulse Widths
- int getBluePW() {
- // Set sensor to read Blue only
- digitalWrite(S2,LOW);
- digitalWrite(S3,HIGH);
- // Define integer to represent Pulse Width
- int PW;
- // Read the output Pulse Width
- PW = pulseIn(sensorOut, LOW);
- // Return the value
- return PW;
- }
复制代码上传草图后,您将获得此类读数。记录你在两个极端情况下得到的读数。
代码说明 该草图首先定义用于连接TCS230的引脚。还定义了一些变量来表示红色、绿色和蓝色阵列的脉冲宽度。 - #define S0 4
- #define S1 5
- #define S2 6
- #define S3 7
- #define sensorOut 8
- int redPW = 0;
- int greenPW = 0;
- int bluePW = 0;
复制代码
在setup()函数中,我们将S0-S3引脚定义为输出。这些引脚将用于选择频率缩放和我们希望处理的颜色。S0和S1引脚用于将频率缩放设置为20%,这是将此颜色传感器与Arduino一起使用时的常用值。接下来,传感器输出引脚被定义为Arduino的输入。最后,我们设置串口监视器。 - void setup() {
- // Set S0 - S3 as outputs
- pinMode(S0, OUTPUT);
- pinMode(S1, OUTPUT);
- pinMode(S2, OUTPUT);
- pinMode(S3, OUTPUT);
- // Set Pulse Width scaling to 20%
- digitalWrite(S0,HIGH);
- digitalWrite(S1,LOW);
- // Set Sensor output as input
- pinMode(sensorOut, INPUT);
- // Setup Serial Monitor
- Serial.begin(9600);
- }
复制代码
在loop()函数中,我们调用三个函数 getRedPW()、getGreenPW() 和 getBluePW() 来获取脉冲宽度。让我们以 getRedPW() 为例进行介绍。
getRedPW() 函数获取红色脉冲宽度。首先设置S2和S3引脚以选择红色过滤器。这是此函数与其绿色和蓝色对应不同的唯一步骤。
接下来,定义一个整数来存储脉冲宽度。然后使用pulseIn()函数确定脉冲宽度。此函数测量脉冲宽度,注意我们已将其配置为测量脉冲的低电平部分的宽度。结果是以毫秒为单位的时间。然后返回该值。 - int getRedPW() {
- // Set sensor to read Red only
- digitalWrite(S2,LOW);
- digitalWrite(S3,LOW);
- // Define integer to represent Pulse Width
- int PW;
- // Read the output Pulse Width
- PW = pulseIn(sensorOut, LOW);
- // Return the value
- return PW;
- }
复制代码
回到loop()函数中,我们调用三个函数来读取颜色脉冲宽度,在它们之间添加200毫秒的延迟以使传感器稳定。然后我们在串口监视器上打印这些值。 - void loop() {
- // Read Red Pulse Width
- redPW = getRedPW();
- // Delay to stabilize sensor
- delay(200);
- // Read Green Pulse Width
- greenPW = getGreenPW();
- // Delay to stabilize sensor
- delay(200);
- // Read Blue Pulse Width
- bluePW = getBluePW();
- // Delay to stabilize sensor
- delay(200);
- // Print output to Serial Monitor
- Serial.print("Red PW = ");
- Serial.print(redPW);
- Serial.print(" - Green PW = ");
- Serial.print(greenPW);
- Serial.print(" - Blue PW = ");
- Serial.println(bluePW);
- }
复制代码
|