How to Use RGB LEDs to Identify Colours - DIY Colour Sensor




Introduction: How to Use RGB LEDs to Identify Colours - DIY Colour Sensor

This is a DIY colour detector made only using an RGB LED and a photoresistor sensor.

I got a comment and request from one of my Instructables that they would like to see an LED used as a colour detector. Then, I got the idea that if I were to use an RGB LED, I can detect all the colour spectrum possible by sending PWM signals to the LED.

Step 1: BoM

  • Arduino
  • Photoresistor
  • 10kΩ resistor
  • 3x 100Ω Resistor
  • Jumper
  • Breadboard wires

Step 2: Wire the RGB LED

This will be the emitter part of our circuit emitting different colours which will bounce off of objects, by the law of optics which will be detected by our photosensor.

* Connect pin 2, the longest pin to the GND pin on the Arduino.

* Connect pin 1, the red coloured LED of the RGB LED to pin 5 on the Arduino.

* Connect pin 3, the greed coloured LED of the RGB LED to pin 6 on the Arduino.

* Connect pin 4, the bleu coloured LED of the RGB LED to pin 9 on the Arduino.

You will notice that all of these are plugged into PWM pins marked with a tilda symbol "~" so that we can independently control the brightness of each of the LEDs.

Step 3: Wire the Photosensor

The reflected light from the emitter (RGB) LED bouncing back off of any objects will be read by the photosensor which will used calibrated values to find the individual R-G-B colour values of a particular colour.

Make sure you move the photosensor very close to the emitter.

* Connect one of the pins, call this pin 1, of the photosensor to the GND pin on the Arduino

* Connect pin 2 of the photosensor to the 3.3V pin on the Arduino.

* Connect pin 2 of the photosensor to the A0 pin on the Arduino.

You will notice that the last two wirings are all parallel. This is because we are making a voltage divider to get the changing voltage reading as the reflected light changes in intensity.

Step 4: Code

// Define colour sensor LED pins
int ledArray[] = {5,6,9};
// boolean to know if the balance has been set
boolean balanceSet = false;
//place holders for colour detected
int red = 0;
int green = 0;
int blue = 0;
//floats to hold colour arrays
float colourArray[] = {0,0,0};
float whiteArray[] = {0,0,0};
float blackArray[] = {0,0,0};
//place holder for average
int avgRead;
void setup(){
  //setup the outputs for the colour sensor
  //begin serial communication
void loop(){
void checkBalance(){
  //check if the balance has been set, if not, set it
  if(balanceSet == false){
 void setBalance(){
  //set white balance
   delay(5000);                              //delay for five seconds, this gives us time to get a white sample in front of our sensor
  //scan the white sample.
  //go through each light, get a reading, set the base reading for each colour red, green, and blue to the white array
  for(int i = 0;i<=2;i++){
     getReading(5);          //number is the number of scans to take for average, this whole function is redundant, one reading works just as well.
     whiteArray[i] = avgRead;
  //done scanning white, now it will pulse blue to tell you that it is time for the black (or grey) sample.
   //set black balance
    delay(5000);              //wait for five seconds so we can position our black sample 
  //go ahead and scan, sets the colour values for red, green, and blue when exposed to black
  for(int i = 0;i<=2;i++){
     blackArray[i] = avgRead;
     //blackArray[i] = analogRead(2);
   //set boolean value so we know that balance is set
  balanceSet = true;
  delay(5000);     //delay another 5 seconds to let us catch up
void checkColour(){
    for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);  //turn or the LED, red, green or blue depending which iteration
     delay(100);                      //delay to allow CdS to stabalize, they are slow
     getReading(5);                  //take a reading however many times
     colourArray[i] = avgRead;        //set the current colour in the array to the average reading
     float greyDiff = whiteArray[i] - blackArray[i];                    //the highest possible return minus the lowest returns the area for values in between
     colourArray[i] = (colourArray[i] - blackArray[i])/(greyDiff)*255; //the reading returned minus the lowest value divided by the possible range multiplied by 255 will give us a value roughly between 0-255 representing the value for the current reflectivity(for the colour it is exposed to) of what is being scanned
     digitalWrite(ledArray[i],LOW);   //turn off the current LED
void getReading(int times){
  int reading;
  int tally=0;
  //take the reading however many times was requested and add them up
for(int i = 0;i < times;i++){
   reading = analogRead(0);
   tally = reading + tally;
//calculate the average and set it
avgRead = (tally)/times;
 //prints the colour in the colour array, in the next step, we will send this to processing to see how good the sensor works.
void printColour(){
Serial.print("R = ");
Serial.print("G = ");
Serial.print("B = ");

Step 5: Calibrate

First prepare a black and white piece of paper before the uploading the code.

After uploading the code, you will notice that during the first 5 seconds of the program running the RGB LED will emit a variety of colours. Place a black paper over the LED and photosensor for this first 5 seconds. Then switch the paper to the white piece of paper for the next 5 seconds.

The code is written so that these first 10 seconds are the calibration period.

Step 6: Test and Enjoy!

Take different coloured paper and test it out. It will print the individual R, G, B values onto the screen.

Makerspace Contest 2017

Participated in the
Makerspace Contest 2017

Be the First to Share


    • Back to School: Student Design Challenge

      Back to School: Student Design Challenge
    • Plywood Contest

      Plywood Contest
    • Teach With Tinkercad Contest

      Teach With Tinkercad Contest



    Question 2 years ago on Step 6

    Hi Sir, if i use a common anode RGB LED, I simply changed the wire connection and signal High to Low in Adruino code, but it seems that it didn't work, the red light always turns on. So could you please help me to fix that? Also, i found that it is better to test the value of R.G and B when the LED is turned off, this will reduce the error. You can contact me via email Thank you so much.


    4 years ago

    Hi, Myself Dr Sandeep Kale from Pune, Maharashtra India.I want to use this for my PhD study. can you please help me. You can mail me or call me contact +918329359557


    Reply 3 years ago

    go ahead


    4 years ago

    Another bug, you should change this "int ledArray[] = {5,6,9};" to "int ledArray[] = {2,3,4};" or change "pinMode(2,OUTPUT);
    pinMode(4,OUTPUT);" to "pinMode(5,OUTPUT);


    5 years ago

    I noticed a few minor glitches.. the resistors to the RGB LED Inoticed, you listed as 100-Ohm, but noticed in one picture, they're 1K (1000), bands Brown-Black-Red, but in other photos noticed they're Brown-black-brown. Also, noticed you mentioned Pin 2 from the CDS cell running going to BOTH 3.3V & A0.. you might want to edit that to read a 10K (Brown-Black-Orange) going from that pin, to +3.3V. otherwise, A0 will constantly read the 3.3V voltage.

    Also, one minor note, I've run across common cathode, but more likely, I've hit some which are common anode.. might have to change the code to read the reverse....


    5 years ago

    you may want to describe the placement of the 4 resistors too....3x100 ohm for the rgb and the last one for the voltage divider


    5 years ago

    You could build a simple photo spectrometer from this