风筝
发表于: 2019-8-14 22:21:39 | 显示全部楼层

在本篇文章中,您将了解TCS230传感器以及如何将其与Arduino开发板一起使用来识别颜色。在本文结束时,您将找到一个创建颜色选择笔的迷人想法。使用此笔,您可以扫描周围物体的颜色,并使用该颜色开始在LCD上绘画。


什么是TSC230传感器?

TSC230芯片包含一个8×8阵列的硅光电二极管,可用于识别颜色。这些光电二极管中的16个具有红色滤光器,16个具有绿色滤光器,16个具有蓝色滤光器而另外16个没有滤光器。

color-picker-module.jpg

TCS230模块有4个白色LED灯。光电二极管从物体表面接收这些LED的反射光,然后根据它们接收的颜色产生电流。


除光电二极管外,该传感器还有一个电流 - 频率转换器。它将光电二极管产生的电流转换为频率。


该模块的输出采用方波脉冲形式,占空比为50%。


该传感器的最佳测量范围约为2至4厘米。

color-picker-diagram.jpg


TCS230引脚分布

TCS230有4个控制引脚。 S0和S1用于输出频率缩放,S2和S3用于选择光电二极管的类型。 (红色、绿色、蓝色、无过滤器)

color-picker-pinout-1.png

color-picker-pinout.jpg

电流 - 频率转换器电路具有分频器。您可以使用S0和S1控制引脚控制此分频器。

例如,如果要测量对象中蓝色的值,则应将S2引脚状态设置为低,并将S3引脚状态设置为高电平。


所需的材料

●    Arduino UNO R3开发板

●    TCS230颜色识别传感器模块

●    面包板

●    RGB LED灯

●    2.4“TFT LCD显示屏

●    公对母跳线

●    220欧姆电阻

●    Arduino IDE

color-picker-required-materials.jpg


TCS239色彩传感器与Arduino的连接

如下图所示,将传感器连接到Arduino开发板。然后通过初始化引脚S0到S4来分析不同颜色的输出。

color-picker-circuit-2.png


代码

以下代码测量三种颜色中每种颜色的输出信号,并在串口上显示结果。

  1. /*
  2.   TCS230 color recognition sensor
  3.   modified on 7 May 2019
  4.   by Mohammadreza Akbari @ Electropeak
  5.   https://electropeak.com/learn/

  6. Color Sensor      Arduino
  7. -----------      --------
  8. VCC               5V
  9. GND               GND
  10. s0                8
  11. s1                9
  12. s2                10
  13. s3                11
  14. OUT               12
  15. OE                GND
  16. */
  17. const int s0 = 8;  
  18. const int s1 = 9;  
  19. const int s2 = 10;  
  20. const int s3 = 11;  
  21. const int out = 12;   
  22. // LED pins connected to Arduino
  23. int redLed = 2;  
  24. int greenLed = 3;  
  25. int blueLed = 4;
  26. // Variables  
  27. int red = 0;  
  28. int green = 0;  
  29. int blue = 0;

  30. void color()  
  31. {   
  32.   digitalWrite(s2, LOW);  
  33.   digitalWrite(s3, LOW);  
  34.   //count OUT, pRed, RED  
  35.   red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);  
  36.   digitalWrite(s3, HIGH);  
  37.   //count OUT, pBLUE, BLUE  
  38.   blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);  
  39.   digitalWrite(s2, HIGH);  
  40.   //count OUT, pGreen, GREEN  
  41.   green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);  
  42. }
  43.    
  44. void setup()   
  45. {  
  46.   Serial.begin(9600);
  47.   pinMode(s0, OUTPUT);  
  48.   pinMode(s1, OUTPUT);  
  49.   pinMode(s2, OUTPUT);  
  50.   pinMode(s3, OUTPUT);  
  51.   pinMode(out, INPUT);  
  52.   pinMode(redLed, OUTPUT);  
  53.   pinMode(greenLed, OUTPUT);  
  54.   pinMode(blueLed, OUTPUT);  
  55.   digitalWrite(s0, HIGH);  
  56.   digitalWrite(s1, HIGH);  
  57. }  
  58.    
  59. void loop()
  60. {  
  61.   color();
  62.   Serial.print("R Intensity:");  
  63.   Serial.print(red, DEC);  
  64.   Serial.print(" G Intensity: ");  
  65.   Serial.print(green, DEC);  
  66.   Serial.print(" B Intensity : ");  
  67.   Serial.print(blue, DEC);  
  68.   //Serial.println();  

  69.   if (red < blue && red < green && red < 20)
  70.   {  
  71.    Serial.println(" - (Red Color)");  
  72.    digitalWrite(redLed, HIGH); // Turn RED LED ON
  73.    digitalWrite(greenLed, LOW);  
  74.    digitalWrite(blueLed, LOW);  
  75.   }  

  76.   else if (blue < red && blue < green)   
  77.   {  
  78.    Serial.println(" - (Blue Color)");  
  79.    digitalWrite(redLed, LOW);  
  80.    digitalWrite(greenLed, LOW);  
  81.    digitalWrite(blueLed, HIGH); // Turn BLUE LED ON  
  82.   }  

  83.   else if (green < red && green < blue)  
  84.   {  
  85.    Serial.println(" - (Green Color)");  
  86.    digitalWrite(redLed, LOW);  
  87.    digitalWrite(greenLed, HIGH); // Turn GREEN LED ON
  88.    digitalWrite(blueLed, LOW);  
  89.   }  
  90.   else{
  91.   Serial.println();  
  92.   }
  93.   delay(300);   
  94.   digitalWrite(redLed, LOW);  
  95.   digitalWrite(greenLed, LOW);  
  96.   digitalWrite(blueLed, LOW);  
  97. }
复制代码

color()函数控制S2和S3引脚读取对象的所有颜色。此函数使用pulseln命令通过颜色传感器接收发送的脉冲。


TCS230色彩传感器校准

为了校准传感器,您需要一个白色物体。

calibrate()函数执行传感器的校准。为此,只需在串口中输入字符“c”即可。然后移除传感器周围的所有彩色物体并重新输入“c”。现在在传感器附近取一个白色物体,再次输入“c”。


校准后,如果将白色物体放在传感器前面,则应该在串行窗口中看到三种红色,绿色和蓝色中每种颜色的值255(或大约255)。


calibrate()函数可在非彩色和白色环境中计算和存储传感器输出频率的最大和最小变化。


然后在loop函数部分中,它将颜色更改范围映射到0-255(或您定义的任何其他范围)。


代码

  1. /*
  2.   // TCS230 color recognition with calibration
  3.   modified on 7 May 2019
  4.   by Mohammadreza Akbari @ Electropeak
  5.   https://electropeak.com/learn/

  6.   Color Sensor      Arduino
  7.   -----------      --------
  8.   VCC               5V
  9.   GND               GND
  10.   s0                8
  11.   s1                9
  12.   s2                10
  13.   s3                11
  14.   OUT               12
  15.   OE                GND
  16. */
  17. const int s0 = 8;
  18. const int s1 = 9;
  19. const int s2 = 10;
  20. const int s3 = 11;
  21. const int out = 12;
  22. // LED pins connected to Arduino
  23. int redLed = 5;
  24. int greenLed = 6;
  25. int blueLed = 3;
  26. // Variables
  27. int red = 0;
  28. int green = 0;
  29. int blue = 0;

  30. // Calibrated value
  31. int cal_min = 5;
  32. int cal_max_r = 50;
  33. int cal_max_g = 50;
  34. int cal_max_b = 50;

  35. void calibrate() {
  36.   Serial.println("Clear sensor area. Then enter c again");
  37.     while (Serial.read() != 'c') {
  38.       //do nothing
  39.       ;
  40.     }
  41.     color();
  42.     cal_max_r = red;
  43.     cal_max_g = green;
  44.     cal_max_b = blue;
  45.     Serial.println("Put white color infront of sensor, Then enter c again");
  46.     while (Serial.read() != 'c') {
  47.       //do nothing
  48.       ;
  49.     }
  50.     color();
  51.     cal_min = (red + green + blue) / 3;
  52.     Serial.println("calibrated successfully.");
  53.     delay(300);
  54. }

  55. void color() {
  56.   digitalWrite(s2, LOW);
  57.   digitalWrite(s3, LOW);
  58.   //count OUT, pRed, RED
  59.   red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  60.   digitalWrite(s3, HIGH);
  61.   //count OUT, pBLUE, BLUE
  62.   blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  63.   digitalWrite(s2, HIGH);
  64.   //count OUT, pGreen, GREEN
  65.   green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  66. }

  67. void setup()
  68. {
  69.   Serial.begin(9600);
  70.   pinMode(s0, OUTPUT);
  71.   pinMode(s1, OUTPUT);
  72.   pinMode(s2, OUTPUT);
  73.   pinMode(s3, OUTPUT);
  74.   pinMode(out, INPUT);
  75.   pinMode(redLed, OUTPUT);
  76.   pinMode(greenLed, OUTPUT);
  77.   pinMode(blueLed, OUTPUT);
  78.   digitalWrite(s0, HIGH);
  79.   digitalWrite(s1, HIGH);
  80. }

  81. void loop()
  82. {
  83.   color();
  84.   if (Serial.read() == 'c') {
  85.     calibrate();
  86.   }


  87.   red = map(red, cal_min, cal_max_r, 255, 0);
  88.   green = map(green, cal_min, cal_max_g, 255, 0);
  89.   blue = map(blue, cal_min, cal_max_b, 255, 0);
  90.   Serial.print("R Intensity:");
  91.   Serial.print(red);
  92.   Serial.print(" G Intensity: ");
  93.   Serial.print(green);
  94.   Serial.print(" B Intensity : ");
  95.   Serial.println(blue);
  96.   delay(200);
  97. }
复制代码

使用TCS230传感器和Arduino制作拾色笔

如果使用Arduino UNO,则必须使用电线将颜色传感器引脚焊接到Arduino板上。 但是如果你使用Arduino MEGA,你可以使用电路板的最后一个引脚将颜色传感器连接到它。

以下代码在LCD上创建绘画页面。 笔的默认颜色为红色。 按住键并将颜色传感器关闭到所需对象以选择其颜色。 然后笔的颜色会变为该对象的颜色。


电路

color-picker-circuit-1.png


代码

  1. /*
  2.   TCS230 color picker + paint
  3.   Modified on 8 May 2019
  4.   By Mohammadreza Akbari @ Electropeak
  5.   https://electropeak.com/learn/

  6.   Color Sensor      Arduino
  7.   -----------      --------
  8.   VCC               5V
  9.   GND               GND
  10.   s0                5V
  11.   s1                5V
  12.   s2                10
  13.   s3                11
  14.   OUT               12
  15.   OE                GND
  16. */

  17. #include <Adafruit_GFX.h>    // Core graphics library
  18. #include <Adafruit_TFTLCD.h> // Hardware-specific library
  19. #include <TouchScreen.h>

  20. #if defined(__SAM3X8E__)
  21. #undef __FlashStringHelper::F(string_literal)
  22. #define F(string_literal) string_literal
  23. #endif

  24. //LCD
  25. #define YP A3  // must be an analog pin, use "An" notation!
  26. #define XM A2  // must be an analog pin, use "An" notation!
  27. #define YM 9   // can be a digital pin
  28. #define XP 8   // can be a digital pin

  29. #define TS_MINX 150
  30. #define TS_MINY 120
  31. #define TS_MAXX 920
  32. #define TS_MAXY 940

  33. // For better pressure precision, we need to know the resistance
  34. // between X+ and X- Use any multimeter to read it
  35. // For the one we're using, its 300 ohms across the X plate
  36. TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

  37. #define LCD_CS A3
  38. #define LCD_CD A2
  39. #define LCD_WR A1
  40. #define LCD_RD A0
  41. // optional
  42. #define LCD_RESET A4

  43. // Assign human-readable names to some common 16-bit color values:
  44. #define BLACK   0x0000
  45. #define BLUE    0x001F
  46. #define RED     0xF800
  47. #define GREEN   0x07E0
  48. #define CYAN    0x07FF
  49. #define MAGENTA 0xF81F
  50. #define YELLOW  0xFFE0
  51. #define WHITE   0xFFFF

  52. Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

  53. #define BOXSIZE 40
  54. #define PENRADIUS 3
  55. int oldcolor, ccolor;

  56. #define MINPRESSURE 10
  57. #define MAXPRESSURE 1000

  58. //Color sensor
  59. const int s2 = 10;
  60. const int s3 = 11;
  61. const int out = 12;

  62. const int button = 13;


  63. // Color variables
  64. int red = 0;
  65. int green = 0;
  66. int blue = 0;

  67. // Calibrated value
  68. int cal_min = 5;
  69. int cal_max_r = 50;
  70. int cal_max_g = 50;
  71. int cal_max_b = 50;

  72. uint16_t my_color;

  73. void calibrate() {
  74.   Serial.println("Clear sensor area. Then enter c again");
  75.   while (Serial.read() != 'c') {
  76.     //do nothing
  77.     ;
  78.   }
  79.   color();
  80.   cal_max_r = red;
  81.   cal_max_g = green;
  82.   cal_max_b = blue;
  83.   Serial.println("Put white color infront of sensor, Then enter c again");
  84.   while (Serial.read() != 'c') {
  85.     //do nothing
  86.     ;
  87.   }
  88.   color();
  89.   cal_min = (red + green + blue) / 3;
  90.   Serial.println("calibrated successfully.");
  91.   delay(300);
  92. }

  93. void color() {
  94.   digitalWrite(s2, LOW);
  95.   digitalWrite(s3, LOW);
  96.   //count OUT, pRed, RED
  97.   red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  98.   digitalWrite(s3, HIGH);
  99.   //count OUT, pBLUE, BLUE
  100.   blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  101.   digitalWrite(s2, HIGH);
  102.   //count OUT, pGreen, GREEN
  103.   green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  104. }

  105. void pick_color() {
  106.   color();
  107.   red = map(red, cal_min, cal_max_r, 255, 0);
  108.   green = map(green, cal_min, cal_max_g, 255, 0);
  109.   blue = map(blue, cal_min, cal_max_b, 255, 0);

  110.   Serial.print("R Intensity:");
  111.   Serial.print(red);
  112.   Serial.print(" G Intensity: ");
  113.   Serial.print(green);
  114.   Serial.print(" B Intensity : ");
  115.   Serial.println(blue);

  116.   //my_color = tft.color565(abs(255 - red), abs(255 - green), abs(255 - blue));
  117.   my_color = tft.color565(red, green, blue);
  118.   tft.fillRect(0, 0, 6*BOXSIZE, BOXSIZE, my_color);
  119.   

  120.   delay(100);

  121. }

  122. void setup()
  123. {
  124.   Serial.begin(9600);
  125.   tft.reset();
  126.   delay(1000);
  127.   uint16_t identifier = tft.readID();

  128.   if (identifier == 0x9325) {
  129.     Serial.println(F("Found ILI9325 LCD driver"));
  130.   } else if (identifier == 0x9328) {
  131.     Serial.println(F("Found ILI9328 LCD driver"));
  132.   } else if (identifier == 0x7575) {
  133.     Serial.println(F("Found HX8347G LCD driver"));
  134.   } else if (identifier == 0x9341) {
  135.     Serial.println(F("Found ILI9341 LCD driver"));
  136.   } else if (identifier == 0x8357) {
  137.     Serial.println(F("Found HX8357D LCD driver"));
  138.   } else {
  139.     Serial.print(F("Unknown LCD driver chip: "));
  140.     Serial.println(identifier, HEX);
  141.     Serial.println(F("If using the Adafruit 2.8" TFT Arduino shield, the line:"));
  142.     Serial.println(F("#define USE_ADAFRUIT_SHIELD_PINOUT"));
  143.     Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
  144.     Serial.println(F("If using the breakout board, it should NOT be #defined!"));
  145.     Serial.println(F("Also if using the breakout, double-check that all wiring"));
  146.     Serial.println(F("matches the tutorial."));
  147.     return;
  148.   }

  149.   tft.begin(identifier);

  150.   tft.fillScreen(BLACK);

  151.   tft.fillRect(0, 0, 6*BOXSIZE, BOXSIZE, RED);
  152.   my_color = RED;

  153.   pinMode(s2, OUTPUT);
  154.   pinMode(s3, OUTPUT);
  155.   pinMode(out, INPUT);
  156.   pinMode(button, INPUT_PULLUP);
  157. }

  158. void loop()
  159. {
  160.   if (Serial.read() == 'c') {
  161.     calibrate();
  162.   }

  163.   while (digitalRead(button) == LOW) {
  164.     pick_color();
  165.   }

  166.   TSPoint p = ts.getPoint();

  167.   // if sharing pins, you'll need to fix the directions of the touchscreen pins
  168.   //pinMode(XP, OUTPUT);
  169.   pinMode(XM, OUTPUT);
  170.   pinMode(YP, OUTPUT);
  171.   //pinMode(YM, OUTPUT);

  172.   // we have some minimum pressure we consider 'valid'
  173.   // pressure of 0 means no pressing!

  174.   if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
  175.     /*
  176.     Serial.print("X = "); Serial.print(p.x);
  177.     Serial.print("\tY = "); Serial.print(p.y);
  178.     Serial.print("\tPressure = "); Serial.println(p.z);
  179.     */
  180.    
  181.     if (p.y < (TS_MINY-5)) {
  182.       Serial.println("erase");
  183.       // press the bottom of the screen to erase
  184.       tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);
  185.     }
  186.     // scale from 0->1023 to tft.width
  187.     p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
  188.     p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
  189.     /*
  190.     Serial.print("("); Serial.print(p.x);
  191.     Serial.print(", "); Serial.print(p.y);
  192.     Serial.println(")");
  193.     */
  194.    
  195.     if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
  196.       tft.fillCircle(p.x, p.y, PENRADIUS, my_color);
  197.     }
  198.   }
  199. }
复制代码

当按键按下时调用pick_color函数。 它读取位于传感器附近的物体的颜色,并将笔颜色更改为该颜色。


以上就是本文的全部内容,如有问题,请随时在本帖下面进行回复。

跳转到指定楼层
发表于: 2020-4-4 00:05:39 | 显示全部楼层

您好,我想问一下第一步编译完为什么我的LED灯颜色不变T^T
回复

使用道具 举报

风筝
发表于: 2020-4-4 08:12:37 | 显示全部楼层

啥也不会呜呜呜 发表于 2020-4-4 00:05
您好,我想问一下第一步编译完为什么我的LED灯颜色不变T^T

看一下连接方式是否正确
回复

使用道具 举报

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

本版积分规则

主题 700 | 回复: 1480



手机版|

GMT+8, 2024-4-23 15:15 , Processed in 0.046232 second(s), 8 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

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

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