Arduino UNO R4 - TCS3200D/TCS230 Color Sensor

This guide will show you how to use Arduino UNO R4 and the TCS3200D/TCS230 color recognition sensor module to calibrate and read RGB values from objects and detect colors.

Arduino UNO R4 with TCS3200D TCS230 color recognition sensor module tutorial

Overview of TCS3200D/TCS230 Color Sensor

The TCS3200D/TCS230 is a color recognition sensor module that uses an 8x8 array of photodiodes. Sixteen photodiodes have red filters, 16 have green filters, 16 have blue filters, and 16 are clear (no filter). The module converts light intensity into a square-wave frequency signal. By switching the color filters and measuring the output frequency (or pulse width), we can estimate the RGB values of an object.

Many modules include white LEDs to illuminate the target. This makes the readings more consistent and helps the sensor detect colors reliably, even in low light.

Pinout

The TCS3200D/TCS230 color sensor module typically has these pins:

  • VCC pin: Connect this pin to VCC (5V).
  • GND pin: Connect this pin to GND (0V).
  • S0, S1 pins: Output frequency scaling selection.
  • S2, S3 pins: Color filter selection.
  • OUT pin: Square-wave frequency output.
  • OE pin: Output enable (active LOW). Most modules already connect this pin to GND internally, so you do not need to wire it. If yours does not, connect it to GND.
TCS3200 TCS230 color sensor module pinout diagram showing VCC GND S0 S1 S2 S3 OUT pins

How It Works

The sensor needs to be told two things: which color channel to measure, and how strong to make the output signal. Two pairs of control pins handle this:

  • S0 and S1 control the output frequency scaling:
  • S0 = LOW, S1 = LOW: Power down
  • S0 = LOW, S1 = HIGH: 2% scaling
  • S0 = HIGH, S1 = LOW: 20% scaling
  • S0 = HIGH, S1 = HIGH: 100% scaling
  • S2 and S3 select the color filter:
  • S2 = LOW, S3 = LOW: Red filter
  • S2 = LOW, S3 = HIGH: Blue filter
  • S2 = HIGH, S3 = LOW: Clear (no filter)
  • S2 = HIGH, S3 = HIGH: Green filter

The OUT pin outputs a square wave (typically 2 Hz to 500 kHz). The frequency is proportional to the intensity of the selected color, while the pulse width is inversely proportional. We can measure the pulse width using pulseIn() and then convert it to RGB values after calibration.

Tips for Stable Readings

  • Place the sensor 1-3 cm from the object and keep the angle consistent.
  • Use the built-in white LEDs to provide stable lighting.
  • Shield the sensor from ambient light changes for more accurate results.

Wiring Diagram

This image shows how to connect the TCS3200 color sensor to Arduino UNO R4:

TCS3200 Color SensorArduino UNO R4
VCC5V
GNDGND
S0Pin 4
S1Pin 5
S2Pin 6
S3Pin 7
OUTPin 8
The wiring diagram between Arduino UNO R4 and TCS3200 color sensor  showing connection between pins

This image is created using Fritzing. Click to enlarge image

See The best way to supply power to the Arduino Uno R4 and other components.

Arduino UNO R4 Code - Calibration (Pulse Width)

Calibration is required because the sensor’s raw readings are affected by the environment. Factors such as LED brightness, distance, surface reflectivity, and ambient light change the measured values. You can think of these effects as “noise.” The first calibration step helps you measure that noise range (minimum and maximum for each color) so you can subtract its influence and map readings to correct 0–255 RGB values for your setup.

/* * This Arduino UNO R4 code was developed by newbiely.com * * This Arduino UNO R4 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-tcs3200d-tcs230-color-sensor */ // Define color sensor pins #define S0 4 #define S1 3 #define S2 6 #define S3 5 #define sensorOut 7 // Variables for Color Pulse Width Measurements int redPW = 0; int greenPW = 0; int bluePW = 0; // Variables to track min and max pulse widths for calibration int redMin = 10000, redMax = 0; int greenMin = 10000, greenMax = 0; int blueMin = 10000, blueMax = 0; void setup() { // Set S0 - S3 as outputs pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); // Set Pulse Width scaling to 20% digitalWrite(S0, HIGH); digitalWrite(S1, LOW); // Set Sensor output as input pinMode(sensorOut, INPUT); // Setup Serial Monitor Serial.begin(9600); Serial.println("=== TCS3200 Calibration ==="); Serial.println("Point the sensor at different objects (white, black, colors)."); Serial.println("Min and Max values are tracked automatically."); Serial.println("When values look stable, note them down for the next code."); Serial.println("------------------------------------------"); } void loop() { // Read Red Pulse Width redPW = getRedPW(); // Delay to stabilize sensor delay(200); // Read Green Pulse Width greenPW = getGreenPW(); // Delay to stabilize sensor delay(200); // Read Blue Pulse Width bluePW = getBluePW(); // Delay to stabilize sensor delay(200); // Update min and max values if (redPW < redMin) redMin = redPW; if (redPW > redMax) redMax = redPW; if (greenPW < greenMin) greenMin = greenPW; if (greenPW > greenMax) greenMax = greenPW; if (bluePW < blueMin) blueMin = bluePW; if (bluePW > blueMax) blueMax = bluePW; // Print current readings Serial.print("Red PW = "); Serial.print(redPW); Serial.print(" - Green PW = "); Serial.print(greenPW); Serial.print(" - Blue PW = "); Serial.println(bluePW); // Print current min/max Serial.print(" Min -> R:"); Serial.print(redMin); Serial.print(" G:"); Serial.print(greenMin); Serial.print(" B:"); Serial.println(blueMin); Serial.print(" Max -> R:"); Serial.print(redMax); Serial.print(" G:"); Serial.print(greenMax); Serial.print(" B:"); Serial.println(blueMax); Serial.println("------------------------------------------"); } // Function to read Red Pulse Widths int getRedPW() { // Set sensor to read Red only digitalWrite(S2, LOW); digitalWrite(S3, LOW); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to read Green Pulse Widths int getGreenPW() { // Set sensor to read Green only digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to read Blue Pulse Widths int getBluePW() { // Set sensor to read Blue only digitalWrite(S2, LOW); digitalWrite(S3, HIGH); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; }

Detailed Instructions

Follow these instructions step by step:

  • If this is your first time using the Arduino Uno R4 WiFi/Minima, refer to the tutorial on setting up the environment for Arduino Uno R4 WiFi/Minima in the Arduino IDE.
  • Connect the Arduino Uno R4 board to the color sensor according to the provided diagram.
  • Connect the Arduino Uno R4 board to your computer using a USB cable.
  • Launch the Arduino IDE on your computer.
  • Select the appropriate Arduino Uno R4 board (e.g., Arduino Uno R4 WiFi) and COM port.
  • Copy the code above and open it in Arduino IDE.
  • Click the Upload button in Arduino IDE to upload the code to Arduino UNO R4.
  • Open the Serial Monitor. You will see continuous readings along with Min and Max values.
  • Move the sensor over different objects: a white object (like paper), a black object, and optionally some colored objects.
  • Watch the Min and Max rows update automatically as the sensor tracks the extremes.
  • When the Min and Max values stop changing (usually after 10-20 seconds), those are your calibration values - write them down.
COM6
Send
=== TCS3200 Calibration === Point the sensor at different objects (white, black, colors). Min and Max values are tracked automatically. When values look stable, note them down for the next code. ------------------------------------------ Red PW = 42 - Green PW = 55 - Blue PW = 60 Min -> R:42 G:55 B:60 Max -> R:42 G:55 B:60 ------------------------------------------ Red PW = 210 - Green PW = 185 - Blue PW = 172 Min -> R:42 G:55 B:60 Max -> R:210 G:185 B:172 ------------------------------------------ Red PW = 44 - Green PW = 57 - Blue PW = 61 Min -> R:42 G:55 B:60 Max -> R:210 G:185 B:172 ------------------------------------------
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

For example, from the output above, your calibration values would be:

  • RedMin = 42, redMax = 210
  • GreenMin = 55, greenMax = 185
  • BlueMin = 60, blueMax = 172

Arduino UNO R4 Code - Read RGB values

/* * This Arduino UNO R4 code was developed by newbiely.com * * This Arduino UNO R4 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-tcs3200d-tcs230-color-sensor */ // Define color sensor pins #define S0 4 #define S1 3 #define S2 6 #define S3 5 #define sensorOut 7 // Calibration Values // *Get these from the Calibration Sketch int redMin = 0; // Red minimum pulse width int redMax = 0; // Red maximum pulse width int greenMin = 0; // Green minimum pulse width int greenMax = 0; // Green maximum pulse width int blueMin = 0; // Blue minimum pulse width int blueMax = 0; // Blue maximum pulse width // Variables for Color Pulse Width Measurements int redPW = 0; int greenPW = 0; int bluePW = 0; // Variables for final RGB values int redValue = 0; int greenValue = 0; int blueValue = 0; void setup() { // Set S0 - S3 as outputs pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); // Set Pulse Width scaling to 20% digitalWrite(S0, HIGH); digitalWrite(S1, LOW); // Set Sensor output as input pinMode(sensorOut, INPUT); // Setup Serial Monitor Serial.begin(9600); } void loop() { // Read Red Pulse Width redPW = getRedPW(); // Map to value from 0-255 redValue = map(redPW, redMin, redMax, 255, 0); // Delay to stabilize sensor delay(200); // Read Green Pulse Width greenPW = getGreenPW(); // Map to value from 0-255 greenValue = map(greenPW, greenMin, greenMax, 255, 0); // Delay to stabilize sensor delay(200); // Read Blue Pulse Width bluePW = getBluePW(); // Map to value from 0-255 blueValue = map(bluePW, blueMin, blueMax, 255, 0); // Delay to stabilize sensor delay(200); // Print output to Serial Monitor Serial.print("Red = "); Serial.print(redValue); Serial.print(" - Green = "); Serial.print(greenValue); Serial.print(" - Blue = "); Serial.println(blueValue); } // Function to read Red Pulse Widths int getRedPW() { // Set sensor to read Red only digitalWrite(S2, LOW); digitalWrite(S3, LOW); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to read Green Pulse Widths int getGreenPW() { // Set sensor to read Green only digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to read Blue Pulse Widths int getBluePW() { // Set sensor to read Blue only digitalWrite(S2, LOW); digitalWrite(S3, HIGH); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; }

Detailed Instructions

  • In the code above, find these lines near the top:
int redMin = 0; // Red minimum pulse width int redMax = 0; // Red maximum pulse width int greenMin = 0; // Green minimum pulse width int greenMax = 0; // Green maximum pulse width int blueMin = 0; // Blue minimum pulse width int blueMax = 0; // Blue maximum pulse width
  • Replace ALL six 0 values with your calibration numbers from the previous step. For example, if your calibration gave you redMin = 42, redMax = 210, greenMin = 55, greenMax = 185, blueMin = 60, blueMax = 172, change the lines to:
int redMin = 42; int redMax = 210; int greenMin = 55; int greenMax = 185; int blueMin = 60; int blueMax = 172;
  • Upload the code to Arduino UNO R4.
  • Place a colored object in front of the sensor.
  • Check the result on the Serial Monitor.
COM6
Send
Red = 210 - Green = 35 - Blue = 20 Red = 25 - Green = 200 - Blue = 40 Red = 30 - Green = 45 - Blue = 215
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

The RGB values are now mapped to the standard 0-255 range. Lower pulse widths (more light) produce higher RGB values, and higher pulse widths (less light) produce lower RGB values.

Applications

Now that you can read RGB values, you can build projects like:

  • Color sorter: Sort objects by color (red, green, blue)
  • Color matching game: Check if two objects are the same color
  • Line follower robot: Follow colored lines on the floor
  • Quality control: Detect defective products by color
  • Color-activated alarm: Trigger a buzzer or LED when a specific color is detected

Video Tutorial

Learn More

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!