风筝
发表于: 2022-11-8 11:23:55 | 显示全部楼层

颜色传感器(Color Sensor)为复杂的自动化挑战提供更可靠的解决方案。它们用于包括食品和饮料、汽车和制造行业在内的各个行业,用于检测材料、检测零件上的颜色标记、验证制造过程中的步骤等。


虽然在工业应用中使用昂贵的颜色传感器,但TCS230颜色传感器等廉价传感器可用于不太严格的应用。


TCS230颜色传感器(也称为TCS3200)非常受欢迎,价格低廉且易于使用。在我们在Arduino项目中使用此颜色传感器之前,最好先了解一下颜色传感器的实际工作原理。


颜色传感器的工作原理

白光由具有不同波长的三种原色(红、绿、蓝)组成。这些颜色相互结合形成不同的颜色。


当白光落在任何表面上时,某些波长的光会被吸收,而某些波长会被反射,这取决于表面材料的特性。我们看到的颜色是波长反射回我们眼睛的结果。

How-we-see-colors.jpg


现在转回到传感器,典型的颜色传感器包括一个高亮度白色LED,将调制光投射到物体上。为了检测反射光的颜色,几乎所有颜色传感器都由一个颜色敏感滤光片网格(也称为“拜耳滤光片,Bayer Filter)”)和下面的光电二极管阵列组成,如下图所示。

Color-Sensor-Bayer-Filter-and-Photodiodes-Arrangement.jpg


一个像素由4个滤镜组成,一个红色、一个蓝色、一个绿色和一个透明滤镜(无滤镜)。这种模式也被称为“拜耳模式(Bayer Pattern)”。每个滤光片仅将一种颜色的光传递到下方的光电二极管,而透明滤光片则按原样传递光,如下所示。这种通过透明滤光片的额外光是弱光条件下的主要优势。

Color-Sensor-Bayer-Filter-Working-Light-Passing-through-Filters.jpg


然后处理芯片寻址每个光电二极管(一次一种颜色),并测量光的强度。由于存在光电二极管阵列,因此首先对结果进行平均,然后发送出去进行处理。通过测量红光、绿光和蓝光的相对值,可以确定物体的颜色。


TCS230颜色传感器模块

该模块的核心是来自Texas Advanced Optoelectronic Solutions公司的廉价RGB传感器芯片 - TCS230。TCS230颜色传感器是一款完整的颜色检测器,可以检测和测量几乎无限范围的可见颜色。

TCS230-TCS3200-Module-Hardware-Overview.jpg


传感器本位于在模块的中心位置,被四个白色LED包围。模块通电时LED会亮起,用于照亮被感测的物体。借助这些LED,传感器还可以在完全黑暗的环境中工作,以确定物体的颜色或亮度。


TCS230工作在2.7至5.5伏的电源电压下,并提供TTL逻辑电平输出。


TCS230操作方式

TCS230借助8 x 8光电二极管阵列检测颜色,其中16个光电二极管具有红色滤光片,16个光电二极管具有绿色滤光片,16个光电二极管具有蓝色滤光片,其余16个光电二极管是透明的,没有滤光片。


如果您仔细观察传感器,您实际上可以看到这些过滤器。

TCS230-TCS3200-Color-Sensor-Close-Up.jpg


每16个光电二极管并联连接,因此使用两个控制引脚S2和S3,您可以选择读取其中的哪个。因此,例如,如果您只想检测红色,您可以根据表格将两个引脚设置为 LOW,从而选择16个红色过滤光电二极管。


同样,您可以通过S2和S3的不同组合来选择不同类型的光电二极管。


内部电流频率转换器将来自光电二极管的读数转换为方波,其频率与所选颜色的强度成正比。典型输出频率范围为2HZ~500KHZ。


传感器还有两个控制引脚 S0 和 S1,用于缩放输出频率。频率可以缩放为2%、20%或100%三个不同的预设值。这种频率缩放功能允许传感器与各种微控制器和其他设备一起使用。您可以通过S0和S1的不同组合获得不同的比例。对于 Arduino,大多数应用程序使用20%缩放。


TCS230颜色传感器模块引脚分配

下图显示了常见TCS230模块的引脚排列。

TCS230-TCS3200-Color-Sensor-Module-Pinout.jpg


GND 是接地引脚。

OE 是输出使能引脚。该引脚很少使用,并且在大多数模块上永久启用。如果尚未启用,则将其拉低。

S0S1 引脚用于选择频率缩放。

S2S3 引脚用于选择颜色阵列。

OUT 引脚为TTL电平方波。

VCC 引脚为模块供电。将其连接到2.7V至5.5V电源。


将TCS230颜色传感器连接到Arduino UNO开发板

将TCS230连接到Arduino非常简单。除输出启用引脚外,每个引脚都被使用,并且模块由Arduino的5V供电。

Wiring-TCS230-TCS3200-Color-Sensor-Module-with-Arduino.jpg


Arduino上使用的所有引脚都不是专用的,因为该模块不需要任何引脚特定的功能,因此如果您想使用不同的引脚,您可以直接进行修改。


校准传感器

我们实际上将使用两个草图来处理TCS230颜色传感器。

1.  第一个草图(校准草图代码)将帮助我们从传感器获取原始数据。

2.  第二个草图(主要的Arduino草图)将使用之前收到的原始数据来显示被感知颜色的RGB值。

请注意,两个草图都使用相同的硬件连接。


以下是校准草图。此草图按颜色处理TCS230传感器并读取输出引脚的脉冲宽度。然后将输出显示在串口监视器上。


将草图加载到Arduino并安装传感器,使其面向物体。首先找到白色和黑色的参考物体。这些参考物体将产生所有三种颜色的最大值和最小值的读数。

  1. // Define color sensor pins
  2. #define S0 4
  3. #define S1 5
  4. #define S2 6
  5. #define S3 7
  6. #define sensorOut 8

  7. // Variables for Color Pulse Width Measurements
  8. int redPW = 0;
  9. int greenPW = 0;
  10. int bluePW = 0;

  11. void setup() {
  12.         // Set S0 - S3 as outputs
  13.         pinMode(S0, OUTPUT);
  14.         pinMode(S1, OUTPUT);
  15.         pinMode(S2, OUTPUT);
  16.         pinMode(S3, OUTPUT);

  17.         // Set Pulse Width scaling to 20%
  18.         digitalWrite(S0,HIGH);
  19.         digitalWrite(S1,LOW);

  20.         // Set Sensor output as input
  21.         pinMode(sensorOut, INPUT);

  22.         // Setup Serial Monitor
  23.         Serial.begin(9600);
  24. }

  25. void loop() {
  26.         // Read Red Pulse Width
  27.         redPW = getRedPW();
  28.         // Delay to stabilize sensor
  29.         delay(200);

  30.         // Read Green Pulse Width
  31.         greenPW = getGreenPW();
  32.         // Delay to stabilize sensor
  33.         delay(200);

  34.         // Read Blue Pulse Width
  35.         bluePW = getBluePW();
  36.         // Delay to stabilize sensor
  37.         delay(200);

  38.         // Print output to Serial Monitor
  39.         Serial.print("Red PW = ");
  40.         Serial.print(redPW);
  41.         Serial.print(" - Green PW = ");
  42.         Serial.print(greenPW);
  43.         Serial.print(" - Blue PW = ");
  44.         Serial.println(bluePW);
  45. }


  46. // Function to read Red Pulse Widths
  47. int getRedPW() {
  48.         // Set sensor to read Red only
  49.         digitalWrite(S2,LOW);
  50.         digitalWrite(S3,LOW);
  51.         // Define integer to represent Pulse Width
  52.         int PW;
  53.         // Read the output Pulse Width
  54.         PW = pulseIn(sensorOut, LOW);
  55.         // Return the value
  56.         return PW;
  57. }

  58. // Function to read Green Pulse Widths
  59. int getGreenPW() {
  60.         // Set sensor to read Green only
  61.         digitalWrite(S2,HIGH);
  62.         digitalWrite(S3,HIGH);
  63.         // Define integer to represent Pulse Width
  64.         int PW;
  65.         // Read the output Pulse Width
  66.         PW = pulseIn(sensorOut, LOW);
  67.         // Return the value
  68.         return PW;
  69. }

  70. // Function to read Blue Pulse Widths
  71. int getBluePW() {
  72.         // Set sensor to read Blue only
  73.         digitalWrite(S2,LOW);
  74.         digitalWrite(S3,HIGH);
  75.         // Define integer to represent Pulse Width
  76.         int PW;
  77.         // Read the output Pulse Width
  78.         PW = pulseIn(sensorOut, LOW);
  79.         // Return the value
  80.         return PW;
  81. }
复制代码

上传草图后,您将获得此类读数。记录你在两个极端情况下得到的读数。

TCS230-Color-Sensor-Calibration-Output.jpg


代码说明

该草图首先定义用于连接TCS230的引脚。还定义了一些变量来表示红色、绿色和蓝色阵列的脉冲宽度。

  1. #define S0 4
  2. #define S1 5
  3. #define S2 6
  4. #define S3 7
  5. #define sensorOut 8

  6. int redPW = 0;
  7. int greenPW = 0;
  8. int bluePW = 0;
复制代码

在setup()函数中,我们将S0-S3引脚定义为输出。这些引脚将用于选择频率缩放和我们希望处理的颜色。S0和S1引脚用于将频率缩放设置为20%,这是将此颜色传感器与Arduino一起使用时的常用值。接下来,传感器输出引脚被定义为Arduino的输入。最后,我们设置串口监视器。

  1. void setup() {
  2.         // Set S0 - S3 as outputs
  3.         pinMode(S0, OUTPUT);
  4.         pinMode(S1, OUTPUT);
  5.         pinMode(S2, OUTPUT);
  6.         pinMode(S3, OUTPUT);

  7.         // Set Pulse Width scaling to 20%
  8.         digitalWrite(S0,HIGH);
  9.         digitalWrite(S1,LOW);

  10.         // Set Sensor output as input
  11.         pinMode(sensorOut, INPUT);

  12.         // Setup Serial Monitor
  13.         Serial.begin(9600);
  14. }
复制代码

在loop()函数中,我们调用三个函数 getRedPW()getGreenPW()getBluePW() 来获取脉冲宽度。让我们以 getRedPW() 为例进行介绍。


getRedPW() 函数获取红色脉冲宽度。首先设置S2和S3引脚以选择红色过滤器。这是此函数与其绿色和蓝色对应不同的唯一步骤。


接下来,定义一个整数来存储脉冲宽度。然后使用pulseIn()函数确定脉冲宽度。此函数测量脉冲宽度,注意我们已将其配置为测量脉冲的低电平部分的宽度。结果是以毫秒为单位的时间。然后返回该值。

  1. int getRedPW() {
  2.         // Set sensor to read Red only
  3.         digitalWrite(S2,LOW);
  4.         digitalWrite(S3,LOW);
  5.         // Define integer to represent Pulse Width
  6.         int PW;
  7.         // Read the output Pulse Width
  8.         PW = pulseIn(sensorOut, LOW);
  9.         // Return the value
  10.         return PW;
  11. }
复制代码

回到loop()函数中,我们调用三个函数来读取颜色脉冲宽度,在它们之间添加200毫秒的延迟以使传感器稳定。然后我们在串口监视器上打印这些值。

  1. void loop() {
  2.         // Read Red Pulse Width
  3.         redPW = getRedPW();
  4.         // Delay to stabilize sensor
  5.         delay(200);

  6.         // Read Green Pulse Width
  7.         greenPW = getGreenPW();
  8.         // Delay to stabilize sensor
  9.         delay(200);

  10.         // Read Blue Pulse Width
  11.         bluePW = getBluePW();
  12.         // Delay to stabilize sensor
  13.         delay(200);

  14.         // Print output to Serial Monitor
  15.         Serial.print("Red PW = ");
  16.         Serial.print(redPW);
  17.         Serial.print(" - Green PW = ");
  18.         Serial.print(greenPW);
  19.         Serial.print(" - Blue PW = ");
  20.         Serial.println(bluePW);
  21. }
复制代码

跳转到指定楼层
风筝
发表于: 2022-11-8 11:32:36 | 显示全部楼层

Arduino代码 – 从TCS230读取RGB值

完成校准后,您可以上传下一个草图,我们将从TCS230颜色传感器读取RGB值。


在上传草图之前,在草图顶部输入您从校准草图中获得的六个校准值。用您的实际值替换“0”。

  1. // Define color sensor pins
  2. #define S0 4
  3. #define S1 5
  4. #define S2 6
  5. #define S3 7
  6. #define sensorOut 8

  7. // Calibration Values
  8. // *Get these from Calibration Sketch
  9. int redMin = 0; // Red minimum value
  10. int redMax = 0; // Red maximum value
  11. int greenMin = 0; // Green minimum value
  12. int greenMax = 0; // Green maximum value
  13. int blueMin = 0; // Blue minimum value
  14. int blueMax = 0; // Blue maximum value

  15. // Variables for Color Pulse Width Measurements
  16. int redPW = 0;
  17. int greenPW = 0;
  18. int bluePW = 0;

  19. // Variables for final Color values
  20. int redValue;
  21. int greenValue;
  22. int blueValue;

  23. void setup() {
  24.         // Set S0 - S3 as outputs
  25.         pinMode(S0, OUTPUT);
  26.         pinMode(S1, OUTPUT);
  27.         pinMode(S2, OUTPUT);
  28.         pinMode(S3, OUTPUT);

  29.         // Set Sensor output as input
  30.         pinMode(sensorOut, INPUT);

  31.         // Set Frequency scaling to 20%
  32.         digitalWrite(S0,HIGH);
  33.         digitalWrite(S1,LOW);

  34.         // Setup Serial Monitor
  35.         Serial.begin(9600);
  36. }

  37. void loop() {
  38.         // Read Red value
  39.         redPW = getRedPW();
  40.         // Map to value from 0-255
  41.         redValue = map(redPW, redMin,redMax,255,0);
  42.         // Delay to stabilize sensor
  43.         delay(200);

  44.         // Read Green value
  45.         greenPW = getGreenPW();
  46.         // Map to value from 0-255
  47.         greenValue = map(greenPW, greenMin,greenMax,255,0);
  48.         // Delay to stabilize sensor
  49.         delay(200);

  50.         // Read Blue value
  51.         bluePW = getBluePW();
  52.         // Map to value from 0-255
  53.         blueValue = map(bluePW, blueMin,blueMax,255,0);
  54.         // Delay to stabilize sensor
  55.         delay(200);

  56.         // Print output to Serial Monitor
  57.         Serial.print("Red = ");
  58.         Serial.print(redValue);
  59.         Serial.print(" - Green = ");
  60.         Serial.print(greenValue);
  61.         Serial.print(" - Blue = ");
  62.         Serial.println(blueValue);
  63. }


  64. // Function to read Red Pulse Widths
  65. int getRedPW() {
  66.         // Set sensor to read Red only
  67.         digitalWrite(S2,LOW);
  68.         digitalWrite(S3,LOW);
  69.         // Define integer to represent Pulse Width
  70.         int PW;
  71.         // Read the output Pulse Width
  72.         PW = pulseIn(sensorOut, LOW);
  73.         // Return the value
  74.         return PW;
  75. }

  76. // Function to read Green Pulse Widths
  77. int getGreenPW() {
  78.         // Set sensor to read Green only
  79.         digitalWrite(S2,HIGH);
  80.         digitalWrite(S3,HIGH);
  81.         // Define integer to represent Pulse Width
  82.         int PW;
  83.         // Read the output Pulse Width
  84.         PW = pulseIn(sensorOut, LOW);
  85.         // Return the value
  86.         return PW;
  87. }

  88. // Function to read Blue Pulse Widths
  89. int getBluePW() {
  90.         // Set sensor to read Blue only
  91.         digitalWrite(S2,LOW);
  92.         digitalWrite(S3,HIGH);
  93.         // Define integer to represent Pulse Width
  94.         int PW;
  95.         // Read the output Pulse Width
  96.         PW = pulseIn(sensorOut, LOW);
  97.         // Return the value
  98.         return PW;
  99. }
复制代码

加载草图并使用不同颜色的样本观察结果。如有必要,您可以对校准值进行微调。


代码说明

您会注意到此草图的大部分内容与之前的草图完全相同。首先在到草图顶部,输入您从校准草图中获得的六个校准值。

  1. // Calibration Values
  2. int redMin = 0; // Red minimum value
  3. int redMax = 0; // Red maximum value
  4. int greenMin = 0; // Green minimum value
  5. int greenMax = 0; // Green maximum value
  6. int blueMin = 0; // Blue minimum value
  7. int blueMax = 0; // Blue maximum value
复制代码

为输出的RGB值定义了三个新变量。

  1. int redValue;
  2. int greenValue;
  3. int blueValue;
复制代码

在loop()函数中,我们使用之前草图中使用的相同函数读取每个值。然后我们使用Arduino的map()函数将这些值转换成RGB值,使用我们的校准值作为参考。


请注意,我们已经反转了范围(最小值映射到255,最大值映射到0),因为我们的函数返回脉冲宽度,而不是频率。

  1. // Read Red value
  2. redPW = getRedPW();
  3. // Map to value from 0-255
  4. redValue = map(redPW, redMin,redMax,255,0);
  5. // Delay to stabilize sensor
  6. delay(200);
复制代码

最后,我们在串口监视器上输出值。这些最终读数将对应于被扫描物体的RGB值。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 714 | 回复: 1501



手机版|

GMT+8, 2024-12-22 09:08 , Processed in 0.053046 second(s), 10 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表