回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【雕爷学编程】Arduino动手做(63)---TCS3200D颜色识别传感器4 中等

头像 驴友花雕 2023.07.24 52 0

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验六十三: 颜色传感器GY-33 GY-31 TCS3200D TCS34725颜色识别颜色感应模块
 

5.14-01.jpg

知识点:TCS3200D
是TAOS(Texas Advanced Optoelectronic Solutions)公司推出的可编程彩色光到频率的转换器。它把可配置的硅光电二极管与电流频率转换器集成在一个单一的CMOS电路上,同时在单一芯片上还集成了红绿蓝(RGB)三种滤光器,是业界第一个有数字兼容接口的RGB彩色传感器。TCS3200D的输出信号是数字量,可以驱动标准的TTL或CMOS逻辑输入,因此可直接与微处理器或其它逻辑电路相连接。由于输出的是数字量,并且能够实现每个彩色信道10位以上的转换精度,因而不再需要A/D转换电路,使电路变得更简单。该颜色传感器主要可用于尿液分析仪,生化分析仪,验钞机等需要检测颜色的产品上。
 

5.14-08.jpg

TCS3200D颜色识别传感器(可编程彩色光频识别转换器模块)

主要参数

尺寸:3737mm
固定孔:3mm
孔距:22.622.6mm
电压:5V
芯片:TCS3200D
端口:数字量
输出:10-12KHz,占空比50%
检测距离:10mm
平台:Arduino 单片机

 

主要特点

输出占空比50%
所有的引脚全部引出
采用TCS3200D,性能优于TCS230D
所有IO全部引出,可控式LED补光灯
通过程序可以读取颜色的RGB值
适用于静态物体颜色的检测
注意:不能检测灯光的颜色
检测距离1厘米最佳
检测有效距离小于等于5厘米
可直接和单片机连接
采用高亮白色LED灯反射光
静态识别物体颜色,不同颜色输出不同频率

 

5.14-19.jpg
5.14-20.jpg

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验六十三: 颜色传感器GY-33 GY-31 TCS3200D TCS34725颜色识别颜色感应模块

程序六:使用用RGB LED来重现检测到的颜色

实验接线示意图(注:实际接线有所调整)
 

5.14-37.jpg

Arduino参考开源代码

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序六:使用用RGB LED来重现检测到的颜色
*/

#define s0 6        //模块引脚接线
#define s1 5
#define s2 4
#define s3 3
#define out 2

#define LED_R 9   //LED 引脚,不要忘记“pwm”
#define LED_G 10
#define LED_B 11

int Red = 0, Blue = 0, Green = 0;

void setup() {
  pinMode(LED_R, OUTPUT);    / 引脚模式
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);

  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(out, INPUT);

  Serial.begin(9600);   //初始化串口监视器波特率

  //将 S0/S1 置于 HIGH/HIGH 电平表示输出频率缩放为 100%(推荐)
  digitalWrite(s0, HIGH);
  //LOW/LOW 关闭 HIGH/LOW 为 20%,LOW/HIGH 为 2%
  digitalWrite(s1, HIGH);
}

void loop() {
  GetColors();  //执行GetColors函数,获取颜色

  //analogWrite 生成一个 0-255 值的 PWM 信号(0 为 0V,255 为 5V),
  //LED_R 是我们生成信号的引脚,15/60 是“红色”值的最小值/最大值,尝试测量你自己的
  analogWrite(LED_R, map(Red, 15, 60, 255, 0));
  //例如:如果传感器给出的“红色”值为 15 -> 它将在 LED_R 引脚上生成一个 255 值的 pwm 信号,
  //与 60->0 相同,因为传感器给出的值越低,值越高那个颜色
  analogWrite(LED_G, map(Green, 30, 55, 255, 0));
  analogWrite(LED_B, map(Blue, 13, 45, 255, 0));

}

void GetColors(){
  //S2/S3 级别定义了我们使用的光电二极管 LOW/LOW 
  //代表红色 LOW/HIGH 代表蓝色,HIGH/HIGH 代表绿色
  digitalWrite(s2, LOW);                                           
  digitalWrite(s3, LOW);
  //这里我们等到“out”变低,我们开始测量持续时间并在“out”再次为高时停止,
  //如果你对这个表达式有问题,请检查代码的底部
  Red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);       
  delay(20);
  //这里我们选择其他颜色(光电二极管组)并使用相同的技术测量其他颜色值
  digitalWrite(s3, HIGH);                                         
  Blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  delay(20);
  digitalWrite(s2, HIGH);
  Green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  delay(20);
}

//这里是一个如何理解上面那个表达式的例子,
//""digitalRead(out) == HIGH ? LOW : HIGH"" 这整个表达式要么是 HIGH 要么是 LOW,
//因为 pulseIn 函数在第二个参数上需要一个 HIGH/LOW 值

//led_Status = led_Status == HIGH ? LOW : HIGH;
//
//if(led_Status == HIGH)
//{
//led_Status =LOW;
//}
//else
//{
//led_Status = HIGH;
//}

实验场景图之一(检测到红色,RGB灯亮红色)
 

5.14-38.jpg

实验场景图之二(检测到蓝色,RGB灯亮蓝色)
 

5.14-39.jpg

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验六十三: 颜色传感器GY-33 GY-31 TCS3200D TCS34725颜色识别颜色感应模块
程序七:Arduino 颜色检测器
(1)实验接线示意图(具体有调整)
 

5.14-40.jpg

Arduino参考开源代码(主程序)
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序七:Arduino 颜色检测器(主程序)
*/

#include "stationDefines.h"//导入驱动库

/* 液晶显示器 */
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// 设置 LCD 地址为 0x27; 16个字符2行(使用I2C扫描确认地址)
LiquidCrystal_I2C lcd(0x27, 16, 2); 

void setup() {
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(outPin, INPUT); //从传感器输出成为arduino的输入

  // 将频率缩放设置为 100%
  digitalWrite(s0, HIGH);
  digitalWrite(s1, HIGH);

  Serial.begin(9600);
  //lcd.begin();
  //lcd.noBacklight();
  lcd.init();//初始化LCD屏
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("MJRoBot ColorDet");
  Serial.println("MJRoBot Color Detector");
  startTiming = millis();
}

void loop(){
  getColor();
  if (DEBUG) printData();
  elapsedTime = millis() - startTiming;
  if (elapsedTime > 1000)
  {
    showDataLCD();
    startTiming = millis();
  }
  delay(1000); // 在读数之间等待一秒钟
}

Arduino参考开源代码(副程序之一,保存文件名RGB_Defines)
 

代码
/* 基于 RGB 分量 ==> 确定颜色 */
void getColor(){  
  readRGB();
  
        if (red > 8 && red < 18 && grn > 9 && grn < 19 && blu > 8 && blu < 16) color = "WHITE";
  else if (red > 80 && red < 125 && grn > 90 && grn < 125 && blu > 80 && blu < 125) color = "BLACK";
  else if (red > 12 && red < 30 && grn > 40 && grn < 70 && blu > 33 && blu < 70) color = "RED";
  else if (red > 50 && red < 95 && grn > 35 && grn < 70 && blu > 45 && blu < 85) color = "GREEN";
  else if (red > 10 && red < 20 && grn > 10 && grn < 25 && blu > 20 && blu < 38) color = "YELLOW";
  else if (red > 65 && red < 125 && grn > 65 && grn < 115 && blu > 32 && blu < 65) color = "BLUE";
  else  color = "NO_COLOR";
}

/* 读取 RGB 分量 */
void readRGB() {
  red = 0;
  grn = 0;
  blu = 0;
  int n = 10;
  for (int i = 0; i < n; ++i)
  {
    //读取红色组件
    digitalWrite(s2, LOW);
    digitalWrite(s3, LOW);
    red = red + pulseIn(outPin, LOW);
  
    //读取绿色组件
    digitalWrite(s2, HIGH);
    digitalWrite(s3, HIGH);
    grn = grn + pulseIn(outPin, LOW);
    
    //让我们读取蓝色组件
    digitalWrite(s2, LOW);
    digitalWrite(s3, HIGH);
    blu = blu + pulseIn(outPin, LOW);
  }
  red = red/n;
  grn = grn/n;
  blu = blu/n;
}

Arduino参考开源代码(副程序之二,保存文件名printsplayFunctions)
 

代码
/***************************************************
在串行监视器上显示捕获的数据
****************************************************/
void showDataLCD(void)
{
  lcd.clear();
  lcd.setCursor (0,0);
  lcd.print("R");
  lcd.setCursor (1,0);
  lcd.print("    ");
  lcd.setCursor (1,0);
  lcd.print(red);
  lcd.setCursor (5,0);
  lcd.print(" G");
  lcd.setCursor (7,0);
  lcd.print("    ");
  lcd.setCursor (7,0);
  lcd.print(grn);
  lcd.setCursor (12,0);
  lcd.print("B");
  lcd.setCursor (13,0);
  lcd.print("    ");
  lcd.setCursor (13,0);
  lcd.print(blu);
  
  lcd.setCursor (0,1);
  lcd.print("Color: ");
  lcd.setCursor (7,1); 
  lcd.print("        ");
  lcd.setCursor (7,1);  
  lcd.print(color);
  
}

/***************************************************
* 在串行监视器上显示捕获的数据
****************************************************/
void printData(void)
{
  Serial.print("red= ");
  Serial.print(red);
  Serial.print("   green= ");
  Serial.print(grn);
  Serial.print("   blue= ");
  Serial.print(blu);
  Serial.print (" - ");
  Serial.print (color);
  Serial.println (" detected!");
}

Arduino参考开源代码(相关库文件,保存文件名stationDefines.h)
 

代码
// TCS230 or TCS3200 pins wiring to Arduino
#define s0 4
#define s1 5
#define s2 6
#define s3 7
#define outPin 8

boolean DEBUG = true;

// Variables
int red;
int grn;
int blu;
String color ="";
int count = 0;
long startTiming = 0;
long elapsedTime =0;

上述四个文件需要放在一个文件夹内,打开是这样
 

5.14-41.jpg

实验串口返回情况
 

5.14-42.jpg

Arduino实验场景图

 

5.14-43.jpg
5.14-44.jpg

颜色传感器简介:
我们看到的颜色实际上是反射光的波长,实际上并不存在,但我们被操纵以这种方式看到它。例如,我们看到的红色在整个可见光谱中具有大约 620 到 750 nm 的特定波长。类似地,蓝色具有大约 450 到 495 nm 的波长。另外,请记住,我们看到的颜色实际上是从表面反射的颜色,而其余颜色则被该特定表面吸收。例如,我们看到一个苹果的红色,因为它是从它身上反射出来的颜色。

当我们看一个物体时,实际发生的是彩色表面反射的光到达我们眼睛后部的视网膜。我们的视网膜有许多感光细胞,它们对光做出反应,并在大脑中启动一个化学过程,将光感知为一种特定的颜色。

在计算机中,传感器有助于区分光线。例如,如果我们使用一个简单的光敏电阻(LDR)来检测两个不同颜色表面上的颜色;比如让我们说,红色和蓝色。我们将首先在两个表面上照射红光,红色表面会反射光线,而蓝色表面会吸收光线。因此,对于 LDR,红色表面会显得很亮。同样,当我们照射蓝光时,红色表面会吸收它,而蓝色表面会反射它,蓝色表面看起来很亮。
 

6.jpg

TCS3200 颜色传感器的工作原理:
TCS3200 是一个 8×8 光电二极管阵列。TCS3200 颜色传感器检测颜色并将色光转换为频率。传感器的输出与物体表面反射的光强度成正比。TCS3200 模块具有 RGB 和透明传感器以及嵌入到板上的 4 个 LED。相关图片

光电二极管具有三种不同的滤色器,红色、蓝色、绿色和透明各 16 个。它基本上由感知彩色光的光电二极管组成,然后电流频率转换器将它们转换为频率与光强度成正比的方波。

 

66.jpg

TCS3200 是一款采用 SOC 封装的 8 引脚 IC。每个引脚都有特定的用途。引脚 1 和 2(SO 和 S1)用于缩放输出频率。引脚 3 是输出使能引脚,引脚 4 是 GND。引脚 5 为 VDD,最大电源电压为 5.5 V。引脚 6 是用于方波输出的输出引脚。引脚 7 和 8(S2 和 S3)用于选择光电二极管。主要引脚为 S0、S1 和 S3、S4。这些将用于根据所使用的微控制器来缩放输出方波的频率。不同的微控制器具有不同的定时器配置。频率缩放功能基本上允许传感器的输出针对各种微控制器进行优化。
 

666.jpg

这个项目将使用一个简单的 Arduino 颜色传感器。如前所述,使用的 TCS3200 具有不同的滤色器。每种颜色的强度都有不同的频率。此处使用的 Arduino 通过对颜色传感器的 S0 和 S1 引脚施加 HIGH,将输出频率固定为 100%。颜色传感器的 S2 和 S3 引脚将选择颜色二极管的类型。选择特定光电二极管时,激活Arduino上的脉冲功能。

这与有助于计算输出信号的颜色传感器的输出相连。对于其他光电二极管,红色、绿色和蓝色也是如此。在每种情况下,使用 PULSEIN 功能测量频率并显示在串行终端上。因此检测到的颜色被使用并显示在点亮 LED(发光二极管)的 LCD 上。
 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序八:检测到的颜色被使用并显示在点亮 LED(发光二极管)的 LCD 上
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int red = 0;
int green = 0;
int blue = 0;

void setup(){
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, INPUT);

  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);

  lcd.init();
  lcd.backlight();
}

void loop(){
  digitalWrite(12, LOW);
  digitalWrite(11, LOW);
  red = pulseIn(10, digitalRead(10) == HIGH ? LOW : HIGH);
  digitalWrite(11, HIGH);
  blue = pulseIn(10, digitalRead(10) == HIGH ? LOW : HIGH);
  digitalWrite(12, HIGH);
  green = pulseIn(10, digitalRead(10) == HIGH ? LOW : HIGH);

  lcd.clear();
  if (red < blue && red < green && red < 20)
  {
    Serial.println(" Red Color");
    lcd.print("Red Color");
  }

  else if (blue < red && blue < green)
  {
    Serial.println(" Blue Color");
    lcd.print("Blue Color");
  }

  else if (green < red && green < blue)
  {
    Serial.println(" Green Color");
    lcd.print("Green Color");
  }
  delay(500);
}

实验串口返回情况

 

5.14-45.jpg

Arduino实验场景图

 

5.14-46.jpg

程序九:将颜色数值打印到带有 i2c接口的LCD上
(1)Arduino参考开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序九:将颜色数值打印到带有 i2c接口的LCD上
*/

#include <Wire.h>//IIC驱动库
#include <LiquidCrystal_I2C.h>//1602屏驱动库
//TCS3200 引脚连接到 Arduino
#define S1 9
#define S0 8
#define S3 12
#define S2 11
#define sensorOut 10
// 将 LCD 地址设置为 0x27 或 0x3f 以实现 16 个字符和 2 行显示
LiquidCrystal_I2C lcd(0x27, 16, 2);
// 存储光电二极管读取的频率
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  // 设置输出
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  //将sensorOut设置为输入
  pinMode(sensorOut, INPUT)
  // 将频率缩放设置为 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  // 开始串行通信
  Serial.begin(9600);

}
void loop() {
  // 设置要读取的 红色 (R) 过滤光电二极管
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("R      G      B");

  // 读取输出频率
  redFrequency = pulseIn(sensorOut, LOW);

  // 打印 红色 (R) 值
  Serial.print("R = ");
  Serial.print(redFrequency);
  lcd.setCursor(0, 1);
  lcd.print(redFrequency);
  delay(100);

  // 设置要读取的绿色 (G) 滤波光电二极管
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);

  // 读取输出频率
  greenFrequency = pulseIn(sensorOut, LOW);

  //打印绿色(G)值
  Serial.print(" G = ");
  Serial.print(greenFrequency);
  lcd.setCursor(6, 1);
  lcd.print(greenFrequency);
  delay(100);

  // 设置要读取的蓝色 (B) 过滤光电二极管
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);

  // 读取输出频率
  blueFrequency = pulseIn(sensorOut, LOW);

  // 打印蓝色 (B) 值
  Serial.print(" B = ");
  Serial.println(blueFrequency);
  lcd.setCursor(13, 1);
  lcd.print(blueFrequency);
  delay(100);
}

实验串口返回情况
 

5.14-47.jpg

打开Arduino IDE——工具——串口绘图器,查看实验波形
实验串口绘图器返回情况
 

5.14-48.jpg

Arduino实验场景图

 

5.14-49.jpg

评论

user-avatar
icon 他的勋章
    展开更多