You are on page 1of 14

I am going to show you how you can use an RGB LED and a Cds photocell

as a colour sensor for a micro-controller. I will illustrate the method to


retrieve a colour using Arduino, and I will show you a how you can verify the
colour being scanned with a small Processing sketch.
We will be making this colour sensor on a breadboard, but it is
easily transferred onto a prototyping board, and for those who fab their own
boards, this would be an awesome kit that is super cheap to throw together. I
am sure it would only take about two minutes to write a gerber file for this
circuit and make a nice little finished sensor.
Step 1: Gather Some Parts
For this sensor you will need
a breadboard (not reuired, but it is how I will walk you through it.!
an "#$ %&' (alternatively you could use ( %&'s!
A ))* ohm resistor
A +d, photocell (these can be salvaged out of all kinds of things like
nightlights or garden lamps!
An Arduino, or a clone. I am using a "$$ in this e-ample
Tools you will need
A computer
a cable to upload to your Arduino
Step 2: A Little Theory
,ome of you might be wondering how a +d, photocell can detect colours.
Well it is surprisingly simple and provides pretty accurate results.
We see colour as a freuency of light reflected from an ob.ect. ,o different
colours reflect different wavelengths which our eyes then interpret as colours.
(/aybe brain...I am no scientist!
A common CdS photocell has a very similar response to colour as the
human eye.
$ecause colours absorb certain wavelengths and reflect certain wavelengths,
we can use different wavelengths(colours! of light and take readings(from a
sensor that has nearly human responses! and thereby make a pretty good
guess at what colour the sensor is being e-posed to.
Step 3: Build the Circuit
I have included both images of the breadboard arrangment, and a small
diagram to show you how to wire up the sensor to the Arduino.
0he circuit is really simple. 1irst we will look at the "#$ %&' half of the
sensor. It is simply a common cathode "#$ %&' connected to pins ),(, and 2
of the Arduino with a ))* ohm resistor going out to ground. 0his will allow us
to turn each of the %&'s within the package on and off individually when we
need to.
3n the other side of the circuit we have a +ds photocell being fed 4 volts from
the arduino. combined with the resistor going out to ground this effectively
creates a voltage divider which allows us to read a changing analog value on
analog pin *.
0his sensor works great on a breadboard, but it works even better if you put it
into a more permanent enclosure to minimili5e ambient light interference.
0he photo of the light tight (ish! enclosure was used in another one of my
pro.ects and is included here only to illustrate what I meant. (1eel free to
check it out though,here.!
Step 4: Code the Arduino
3pen up the Arduino environment, and create a new sketch by clicking 1ile -
6ew. 1or those that don7t want to follow along, I have included the code as a
te-t file. +opy8Paste it into a new sketch in Arduino, and you are good to go.
Declarations
0he beginning of a sketch is where we make our declarations, so type the
following code into the environment window.
// Deine colour sensor !"D pins
int ledArray#$ % &'(3(4)*
// +oolean to ,now i the +alance has +een set
+oolean +alanceSet % alse*
//place holders or colour detected
int red % -*
int .reen % -*
int +lue % -*
//loats to hold colour arrays
loat colourArray#$ % &-(-(-)*
loat whiteArray#$ % &-(-(-)*
loat +lac,Array#$ % &-(-(-)*
//place holder or avera.e
int av./ead*

9889 is reserved for denoted comments, therefore you do not need the te-t on
lines that begin with 9889 for the sketch to work. 0he rest of it are some names
that we are giving to some placeholders, and the declarations for what kind of
data they will contain. As you can see, we start by setting up an array to hold
the pin numbers. 0hese correspond to the pins that the different colour %&'s
are conected to on the Arduino.6e-t we declare a $oolean value to check
whether or not balancing has been performed. A $oolean value is something
that returns true or false. We go on to create some place holders for the colour
values, and some arrays to use for holding the scan data and balancing the
detected colour. Although we are not finished yet, go ahead and save your
sketch. #ive it a name that is meaningful to you, something like
coloursensor.pde maybe.
Setup
0he ne-t step in creating an Arduino sketch is to write the setup function.
,etup is run when the Arduino first boots up, so this is where we tell the
Arduino what how we want to use the pins and setup other features that we
may need such as serial communication.
0ype the following below the code that you .ust entered.
void setup01&

//setup the outputs or the colour sensor
pin2ode0'(34T54T1*
pin2ode03(34T54T1*
pin2ode04(34T54T1*

//+e.in serial communication
Serial.+e.in067--1*

)

6ot much to this section. :ere we are .ust telling the Arduino that we intend on
using pins ),(,and 2 as outputs. 0his is neccesary if we want to light our
%&'s...and we do, if only very briefly.
0he ne-t part is to tell the Arduino that we intend to make use of the serial
port, and that it should be opened and ready to communicate at the baud rate
specified (in brackets!.
!oop
0he loop function is typically where the magic happens in an Arduino. It is the
code that is run over and over again once the Arduino is booted and setup has
been passed through. Put the ne-t bit of code under your setup function.
void loop01&
chec,Balance01*
chec,Colour01*
printColour01*
)

3kay at first glance it looks like there really is not much there. $ut these are
each calls to private functions. 1or some pro.ects I find this type of approach
works well. It makes it easier to read (I think! as each block of code is
seperated with a meaningful name, and we can see what the sketch is going
to do at a glance.
1irst it will check the balance, then it will check the colour, and then it will print
the colour to the serial port so we can see the values that it read.
%et7s e-plore the first private function, check$alance, and add it to our code.
0ype the following below your loop function.

void chec,Balance01&
//chec, i the +alance has +een set( i not( set it
i0+alanceSet %% alse1&
setBalance01*
)
)

As you can see, if the balance,et value (a boolean value! is set to false, then
it makes a call to a secondary function called set$alance, where we set the
white and black balancing readings. 0his will only happen when you boot up
the arduino the one time.

void setBalance01&
//set white +alance
delay08---1* //delay or ive seconds( this .ives us
time to .et a white sample in ront o our sensor
//scan the white sample.
//.o throu.h each li.ht( .et a readin.( set the +ase readin. or each
colour red( .reen( and +lue to the white array
or0int i % -*i9%'*i::1&
di.ital;rite0ledArray#i$(<=><1*
delay0?--1*
.et/eadin.081* //num+er is the num+er o scans to ta,e or
avera.e( this whole unction is redundant( one readin. wor,s @ust as
well.
whiteArray#i$ % av./ead*
di.ital;rite0ledArray#i$(!3;1*
delay0?--1*
)
//done scannin. white( now it will pulse +lue to tell you that it is time or
the +lac, 0or .rey1 sample.
//set +lac, +alance
delay08---1* //wait or ive seconds so we can position our
+lac, sample
//.o ahead and scan( sets the colour values or red( .reen( and +lue
when eAposed to +lac,
or0int i % -*i9%'*i::1&
di.ital;rite0ledArray#i$(<=><1*
delay0?--1*
.et/eadin.081*
+lac,Array#i$ % av./ead*
//+lac,Array#i$ % analo./ead0'1*
di.ital;rite0ledArray#i$(!3;1*
delay0?--1*
)
//set +oolean value so we ,now that +alance is set
+alanceSet % true*
delay08---1* //delay another 8 seconds to let us catch up
)

If you noticed, we made yet another call to a function get"eading. We will add
that right after we put in the check+olour function.
3nce our balancing numbers have been set, we go on to finally read the
colour. 0he function is basically the same as set$alance,, with the addition of
the math that balances the reading. %et7s add it now.

void chec,Colour01&
or0int i % -*i9%'*i::1&
di.ital;rite0ledArray#i$(<=><1* //turn or the !"D( red( .reen or +lue
dependin. which iteration
delay0?--1* //delay to allow CdS to sta+aliBe( they are slow
.et/eadin.081* //ta,e a readin. however many times
colourArray#i$ % av./ead* //set the current colour in the array to
the avera.e readin.
loat .reyDi % whiteArray#i$ C +lac,Array#i$* //the hi.hest
possi+le return minus the lowest returns the area or values in +etween
colourArray#i$ % 0colourArray#i$ C +lac,Array#i$1/0.reyDi1D'88* //the
readin. returned minus the lowest value divided +y the possi+le ran.e
multiplied +y '88 will .ive us a value rou.hly +etween -C'88
representin. the value or the current relectivity0or the colour it is
eAposed to1 o what is +ein. scanned
di.ital;rite0ledArray#i$(!3;1* //turn o the current !"D
delay0?--1*
)


)

We will also need to add our function get"eading, otherwise our sketch won7t
have real values. 0his function .ust allows us to take a few readings and
average them out. 0his allows for a slightly smoother reading.

void .et/eadin.0int times1&
int readin.*
int tally%-*
//ta,e the readin. however many times was reEuested and add them up
or0int i % -*i 9 times*i::1&
readin. % analo./ead0-1*
tally % readin. : tally*
delay0?-1*
)
//calculate the avera.e and set it
av./ead % 0tally1/times*
)

6ow we have a colour read into our colour holding array, all we need to do
now is output it to the screen. "emember that we setup serial communication
back in the setup function, all we have to do now is use the serial port to send
out our data. 0he Arduino environment includes a serial monitor, which will
allow you to see the data as it is passed from the Arduino. ,o let7s add the last
function to the sketch.

//prints the colour in the colour array( in the neAt step( we will send this
to processin. to see how .ood the sensor wor,s.
void printColour01&
Serial.print0F/ % F1*
Serial.println0int0colourArray#-$11*
Serial.print0F> % F1*
Serial.println0int0colourArray#?$11*
Serial.print0FB % F1*
Serial.println0int0colourArray#'$11*
//delay0'---1*
)

0his will print out some data that looks something like this

" ; )(<
# ; =<
$ ; *

which would be the euivilent to a red-orange colour.

I have left this sketch super simple. >ou can dress it up as you see fit. 0he
idea is to show how to make and use the sensor, creative implementation is
up to you.
6ow you can save your file again and upload it to the Arduino. >our Arduino
should start running the sketch, the little lights should be flickering.
0he sketch is very basic. I have offered it as a building block and to show you
how to use the sensor.

You might also like