Arduino Nano - TCS3200D/TCS230 Color Sensor

This comprehensive guide shows you how to connect the TCS3200D/TCS230 color sensor to Arduino Nano for precise color measurement and RGB value extraction. Master calibration procedures and develop color recognition capabilities in your projects.

Learning objectives:

Arduino Nano with TCS3200D TCS230 color recognition sensor module tutorial

Hardware Preparation

1×Official Arduino Nano
1×Alternatively, DIYables ATMEGA328P Nano Development Board
1×USB A to Mini-B USB cable
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

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 sensor utilizes a photodiode matrix arranged in an 8×8 grid for color detection through optical filtering. Within this 64-element array, 16 photodiodes feature red spectral filters, another 16 use green filters, 16 employ blue filters, and the remaining 16 operate without filters (clear response). Color measurement happens by activating specific filter sets and analyzing the resulting frequency-modulated square-wave output.

Built-in white LED arrays on typical modules deliver constant illumination to targets, maintaining reading stability regardless of external lighting variations and enhancing performance in dim environments.

Pinout

Available connections on the TCS3200D/TCS230 sensor board:

  • VCC pin: Supply voltage input (+5V).
  • GND pin: Ground reference (0V).
  • S0, S1 pins: Output frequency scaling selectors.
  • S2, S3 pins: Color channel filter selectors.
  • OUT pin: Frequency-modulated square wave output.
  • OE pin: Output enable input (enables when LOW). Standard modules typically hard-wire this to GND internally. If not connected, manually wire to GND.
TCS3200 TCS230 color sensor module pinout diagram showing VCC GND S0 S1 S2 S3 OUT pins

How It Works

Two critical settings control sensor behavior: which color channel to activate and what output signal strength to generate. Two pairs of control inputs manage these functions:

Frequency scaling control (S0 and S1 pins):

  • S0=LOW, S1=LOW: Power down state
  • S0=LOW, S1=HIGH: 2% scaling factor
  • S0=HIGH, S1=LOW: 20% scaling factor
  • S0=HIGH, S1=HIGH: 100% scaling factor (full speed)

Color channel selection (S2 and S3 pins):

  • S2=LOW, S3=LOW: Red photodiodes active
  • S2=LOW, S3=HIGH: Blue photodiodes active
  • S2=HIGH, S3=LOW: Clear photodiodes active (no filtering)
  • S2=HIGH, S3=HIGH: Green photodiodes active

The OUT pin delivers square-wave frequencies spanning approximately 2 Hz to 500 kHz range. Frequency increases with light intensity—brighter illumination produces higher frequency output. The pulseIn() function measures pulse duration, which correlates inversely—shorter durations indicate stronger light. Calibrated measurements translate into conventional 0-255 RGB format.

Achieving Optimal Precision

  • Keep sensor positioned 1-3 cm from measurement target with stable angular alignment.
  • Utilize integrated white LED illumination for repeatable lighting.
  • Shield sensor from variable ambient light to enhance measurement consistency.

Wiring Diagram

TCS3200 color sensor to Arduino Nano wiring configuration:

TCS3200 Color SensorArduino Nano
VCC5V
GNDGND
S0D4
S1D3
S2D6
S3D5
OUTD7
The wiring diagram between Arduino Nano and 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 Nano and other components.

Arduino Nano Code - Pulse Width Calibration

Calibration eliminates environmental interference from raw measurements. Variables including LED output strength, target spacing, material reflectivity, and room lighting all affect readings. Think of these as systematic errors requiring measurement. The calibration routine identifies minimum and maximum pulse widths across all color channels, establishing reference boundaries for converting raw data into accurate 0–255 RGB values matched to your deployment environment.

/* * This Arduino Nano code was developed by newbiely.com * * This Arduino Nano code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano/arduino-nano-tcs3200d-tcs230-color-sensor */ // Define color sensor pins #define PIN_S0 4 #define PIN_S1 3 #define PIN_S2 6 #define PIN_S3 5 #define PIN_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(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

  • Load the calibration sketch into Arduino IDE
  • Connect Arduino Nano via USB and upload using the Upload button
  • Access Serial Monitor to observe real-time Min/Max tracking
  • Expose sensor to diverse surfaces: white materials (printer paper), black objects, plus multi-colored items
  • Watch Min/Max boundaries update automatically as extremes are detected
  • Once values stabilize (generally 10-20 seconds), document all six calibration parameters
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  

Sample calibration parameters extracted from above output:

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

Arduino Nano Code - RGB Value Measurement

/* * This Arduino Nano code was developed by newbiely.com * * This Arduino Nano code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano/arduino-nano-tcs3200d-tcs230-color-sensor */ // Define color sensor pins #define PIN_S0 4 #define PIN_S1 3 #define PIN_S2 6 #define PIN_S3 5 #define PIN_sensorOut 7 // 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

  • Identify calibration variables at code start:
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
  • Substitute all six zero placeholders with measured calibration data. Example using values 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;
  • Transfer updated code to Arduino Nano
  • Arrange colored sample before sensor
  • Check RGB output via 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  

Displayed RGB values conform to standard 0-255 scaling. Reduced pulse widths (indicating brighter reflections) generate higher RGB outputs; extended pulse widths (dimmer reflections) yield lower values.

Project Applications

With operational RGB measurement capability, you can develop:

  • Chromatic sorting system: Categorize objects by color (red/green/blue differentiation)
  • Color verification device: Confirm color consistency between samples
  • Colored path follower: Robots that navigate along chromatic markers
  • Visual quality inspection: Detect production defects via color analysis
  • Color-triggered automation: Execute actions when specific hues are 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!