Magical Colour Copying Chameleon Lamp




Introduction: Magical Colour Copying Chameleon Lamp

About: Dad, maker, dreamer, hacker, painter.

In this Instructable, I will show you how to make an Arduino powered lamp that detects the colour under it and then attempts to emulate that colour. All using easy to find parts (most can be found in the Dollar store with the exception of the Arduino of course).

It turns out that a colour detection module can be built for next to nothing, and the results are astoundingly good for the investment.
The biggest hurtle in this project is getting the balance right on our sensor as we are using LEDs to represent the colour being detected, which becomes our limit. Dark colours are more difficult to represent. The sensor still does a good job at detecting and giving a reliable reading, but again, balancing becomes the real issue. Reflectivity will also play with the readings. That being said, this sensor would work great for all manner of colour detecting projects. Best of all it is super cheap to make. 

I really hope that a few of you out there both copy and improve on my lamp, or find some other great uses for this cheap, easy to make, Arduino friendly Colour sensor.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Get Stuff

To build the colour detection module you will need
  • a CdS photocell (cadmium sulfide), also called an LDR or light dependent resistor. Anyways, it is one of those little light detectors on most garden lamps, night-lights, etc.
  • A 10K resistor
  • A  red LED
  • a green LED
  • a blue LED
  • alternatively you could use an RGB(red green blue) LED
  • A 220 ohm resitor
  • a bit of shrink wrap or a cut section of a pen or anything else that would be a decent shroud for the LDR
  • a shroud for the entire sensor (film case cut, pvc pipe, bits of plastic, again anything to shield the whole ensemble from ambient light a bit)
  • a bit of prototyping board.
  • Hookup wire (I also use male header pins and jumpers, but this is not required)

To make the rest of the lamp, you will also need.
  • An enclosure
  • a diffuser (I managed to get mine all in one with a tomato container from the Dollar store)
  • an Arduino that will fit in your enclosure (I used a mini)
  • another RGB LED or a red, green and blue LED
  • three 220 ohm resistors
  • some decor (use your imagination here, I went for the magic lamp look, you do what pleases you or go with what you have on hand as I did)
Tools that you will need
  • soldering iron
  • glue gun
  • x-acto knife
  • tape
  • white glue
  • paint brush
  • imagination
I decided to leave mine tethered to my computer for power, but you may want to add an on/off switch, and batteries.

Step 2: Random Thoughts

Some of you might be wondering how a CdS photocell can detect colours. Well it is surprisingly simple and provides pretty accurate results.

We see colour as a frequency of light reflected from an object. So different colours reflect different wavelengths which our eyes then interpret as colours. (Maybe brain...I am no scientist)

A common CdS photocell has a very similar response to colour as the human eye.

Because 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 exposed to.

It also turns out that a computer represents colours as a red, green, and blue value in order to display it to our screen. We will be using red, green and blue LEDs for both detection and representation of colour.

Follow all that? No? Don't worry, stay with me and build it, everything will become clearer.

Step 3: Build the Colour Sensor

I like to build things in modules and use headers and jumpers to connect them, but it is not strictly necessary. I may want/need this thing again, so I built the sensor as a separate module.

Start by wiring up the CdS photocell. One side should go to a 5V pin on the Arduino. The other end should go out to ground via a 10k resistor, and also to analog pin 2 on the Arduino. (see wiring diagram, it is marked pin 0, but the code uses pin 2, either will work, just make the appropriate changes)

The sensitivity of the sensor can be changed by altering the resistor. A higher resistance will provide a better sensitivity to darker colours. Anywhere from 1k up to 10k should be decent. I used a 10k because it was what I had on hand, but I believe that a lower value would have been better for this application.

Once the the Cds photocell is wired up, wire in the 3 LEDs with their grounds going through the 220 ohm resistor. The red LED will connect to digital pin 2 on the Arduino. The green to pin 3, and the blue to pin 4.
Try to arrange the LEDs so that they are equidistant from the photocell. Another hint is to try and leave a little bit of wire leads above your proto-board so that you can gently bend them in order to fine tune the beams. You want the LEDs to illuminate the area beneath the photocell as equally as you can manage. (see wiring diagram)
Use some heat shrink tubing or something else to shroud the CdS from direct exposure from the LEDs. While we will be doing balancing to our readings, we don't want to contend with to much extra light. We are trying to detect what light is detected, and having too much exposure to direct light will throw the reading off. I used a section cut from a cheap black pen to make my shroud, and hot glued it in place.

Once the circuit is built and the shroud is added to the CdS photocell, you can go ahead and shroud the entire sensor ensemble. It is not necessary, but will help the sensor to keep a decent balance even when the ambient light changes. An added bonus is that it hides all the flashing from the sensor doing it's thing. I used a bit of black plastic I had kicking around from a garden light to make mine.
I cut it to fit my project, and also a bit to allow the sensor to sit, and then glued my board in place.
To further cut back on ambient light interfering, I went on to wrap the whole ensemble in black electrical tape.

Step 4: Build the Colour Emulator

The colour emulator is a run of the mill RGB lamp or Mood light. Attach a red LED with a 330 ohm resistor to pin 9 on the Arduino, A green LED/resistor combo to pin 10, and a blue one to pin 11.

If you want to have a better look at a RGB lamp with Arduino, I wrote another Instructable called RGB Moodlamp with Custom Library . I use the same library to control the lamp in this project, so it might be worth a visit.

A good trick for diffusing the light from an LED is to remove the lens. This is easy, just sand them down gently until the lens is gone (the curved part). Be careful not to sand too far as you can damage the LED. This will help in blending the colours together, especially when you are using separate LEDs, as I am in this project.

It would have been better to use a proper RGB LED for this side of things, but I used what I had on hand. Still nice.

I wired mine up on a  little circular board with an Arduino mini mounted to the underside. I put my board onto some stand-offs that allowed for my colour sensor to be seated beneath the lamp.


Step 5: Closure

Now it is time to load the whole thing into the enclosure. I used a tomato preserving container that I found at the Dollar store. Everything fit nicely inside and it had a decent shape, and I thought it would made a good diffuser.

First mark off where your sensor and stand-offs will go and make the appropriate mounting holes. Your sensor needs a clear sight to the colour beneath it, so cut a hole where it will sit.

Use hot glue to position your sensor, connect all wires and fasten your stand-offs.

the container was a good size, but I underestimated its ability to diffuse my LEDs enough. I used some watered down white glue and some toilet paper to add another layer of diffusion. Slather some glue on to your surface with a paint brush, lie paper on top and paint it down with more glue. Let it dry overnight.

I also covered up the bottom and added a plastic bezel I found to give it some lift and look. I enveloped the bottom section of the container in a funky bit of fabric, and then added a little strip of brass for pizazz.

Looks kind of magical. Kinda. Could have probably put more effort into the look of the thing. Ah well, we all do what interests us most. Mine is simply realizing an idea, which I was anxious to get to.
Something good to do while you are waiting for glue to dry is to prepare a balance board and and testing board.

For the balancing board, you will need a sample of white, a sample of black, and some ranges in between (greys). This will give you some versatility when setting up your sensor.

For a test board you just need some different colour swatches that you would like to see your lamp emulate, and are large enough to get your sensor over.

Step 6: The Genie in the Lamp

Okay, there is no magic genie, but it is finally, time to get to coding the Arduino, playing with your new sensor, and enjoying all the benefits that come along with having a lamp so discreet that it tries to blend in with its surroundings..
Umm, if you can think of a benefit, let me know, I was having trouble with that one.

I have included the code as a text file, you will have to open it in a text editor and then copy and paste it into the Arduino environment. Or, if you prefer, just open the Arduino software and follow along writing it as we go.

For the emulation lamp I am using my custom Moodlamp library, you can get the library files and  documentation on my other RGB Instructable, RGB Moodlamp with Custom Library. Otherwise you can just copy the colour sensor handling code and output to your RGB lamp in your preferred manner.

So let`s look at the code.
Start with the first image, or follow along with the text file.

We start with an include statement followed by a couple of declarations.
The include statement is for the Moodlamp library. The declaration beneath is just saying that our instance of Moodlamp will be called lamp.
Then we set up a couple of place holders.
The first is an array that we will use to address the pins the that LEDs are connected to. Remember we connected our sensor lights to those same pin numbers.
The others should be clear enough by the notes in the image, if not, never fear, they are just some place holders for values that we will use later on.

The place holder for the average reading is not special, it got it’s own image because it was almost overlooked.

Once all our declarations have been made, we will now have to write the setup function. We start by assigning our sensor output pins. We do not need to declare the analog input of the sensor, and the lamps pins are taken care of by the Moodlamp library.
Then we start serial communication so that we can get some debugging information back from our lamp.

After that we can proceed with our loop function. The loop is the code that the Arduino will run again and again. As you can see we are calling a few functions.
First we call checkBalance to see if the balance has been set and set it if needed. (When it turns on)
Then we check the colour under the sensor. Once we have a colour, we print it to the screen, and then set the colour of the lamp. The last call to getReading does nothing useful at all, left it in there by accident. Oh well, I could claim that I was just keeping the lamp from being too idle.

So let`s look at the different functions.

CheckBalance is pretty straight-forward, it checks to see if a balance exists and if it doesn’t, then it sets it by calling the setBalance function.

Let’s look at the setBalance function, it is the longest one.

First we pulse the light red twice and then white using the Moodlamp library. This is to warn the operator that the white scan is about to take place. Leaving the lamp white(all three colour on) leaves as much interfering light as possible for our baseline scans which keeps them equally balanced.

What the following section does is light the red, then green, then green LEDs while taking a sensor reading at each step. This gives us some data about how much of each colour was reflected back to the sensor. These readings should be high as it is white, which should reflect a lot for each colour.

If the meaning is not inferred, you must place a sample of white ( a card or a paper) under the sensor while this scan takes place. The whole thing lasts about three seconds. The scan less than one.

When finished with scanning white, we will scan black. There are some warning lights again, a delay, and then the scan. Here you will want a black or grey sample under the lamp. We will talk a little more on what your sample should be later.

Once the balancing scans are completed, the lamp will turn off, and we set the Boolean value for whether or not balancing values have been established to true.

Once the balances have been set, our program will now start checking the colour beneath the sensor, chances are that in the physical world you still haven’t removed it from your black sample, but never mind that, we were talking about the code.

If you followed what was going on with the balancing scan, we are pretty much doing the same thing. The big difference is that we are using some math to balance our reading now. Basically we are altering our reading based on the maximum and minimum possible readings, and making it a value we can use, namely between 0-255(roughly). Which gives us a pretty fair representation of the colour.

After that, we simply set the colour. We need to just tweek the numbers a little, because often the math above returns greater than or less than our acceptable values. Then we set the red green and blue variables and use the Moodlamp library to facilitate displaying the colour.

I almost forgot to mention the getReading function, which just gets an average reading for times number of readings. Not strickly necessary, as one reading seems sufficient, but I did not know that at the time.

The two print functions are for debugging purposes, and simply print our readings to the serial port. Yes I know I call one in the loop, but you don't have to. I just like scrolling numbers sometimes. Plus I was outputting it to processing during testing, to see exactly what colour the sensor is seeing. I will try to find the time to document and upload that sketch in the near future, but for now you are on your own. (Not hard if you are familiar with Processing and serial communication)

Once you have finished writing your code, upload it to the lamp and start playing. By playing I mean testing....but in a fun way.

Step 7: Ecetera

When you power up your programmed lamp, it will immediately go into setup mode where it will perform the white/black balancing scans.

It will pulse red (to warn white scan is coming) then white, then stay white for two seconds, and then scan. You need to have your white sample under it.

Then it will pulse blue. Change your sample for black before it scans again (about three seconds).
Now, I say black, but this is where having prepared a couple of samples of greys will help. You will need to use a grey for this lamp application, the reason being is that dark colours are hard to make with a light.
This means that you will have to test your lamp by resetting it and trying different greys until you are happy. I am pleased with the results when using a dark middle grey, but much will depend on your lamp construction, your shrouding and your diffuser.
That being said, black will give the best actual real colour return value (the truest when you try the values via a monitor), if you are planning to use the sensor for a different application.

I hope you enjoyed this Instructable. Please give me some feedback, and post your projects if you used this as a starting point or inspiration.

Vote for me, follow me and all that good shameless stuff. I like prizes, I love feedback.

Share and enjoy.

Make It Glow Challenge

Runner Up in the
Make It Glow Challenge

The Mad Science Fair

Participated in the
The Mad Science Fair

Pocket-Sized Contest

Participated in the
Pocket-Sized Contest

Hack It! Challenge

Participated in the
Hack It! Challenge

Be the First to Share


    • Raspberry Pi Contest 2020

      Raspberry Pi Contest 2020
    • Wearables Contest

      Wearables Contest
    • Fix It Contest

      Fix It Contest

    55 Discussions


    3 years ago

    Hey.. great ible.. I went thorough your ible for detecting colours too.. But I still have a basic question- why do you use leds to provide light which then reflects from the surface (to be colour sensed)?

    While writing this question I'm guessing it is to increase the dimensions or channels from 1 to 3. But can you please elaborate a bit on it (if it is correct)
    Sorry if it is already answered, but the science kept bothering me.


    3 years ago

    a lovely and unique Project. thumbsup


    4 years ago on Step 2

    what shall be the cost of the same?


    4 years ago on Introduction

    I love this instructable!!! Enjoying it so much:D
    This was my first project with arduino and all the prototyping boards and things.

    I was stuck for quite a long time in installing the libraries.

    users/documnts/arduino/libraries/moodlamp(I made it)/moodlamp.cpp and moodlamp.h(from the "rgb lamp with custom moodlamp")

    I did this and tried compiling chameleon.txt, got a lot of errors that said something like

    Wprogram.h is not found

    lamp is not declared in this scope


    what I did was

    1, install the arduino ver22 and use that one instead of the newest release(Thanks to the other comentor!)

    2, changed "Wprogram.h" to "Arduino.h" in the cpp and .h

    and it finally worked!!!;-D yayyy

    now I`m going to get working with the hardware part.

    looking so much forward!

    thanx again for the awesome project!!!


    4 years ago on Introduction

    Sooo coool. I've seen products like this on Vat19. This is cool how you made one!!


    4 years ago on Introduction

    I finished the project and have a few suggestions. The drawing shows the use of Analog pin 2 while the program calls for using Analog pin 0. Also, I was unable to get usable readings using a 100K resistor with the photocell. I reduced it to 6.2K and it now works well. Thanks for your project !


    4 years ago on Introduction

    how do you managed to distinguish the ranges exactly for different color?


    5 years ago on Introduction

    This is coolest applied-color-theory
    I've ever seen.

    Kudos to you sir, this good work! :)


    7 years ago on Introduction

    could you guys please help me make a diagram for a RGB LED.


    Reply 7 years ago on Introduction

    hope this helps


    7 years ago on Introduction

    Hi. I got some trouble.

    I put the .ccp and .h files in libreary/moodlamp.
    I got no skteches folder.
    Using IDE 0022

    when i try to compile the library i get this error.

    sketch_feb23a.cpp:1:22: error: moodlamp.h: No such file or directory

    Any idea what i am doing wrong?


    7 years ago on Step 4

    How would you do this using a common anode rgb.
    would it be okay to use one resistor on the anode?


    Reply 7 years ago on Step 4

    no, you would use one resistor on each cathode, and your code would be different as well. The leds will light when pins go low as opposed to high.


    8 years ago on Introduction

    As I already replied. You have left a comment uncommented. Just putt // in front of the line that is a comment and not code that reads" pulse white".


    Reply 8 years ago on Introduction

    like this
    //pulse white
    would it be too much to ask that you remove the over zealous post (the one above where you have posted the entire sketch)? It sure takes up a lot of room for something that could have been posted with a single line. I don't think anyone needs the sketch with a typo in it. It is already included in the instructable.Thanks.