Arduino: Color and UV sensing

Mar 26, 2015 0 comments

In my latest shipment of toys I have one UV sensor board and one color sensor board. With this combination of sensors it’s time to put into practice one of my old ideas: a test rig for compact fluorescent lights. While the luminous flux (think lumens) require an integrating sphere, which is extremely expensive and quite costly to manufacture at hobbyist level, this test rig allows easy measurement of light intensity, or brightness, evaluated in a single point. Furthermore, color temperature can be assessed based on the measured RGB levels. Finally, we can measure how much UV radiation is emitted — a good CFL light should emit as little UV radiation as possible, but does this apply in practice?

The sensors used are the UV Click and the Color Click boards, both manufactured by Mikroelektronika. Both boards operate at 3.3V, which may pose problem as most Arduino boards are 5V boards. In thsi project I used an Arduino Mega clone from Seeedstudio, which offers the option of selecting the operating voltage.

Just remember to put the switch on 3.3V mode before connecting the sensors, or they can be permanently damaged. A small nuisance is that on this board the I 2C pins are on a separate connector, which means that I cannot use the Click shield, and I have to revert to using a breadboard for this project.

Below is the schematic diagram showing how to connect the sensors. The color click uses the SDA, SCL pins from the I 2C connector, and one interrupt pin (I used Arduino Pin 3, which corresponds to interrupt source #1). The UV sensor uses SPI communication, which in case of MEGA boards are pins 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS). Of course, the SPI data lines are found also on the ISP connector, and the SS data line can be changed in software.

Created with

One might notice that on the UV click board there is a jumper that allows for the direct analog output of the sensor. It might look tempting to change the jumper to analog mode and simplify things, but the A/D convertor on Arduino Mega has 10 bits resolution, while the MCP3201 A/D convertor onboard the UV click has 12 bits of resolution.

I’m a lazy guy, and I know it takes less time to search for already written code rather than writing it myself. A Google search for any available libraries for the sensors returned the code for the Color Click board, written by Raivis Rengelis and available on GitHub. Just install this library and the communication with the color sensor is solved. For the UV sensor there is some code on Arduino Playground for MCP3208, which can be easily modified to work with MCP3201.

Some explanations regarding the mathematical calculations inside the code. For the UV sensor the value read by the ADC is converted into values in voltage (expressed in mV). This is more than enough to perform a qualitative assessment of the CFL bulbs, by comparing the UV emissions of each of the tested bulbs.

To show the UV intensity (in mW/cm 2@ 365nm) one should see the figure 4 in the sensor datasheet. Basically, a shaded sensor should output a voltage of 1V. For an UV intensity of 10mW/cm 2the output from the sensor is typical 2.2V. Thus, UV reading = 10 * (V in-1) / 1.2.

For the color sensor, I have both RGB values and light intensity. Lucky me, I have access to a luxmeter so I can use it to calibrate the brightness values. Determining the color temperature is a little bit complicated. The code I use is based on the following paper, in which is stated that “for broadband light sources that do not produce light from a heated element, their color temperature can be characterized by Correlated Color Temperature (CCT), which is also measured in degrees Kelvin (K)”. As this is the case of CFL and LED bulbs, we can use the formulas to convert RGB to CCT.

First, the RGB values must be converted into CIE tristimulus values, or XYZ space. The formula to convert RGB to XYZ is:

X = -0.14282 * R + 1.54924 * G — 0.95641 * B
Y = -0.32466 * R + 1.57837 * G — 0.73191 * B = Illuminance
Z = -0.68202 * R + 0.77073 * G + 0.56332 * B

We then determine

x = X/(X+Y+Z)
y = Y/(X+Y+Z)


n = (x − 0.3320) / (0.1858 − y)

To save memory space we can express directly n as being:

n = (0.23881 * R + 0.25499 * G — 0.58291 * B) / (0.11109 * R — 0.85406 * G + 0.52289 * B)

Finally, we determine the CCT value:

CCT = 449 * n 3+ 3525 * n 2+ 6823.3 * n + 5520.33

Regarding the UV sensor, there are two issues that have to be solved. First, the UV sensor must me enabled. In this project the EN pin of the ML8511 is connected to Arduino digital pin 7. This pin must be set on logical 1 to enable the UV sensor. Second, we must perform an A/D conversion and read the result. The MCP3201 A/D convertor uses SPI communication, albeit with some particularities. First, the MISO line is not used. The CS line pin is used to initiate communication with the device when pulled low. It will also end the A/D conversion when pulled high. The SPI clock pin is used to initiate a conversion and to clock out each bit of the conversion as it takes place. The SPI serial data output pin is used to shift out the results of the A/D conversion. According to the MCP3210 documentation, data will always change on the falling edge of each clock as the conversion takes place. The code for reading the UV value is inspired by the MikroC for AVR example provided with the UV click board, and was modified to work with Arduino IDE.

Before running this code don’t forget to install the software library for the color sensor!

Some preliminary results:

- Measuring the color temperature is influenced by the ambient lighting. Even the sunlight filtered through some yellow colored window shades registered as a different color temperature.

- Whenever one of the color detectors is saturated (eg. reads 65535), the color temperature indicated is wrong. In this case increase the distance between the light source and the sensors.

Related Posts


{{posts[0].date}} {{posts[0].commentsNum}} {{messages_comments}}


{{posts[1].date}} {{posts[1].commentsNum}} {{messages_comments}}


{{posts[2].date}} {{posts[2].commentsNum}} {{messages_comments}}

Contact Form


Email *

Message *

Recent Comments