Arduino Nano ESP32 - TCS3200D/TCS230 Color Sensor

In this tutorial, we'll explore how to connect the TCS3200D/TCS230 color sensor to Arduino Nano ESP32 for accurate color detection and RGB value measurement.

What you'll accomplish:

Arduino Nano ESP32 with TCS3200D TCS230 color sensor module tutorial

Hardware Preparation

1×Arduino Nano ESP32
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×TCS3200D/TCS230 Color Recognition Sensor Module
1×Breadboard
1×Jumper Wires
1×Recommended: Screw Terminal Expansion Board for Arduino Nano
1×Recommended: Breakout Expansion Board for Arduino Nano
1×Recommended: Power Splitter for Arduino Nano ESP32

Or you can buy the following kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of TCS3200D/TCS230 Color Sensor

The TCS3200D/TCS230 employs a structured array of 64 photodiodes in an 8×8 configuration for optical color sensing. The array comprises 16 photodiodes with red optical filters, 16 with green filters, 16 with blue filters, and 16 without filters (clear). Color detection works by activating designated filter groups and analyzing the frequency of the output waveform.

Standard TCS3200D sensor modules incorporate white LED arrays that provide consistent illumination to the measurement target, delivering stable readings across different lighting environments and enabling operation in poorly lit conditions.

Pinout

Connection terminals on the TCS3200D/TCS230 sensor module:

  • VCC pin: Positive power supply (+5V).
  • GND pin: Ground reference (0V).
  • S0, S1 pins: Frequency scaling configuration pins.
  • S2, S3 pins: Color filter activation pins.
  • OUT pin: Frequency-encoded square wave output.
  • OE pin: Output activation pin (active when LOW). Standard modules hardwire this to GND internally. If floating, connect manually to GND.
TCS3200 TCS230 color sensor module pinout diagram showing VCC GND S0 S1 S2 S3 OUT pins

How It Works

Sensor functionality relies on two configurable parameters: which color filter to engage and what output frequency range to use. Two control pin pairs manage these settings:

Frequency scaling configuration (S0 and S1 pins):

  • S0=LOW, S1=LOW: Sensor powered down
  • S0=LOW, S1=HIGH: 2% output scaling
  • S0=HIGH, S1=LOW: 20% output scaling
  • S0=HIGH, S1=HIGH: 100% output scaling (full frequency)

Color filter activation (S2 and S3 pins):

  • S2=LOW, S3=LOW: Red photodiode array active
  • S2=LOW, S3=HIGH: Blue photodiode array active
  • S2=HIGH, S3=LOW: Clear photodiode array active (unfiltered)
  • S2=HIGH, S3=HIGH: Green photodiode array active

The OUT pin generates square wave frequencies within the approximate range of 2 Hz to 500 kHz. Increased light intensity results in elevated frequency output. Arduino's pulseIn() measures pulse duration, which exhibits inverse behavior—brighter illumination yields shorter pulse durations. Through calibration, these pulse measurements transform into familiar 0-255 RGB notation.

Maximizing Measurement Precision

  • Establish fixed sensor-to-object distance (optimal: 1-3 cm) with steady angular positioning.
  • Activate integrated white LED illumination for reproducible results.
  • Shield from fluctuating external light sources for improved accuracy.

Wiring Diagram

Wire the TCS3200 color sensor to Arduino Nano ESP32 according to this configuration:

TCS3200 Color SensorArduino Nano ESP32
VCC5V
GNDGND
S0D4
S1D3
S2D6
S3D5
OUTD7
The wiring diagram between Arduino Nano ESP32 and and TCS3200 color sensor

This image is created using Fritzing. Click to enlarge image

Arduino Nano ESP32 Code - Sensor Calibration

Calibration neutralizes environmental factors affecting sensor performance. Variables such as LED intensity, object proximity, surface characteristics, and surrounding illumination all impact raw measurements. This calibration workflow determines minimum and maximum pulse durations for each color channel, creating reference boundaries that translate raw sensor output into standardized 0–255 RGB values optimized for your deployment conditions.

/* * This Arduino Nano ESP32 code was developed by newbiely.com * * This Arduino Nano ESP32 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tcs3200d-tcs230-color-sensor */ // Define color sensor pins #define PIN_S0 D4 // The Arduino Nano ESP32 pin connected to the S0 of the color module #define PIN_S1 D3 // The Arduino Nano ESP32 pin connected to the S1 of the color module #define PIN_S2 D6 // The Arduino Nano ESP32 pin connected to the S2 of the color module #define PIN_S3 D5 // The Arduino Nano ESP32 pin connected to the S3 of the color module #define PIN_sensorOut D7 // The Arduino Nano ESP32 pin connected to the OUT of the color module // 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(PIN_S0, OUTPUT); pinMode(PIN_S1, OUTPUT); pinMode(PIN_S2, OUTPUT); pinMode(PIN_S3, OUTPUT); // Set Pulse Width scaling to 20% digitalWrite(PIN_S0, HIGH); digitalWrite(PIN_S1, LOW); // Set Sensor output as input pinMode(PIN_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 the pulse width values with min/max Serial.print("Red PW = "); Serial.print(redPW); Serial.print(" - Green PW = "); Serial.print(greenPW); Serial.print(" - Blue PW = "); Serial.println(bluePW); 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("------------------------------------------"); delay(1000); } // Function to read Red Pulse Widths int getRedPW() { // Set sensor to read Red only digitalWrite(PIN_S2, LOW); digitalWrite(PIN_S3, LOW); // Read the Pulse Width int PW = pulseIn(PIN_sensorOut, LOW); // Return the value return PW; } // Function to read Green Pulse Widths int getGreenPW() { // Set sensor to read Green only digitalWrite(PIN_S2, HIGH); digitalWrite(PIN_S3, HIGH); // Read the Pulse Width int PW = pulseIn(PIN_sensorOut, LOW); // Return the value return PW; } // Function to read Blue Pulse Widths int getBluePW() { // Set sensor to read Blue only digitalWrite(PIN_S2, LOW); digitalWrite(PIN_S3, HIGH); // Read the Pulse Width int PW = pulseIn(PIN_sensorOut, LOW); // Return the value return PW; }

Detailed Instructions

To get started with Arduino Nano ESP32, follow these steps:

  • If you are new to Arduino Nano ESP32, refer to the tutorial on how to set up the environment for Arduino Nano ESP32 in the Arduino IDE.
  • Wire the components according to the wiring diagram.
  • Connect the Arduino Nano ESP32 board to your computer using a USB cable.
  • Launch Arduino IDE on your computer.
  • Select the Arduino Nano ESP32 board and its corresponding COM port.
  • Copy the calibration code and paste it into Arduino IDE.
  • Click the Upload button to compile and upload the code.
  • Open the Serial Monitor to observe calibration progress.
  • Direct the sensor toward different colored surfaces: white materials (paper), black surfaces, and various colored objects.
  • Monitor the Min/Max parameters as they update in real-time.
  • When values reach stability (usually 10-20 seconds), record all six calibration numbers.
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  

Calibration parameters extracted from example output:

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

Arduino Nano ESP32 Code - RGB Color Reading

/* * This Arduino Nano ESP32 code was developed by newbiely.com * * This Arduino Nano ESP32 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tcs3200d-tcs230-color-sensor */ // Define color sensor pins #define PIN_S0 D4 // The Arduino Nano ESP32 pin connected to the S0 of the color module #define PIN_S1 D3 // The Arduino Nano ESP32 pin connected to the S1 of the color module #define PIN_S2 D6 // The Arduino Nano ESP32 pin connected to the S2 of the color module #define PIN_S3 D5 // The Arduino Nano ESP32 pin connected to the S3 of the color module #define PIN_sensorOut D7 // The Arduino Nano ESP32 pin connected to the OUT of the color module // Calibration Values // Replace these values with your actual calibration data from the previous step 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 Color values int redValue; int greenValue; int blueValue; void setup() { // Set S0 - S3 as outputs pinMode(PIN_S0, OUTPUT); pinMode(PIN_S1, OUTPUT); pinMode(PIN_S2, OUTPUT); pinMode(PIN_S3, OUTPUT); // Set Pulse Width scaling to 20% digitalWrite(PIN_S0, HIGH); digitalWrite(PIN_S1, LOW); // Set Sensor output as input pinMode(PIN_sensorOut, INPUT); // Setup Serial Monitor Serial.begin(9600); } void loop() { // Read Red value redPW = getRedPW(); // Map to value from 0-255 redValue = map(redPW, redMin, redMax, 255, 0); // Delay to stabilize sensor delay(200); // Read Green value greenPW = getGreenPW(); // Map to value from 0-255 greenValue = map(greenPW, greenMin, greenMax, 255, 0); // Delay to stabilize sensor delay(200); // Read Blue value 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(PIN_S2, LOW); digitalWrite(PIN_S3, LOW); // Read the Pulse Width int PW = pulseIn(PIN_sensorOut, LOW); // Return the value return PW; } // Function to read Green Pulse Widths int getGreenPW() { // Set sensor to read Green only digitalWrite(PIN_S2, HIGH); digitalWrite(PIN_S3, HIGH); // Read the Pulse Width int PW = pulseIn(PIN_sensorOut, LOW); // Return the value return PW; } // Function to read Blue Pulse Widths int getBluePW() { // Set sensor to read Blue only digitalWrite(PIN_S2, LOW); digitalWrite(PIN_S3, HIGH); // Read the Pulse Width int PW = pulseIn(PIN_sensorOut, LOW); // Return the value return PW; }

Detailed Instructions

  • Find the calibration variable declarations near the beginning of the code:
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
  • Insert your recorded calibration values in place of zeros. Example substitution with redMin = 42, redMax = 210, greenMin = 55, greenMax = 185, blueMin = 60, blueMax = 172:
int redMin = 42; int redMax = 210; int greenMin = 55; int greenMax = 185; int blueMin = 60; int blueMax = 172;
  • Upload the updated code to Arduino Nano ESP32.
  • Place a colored target in front of the sensor.
  • Open Serial Monitor to view RGB measurements.
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  

Output RGB values adhere to standard 0-255 scaling. Shorter pulse widths (intense reflections) map to higher RGB numbers; longer pulse widths (weak reflections) map to lower values.

Project Applications

With functional RGB color sensing, you can build:

  • Automated color sorter: Classify items based on chromatic properties (red/green/blue categorization)
  • Color comparison tool: Verify color consistency across multiple samples
  • Color-guided navigation: Robots that follow colored pathways
  • Manufacturing inspection: Identify product defects through color deviation
  • Color-activated control: Trigger specific behaviors when particular colors appear

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!