Making a "color sensor" using reflection of light

by cfsl

Published on February 14, 2017

We're using the light sensor to distinguish between colored marbles and white marbles.  Using an arduino, you can actually distinguish between white marbles, yellow marbles and red or blue marbles.  We're showing a basic setup here that doesn't require an arduino.

The setup is very simple: an LED is mounted under a LEGO ball track and the light sensor measures the light that's reflected by marbles passing by.  Colored items reflect less light than white items.  Using a threshold, you can filter out the colored items and count only the white ones.

This setup only works with low ambient light.  You can add a light shield around the track and the sensor to make it usable in normal lighting conditions.

Update: added arduino code.  More info at step 5.

Duration: 15 minutes

How To Make It


Build the sensor Mount the long led in such a way that it doesn't shine directly on the light sensor. The LED has to point up so that marbles passing by reflect the light of the LED onto the light sensor. The long LED fits nicely in the hole of a studless LEGO piece, which makes it relatively easy to add it to an existing LEGO model. Attach the long LED and the light sensor to the power. The output of the light sensor goes to a threshold, which is connected to a number bit. The number bit has to be set to count up.


Determine light level In this step, we measure the light level coming out of the sensor. For this step, remove the threshold and attach the number bit directly to the light sensor. Put the number bit in "values" mode. Now move a marble back and forth on the track, in the vicinity of the light sensor. Observe the light levels the sensor is measuring on the number bit. In our setup, a white marble resulted in light levels around 50. Yellow marbles reflected less light, showing measurements of around 40. Blue or red marbles resulted in levels of around 25. You may need to adjust the sensitivity of the light sensor. Make sure you measure light levels under the same lighting conditions that you'll be using to count colors. If there's too much light, you will saturate the light sensor, making it impossible to distinguish between colors. That's why you should either turn down the light significantly, or put the sensor in a "dark room" made by cardboard or some other non-transparant material.


Set up the threshold Now attach a power bit to a slider, a number bit, a threshold and some output bit such as the bar graph. Set the number bit to measure values. Move the slider so that the number bit shows a value that's in the middle between two marble values. For example, to distinguish between yellow (values of around 40) and white (values of around 50), set the slider to 45. This allows you to count only the white marbles. If we'd want to count the white and the yellow marbles, but not the blue and red ones, we would set the slider to 33 in our example (value between 25 for red/blue and 40 for yellow). Set the threshold to trigger at the level set by the slider. Move the threshold and the number bit back to the original circuit. Don't forget to set the number bit to count up. Note that it's more difficult to distinguish between yellow and white than it is to distinguish between red/blue and yellow. If you cannot find a good threshold, try to distinguish between white marbles and dark marbles such as red or blue. In our case, the system would consistently distinguish between yellow and white, even though their reflected light values are relatively close to each other.


Enjoy The number bit will now count the marbles that have a color that reflects more light than what the threshold is set at. We added two bits of paper to align all marbles exactly right and to slow them down a bit, making the reading more accurate. This is the basic circuit. Adding an arduino enables you to count a specific color, such as the yellow marbles, for example. Unlike the threshold, the arduino can trigger on values between two boundaries. The threshold only triggers on values above a certain boundary. Or you can have it drive a servo that moves the marbles left or right down the track, resulting in a color sorter.


And now with an arduino Here's a bonus :-) I added an arduino sketch that counts 3 colors. The upper right counts by outputting pulses (so it can drive a number bit set to "count" mode), while the middle right and lower light outputs are analog and output a value so they drive a number bit set to "value" mode. The outputs count (in our case) red/blue marbles (top right), yellow marbles (middle right) and white marbles (bottom right). The tricky part is setting the thresholds. The way I set it up was I measured a base reading: the reading of the light sensor without anything going on. This reading should be sufficiently low so that the sensor is not saturated with the brightest marble. You can set the base reading through BASE_READING in the code. This reading is output to the serial console (sensor value). If you need to change the threshold values, you can comment out the line in resetValues() that sets maxValue to zero. Then, measure the darkest marble (red/blue), write down the max value (it's written to the console), then measure the middle marble (yellow), write down the max value, and finally measure the brightest marble (white) and write down the max value. You can measure by simply letting a marble run down the track while the program is running. You may want to use a few marbles of each color and note the brightness range. With these measurements you should be able to enter the thresholds in the program. Don't forget afterwards to uncomment the line that sets maxValue to zero. Note about the picture: I only have 2 number bits, so I used a latch + bargraph to "count" the red/blue marbles. Every time a red or blue marble is seen, the bargraph toggles between on and off. If you connect a number bit set to "count" mode, it will actually count the red/blue marbles. You can reset the middle and bottom right counters by pressing the button. The top right count cannot be reset this way.

Related Projects