Parts

TCS3200 color sensor

The TCS3200 color sensor (the TCS230 is the same chip's earlier name) on its GY-31 board: one output whose frequency is the color it sees.

This part has a page of its own, with a note on using it and a circuit to try: the part page.

A grid of photodiodes sits behind red, green, blue and clear filters, with four white LEDs to light what it looks at.

Aliases: TCS230, GY-31, color recognition sensor. It is the sensor in most candy and Skittles sorter projects.

There is no bus and no library. Two pins pick a filter, and the output is a square wave: the more of that color in front of the sensor, the higher the frequency. A sketch measures it with pulseIn(), one filter at a time.

Pins

Pin What it does
VCC 2.7 V to 5.5 V.
GND Ground.
S0, S1 Output frequency scaling.
S2, S3 Which photodiodes drive the output.
OE Output enable, active low. Low or unconnected, OUT runs; high, it lets go.
OUT The square wave, 50% duty.
S0 S1 Scaling S2 S3 Filter
LOW LOW Power down LOW LOW Red
LOW HIGH 2% LOW HIGH Blue
HIGH LOW 20% HIGH LOW Clear (no filter)
HIGH HIGH 100% HIGH HIGH Green

Most sketches set 20%: S0 HIGH, S1 LOW. An Uno's pulseIn() keeps up with it easily.

Properties

color is the color of the card in front of the sensor, as #rrggbb. Click one of the cards above the board to change it, before or during Run.

A sketch

const int S0 = 4, S1 = 5, S2 = 6, S3 = 7, OUT = 8;

void setup() {
  pinMode(S0, OUTPUT); pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT); pinMode(S3, OUTPUT);
  pinMode(OUT, INPUT);
  digitalWrite(S0, HIGH); digitalWrite(S1, LOW);  // 20% scaling
  Serial.begin(9600);
}

unsigned long readColor(int s2, int s3) {
  digitalWrite(S2, s2); digitalWrite(S3, s3);
  return pulseIn(OUT, LOW);
}

void loop() {
  unsigned long r = readColor(LOW, LOW);
  unsigned long g = readColor(HIGH, HIGH);
  unsigned long b = readColor(LOW, HIGH);
  Serial.print("R "); Serial.print(r);
  Serial.print("  G "); Serial.print(g);
  Serial.print("  B "); Serial.println(b);
  delay(500);
}

pulseIn() measures how long OUT stays low, half a period. So a shorter pulse means more of that color: a red card gives the shortest pulse on the red filter.

While it runs

The board shows the color in front of it, and the cards still work: click one to swap the card mid-run.

What the model gets right

  • The pin table above, and OE and power-down letting OUT go.
  • The scaling: 2% is a tenth of 20%, which is a fifth of 100%.
  • Each filter picks up a little of its neighbors, as the real filters overlap, and the clear photodiodes see everything.
  • The numbers the common sketches print: at 20% a white card gives pulseIn() lows of about 30 us on each color filter, and a black card about ten times longer.

What it does not do

Noise, infrared, the dark-current frequency, and the distance to the card. Every card reads as if it were a centimeter away under the board's LEDs, and there is no room light. Map your readings with the cards here, then calibrate again on a real sensor: real readings depend on the distance, the room and the card.