Arduino筆記(58):顏色感測器TCS3200 (GY-31)

在自動化展時曾看過有條輸送帶,旁邊有個機械手臂,當通過的小方塊是哪一種顏色,就會被機械手臂夾起,相同顏色的放在一堆。心想應該有個感測器是偵測顏色的,TCS3200 顏色感測器就是這樣的功能,用來判斷紅、綠、藍(RGB)三原色,以下實作就來看一下如何運用濾光片來測得物體的顏色。

[TCS3200檢測原理]

TCS3200色彩傳感器是一個完整的色彩檢測器,包括一個TAOS TCS3200 RGB傳感器芯片和4個白色LED。TCS3200可以檢測和測量幾乎無限範圍的可見顏色。應用包括測試條讀取,顏色分類,環境光感測和校準以及顏色匹配。
根據三原色理論可知,各種顏色是由不同比例的三原色(紅、綠、藍)混合而成的。TCS3200就是使用這個原理,來辨別物體的顏色。透過一個陣列的光電檢測器,每個都有紅色,綠色或藍色濾光片,或沒有濾光片(透明)。
在感測一個物體的顏色時,需輪流讓三個顏色通過濾波器檢測,分析投射到TCS3200感測器上的光來判斷顏色,分別得到三個值後,才知道是哪種顏色。以S2和S3設置為低電位和高電位為例,此時僅允許藍色光通過,此時接收藍色光的數值,依此類推,最後蒐集三個顏色的數值,所組成的就是該物體的顏色。

[TCS3200 特性]

  • 晶片:TCS3200
  • 電源:2.7V至5.5V
  • 具備 LED 燈
  • 抗光干擾、白色LED,可控制亮或滅、可檢測不發光物體顏色
  • 最佳檢測距離:1 cm

接腳說明
接腳名稱
描述
GND4
電源接地
OE3
輸入,啟用輸出頻率(低電位有效)
OUT6
輸出頻率
S0S11,2
輸入,選擇輸出頻率縮放
S2S37,8
選擇輸入光電二極管類型
VDD5
電壓供應
當S0與S1各自的HIGH與LOW組合會影響輸出頻率。對於Arduino,通常使用20%的頻率縮放。因此,將S0引腳設置為高電平,將S1引腳設置為低電平。
S0
S1
輸出頻率級距
LOW
LOW
沒有電源
LOW
HIGH
2%
HIGH
LOW
20%
HIGH
HIGH
100%
要感測器讀取的顏色時,可透過控制接腳 S2和S3來達成。下表是S2跟S3設定高低電位時過濾的顏色表。
S2
S3
過濾顏色
LOW
LOW
紅色 RED
LOW
HIGH
藍色 BLUE
HIGH
LOW
不過濾 (清除)
HIGH
HIGH
綠色 GREEN

[材料]

• Arduino Leonardo x 1
• GY-31 TCS3200顏色感測器模組
• 連接線 x 7 條

[接線]

Arduino
GY-31 TCS3200
5V (VCC)
VCC
GND
GND
Pin 4
S0
Pin 5
S1
Pin 6
S2
Pin 7
S3
Pin 8
OUT


[程式]

因每個感測器的靈敏度不同,第一個程式先讀取紅藍綠三個顏色值,找到最大跟最小的感測範圍,再由第二個程式判斷檢測值落在哪個範圍來判斷物體的顏色。
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8

// 儲存由光電二極體讀取的值
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;

void setup() {
  // 設定S0~S4為輸出
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  
  // 設定 sensorOut 為輸出
  pinMode(sensorOut, INPUT);
  
  // 設定頻率尺度(frequency scaling)為 20%
  digitalWrite(S0,HIGH);
  digitalWrite(S1,LOW);
  
   // 開始串列通訊
  Serial.begin(9600);
}
void loop() {
  // 設定光電二極體讀取濾過的紅色值
  digitalWrite(S2,LOW);
  digitalWrite(S3,LOW);
  
  // 讀取輸出頻率
  redFrequency = pulseIn(sensorOut, LOW);
  
   // 列出紅色值
  Serial.print("R = ");
  Serial.print(redFrequency);
  delay(100);
  
  // 設定光電二極體讀取濾過的綠色值
  digitalWrite(S2,HIGH);
  digitalWrite(S3,HIGH);
  
  // 讀取輸出頻率
  greenFrequency = pulseIn(sensorOut, LOW);
  
  // 列出綠色值 
  Serial.print(" G = ");
  Serial.print(greenFrequency);
  delay(100);
 
  // 設定光電二極體讀取濾過的藍色值
  digitalWrite(S2,LOW);
  digitalWrite(S3,HIGH);
  
  // 讀取輸出頻率
  blueFrequency = pulseIn(sensorOut, LOW);
  
  // 列出藍色值,並換行
  Serial.print(" B = ");
  Serial.println(blueFrequency);
  delay(100);
}

以下是程式二,直接列出物體顏色:

#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8

// 儲存由光電二極體讀取的值
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;

// 儲存紅、藍、綠色的值
int redColor = 0;
int greenColor = 0;
int blueColor = 0;

void setup() {
  // 設定S0~S4為輸出
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  
  // 設定 sensorOut 為輸出
  pinMode(sensorOut, INPUT);
  
  // 設定頻率尺度(frequency scaling)為 20%
  digitalWrite(S0,HIGH);
  digitalWrite(S1,LOW);
  
  // 開始串列通訊
  Serial.begin(9600);
}

void loop() {
  // 設定光電二極體讀取濾過的紅色值
  digitalWrite(S2,LOW);
  digitalWrite(S3,LOW);
  
  // 讀取輸出頻率
  redFrequency = pulseIn(sensorOut, LOW);
  
  // 重新對應讀取的紅色值範圍從 0 到 255
  // 以下的 min 及 max 是前一個程式讀取的最大跟最小值的範圍,需依感測模組而調整 
  // redColor = map(redFrequency, min, max, 255,0);
  redColor = map(redFrequency, 332, 1280, 255,0);
  
  // 列出紅色值
  Serial.print("R = ");
  Serial.print(redColor);
  delay(100);
  
  // 設定光電二極體讀取濾過的綠色值
  digitalWrite(S2,HIGH);
  digitalWrite(S3,HIGH);
  
  // 讀取輸出頻率
  greenFrequency = pulseIn(sensorOut, LOW);
  
  // 重新對應讀取的綠色值範圍從 0 到 255
  // 以下的 min 及 max 是前一個程式讀取的最大跟最小值的範圍,需依感測模組而調整 
  // greenColor = map(greenFrequency, min, max, 255, 0);
  greenColor = map(greenFrequency, 850, 1498, 255, 0);
  
  // 列出綠色值 
  Serial.print(" G = ");
  Serial.print(greenColor);
  delay(100);
 
  // 設定光電二極體讀取濾過的藍色值
  digitalWrite(S2,LOW);
  digitalWrite(S3,HIGH);
  
  // 讀取輸出頻率
  blueFrequency = pulseIn(sensorOut, LOW);
  
  // 重新對應讀取的藍色值範圍從 0 到 255
  // 以下的 min 及 max 是前一個程式讀取的最大跟最小值的範圍,需依感測模組而調整 
  blueColor = map(blueFrequency, 178, 459, 255, 0);
  
  // 列出藍色值
  Serial.print(" B = ");
  Serial.print(blueColor);
  delay(100);

  // 檢查目前測得的顏色值,並顯示物體顏色在串列 Console
  if(redColor > greenColor && redColor > blueColor){
      Serial.println(" - RED detected!");
  }
  if(greenColor > redColor && greenColor > blueColor){
    Serial.println(" - GREEN detected!");
  }
  if(blueColor > redColor && blueColor > greenColor){
    Serial.println(" - BLUE detected!");
  }
}


[實作結果]


[參考資料]

• Randomnerdtutorials:Guide for TCS230/TCS3200 Color Sensor with Arduino
• How to mechatronics:Arduino Color Sensing Tutorial – TCS230 TCS3200 Color Sensor

1 留言

  1. 如果要發出聲音講調感測到的顏色要怎麼改程式

    回覆刪除

張貼留言

較新的 較舊