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