Part

Color sensor, TCS3200 / TCS230 (GY-31)

S2 and S3 pick red, green, blue or clear, and OUT is a square wave whose frequency is that color: read it with pulseIn.

See every part
  • 8 pins
  • 1 setting
  • In 1 project
Drawn live by the editor's own code, at the size you see it.
At a glance

The Color sensor, TCS3200 / TCS230 (GY-31) in brief

What it is, and every setting the properties panel gives it.

The TCS3200 color sensor, on the GY-31 board, has no bus and no library. Behind its lens is an 8 by 8 grid of photodiodes, a quarter behind red filters, a quarter green, a quarter blue and a quarter bare, with four white LEDs to light the card. Two pins, S2 and S3, choose which group is read, and the output pin OUT is a square wave whose frequency is how much of that color the sensor sees. S0 and S1 scale the output to 2, 20 or 100 percent, or power the chip down. A sketch times the wave with pulseIn(), one filter at a time. The Mokxi model keeps the scaling ratios, the filters that overlap a little with their neighbors, and the numbers the common sketches print: at 20 percent a white card gives pulses of about 30 microseconds on each color filter and a black card about ten times longer. Noise, infrared and the distance to the card are not modeled.

Family
Sensors
Pins
8
color
#d8262e
Pins

8 pins

Named as the editor names them, so a wire lands where you expect it.

Pin
Role
What it does
VCC
Input or output
2.7 V to 5.5 V.
GND
Input or output
Ground.
S0
Input or output
Output frequency scaling.
S1
Input or output
Output frequency scaling.
S2
Input or output
Which photodiodes drive the output.
S3
Input or output
Which photodiodes drive the output.
OE
Input or output
Output enable, active low. Low or unconnected, OUT runs; high, it lets go.
OUT
Output
The square wave, 50% duty.
How to use it

How to read a TCS3200 (GY-31) color sensor with an Arduino

The project has no microcontroller. VCC goes to 5 V and GND to ground, S0 is tied to 5 V and S1 to ground, which is the 20 percent scaling most sketches use, and OE is tied to ground, which turns the output on. Two slide switches drive S2 and S3, each starting on ground so the sensor starts on the red filter, and a frequency counter on OUT reads the wave.

The card in front of the sensor is red. On the red filter the counter reads about 14 kHz. Slide the right switch to select the blue filter and it falls to about 4 kHz. Change the card to white and the red filter reads about 18 kHz, and set it to black and it falls to about a twentieth of that. More of a color means a higher frequency, which is the opposite of what a pulseIn() reading looks like.

In a sketch, pulseIn(OUT, LOW) times half a cycle, so at 14 kHz that is about 36 microseconds and the lower the number the more of that color. The filter table is easy to get backward: S2 and S3 low is red, low and high is blue, high and low is clear, and both high is green. Every card here reads as if it were a centimeter from the sensor under its own LEDs with no room light, so calibrate again on real hardware.

Part pin
Board pin
VCC
5 V (2.7 V to 5.5 V)
GND
Ground
S0, S1
S0 high, S1 low: 20 percent scaling
S2, S3
Two switches, or two board pins, to choose the filter
OE
Ground, or unconnected: output on
OUT
A frequency counter, or a board pin for pulseIn()

The chip runs from 2.7 V to 5.5 V, so a 3.3 V ESP32 or Pico drives it directly. Use the same pulseIn() timing on any board.

Color to frequency with a counterlive0.000 s 0.00x
Hold the button
This is the simulator itself, running here. Click anything to open it in the editor.
Reading red, green and blue with pulseIn()
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);       // shorter pulse, more of that color
}

void loop() {
  Serial.print("R "); Serial.print(readColor(LOW, LOW));
  Serial.print("  G "); Serial.print(readColor(HIGH, HIGH));
  Serial.print("  B "); Serial.println(readColor(LOW, HIGH));
  delay(500);
}
Common errors

Common Color sensor, TCS3200 / TCS230 (GY-31) errors and fixes

What goes wrong
The fix
Red and blue readings are swapped.
The filter table is not in order. S2 and S3 low is red, low and high is blue, high and low is clear, and both high is green.
OUT shows nothing at all.
OE is high, or S0 and S1 are both low, which powers the chip down. Take OE low or leave it open, and set S0 and S1 for a scale.
A larger number is read as more of the color.
pulseIn() measures the length of a pulse, not the frequency. A shorter pulse means a higher frequency, so more of that color.
Readings do not match between the simulator and a real sensor.
Real readings depend on the distance, the room and the card. Map your values with the cards here, then calibrate again on the hardware.
Questions

Questions and answers

How does the TCS3200 output a color?

As a frequency. S2 and S3 choose the red, green, blue or clear photodiodes, and OUT is a 50 percent duty square wave whose frequency rises with the amount of that color.

What do S0 and S1 do?

They scale the output frequency: low-high is 2 percent, high-low 20 percent, high-high 100 percent and low-low powers the chip down. Most sketches use 20 percent, which an Uno’s pulseIn() keeps up with easily.

Is the TCS230 the same chip?

Yes. The TCS230 is the TCS3200’s earlier name, and the GY-31 board carries it.

Does the TCS3200 need a library?

No. There is no bus. Set the two filter pins, read OUT with pulseIn() and compare the three numbers.

How it is modeled

What is true about the Color sensor, TCS3200 / TCS230 (GY-31), here

In its help article’s own words: what the simulation gets right, and where it stops.

Modeled

  • 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.

From TCS3200 color sensor, in full.

Projects

See the Color sensor, TCS3200 / TCS230 (GY-31) in a project

One built-in project uses it. It opens in the editor, already wired.

Wire up the Color sensor, TCS3200 / TCS230 (GY-31)

Open the editor and push it into the breadboard. It is free, and it runs on your own machine.