# DIY - UV-Light Sensor

Solar radiation in the ultraviolet (UV) spectrum can get hazardous to the skin very quickly. Official weather stations rarely measure the UV-intensity, so we want to measure the UV-light ourselves!

## Aim of this lesson

In this lesson we are using an UV-light sensor to detect the amount of solar radiation in the UV-spectrum as power per area (μW / cm²).

Additionally, we convert the measured value to the standardized UV-Index which is easier to comprehend.

## Materials

• UV-Light Sensor VEML6070

## Basics

Ultraviolet "light" is a kind of radiation that is invisible to the human eye. It has a shorter wavelength than visible light, but longer than that of X-rays: The spectrum is defined from 100 nm to 380 nm.

Through absorption of the earth's atmosphere in the ozone layer, the solar radiation in the UV-B spectrum (100 - 300 nm) does barely reach the earth's surface. The less dangerous UV-A radiation (300 - 380 nm) is far less absorbed by the atmosphere.

UV-light intensity is measured in micro-watts per square-centimeter (μW / cm²). Our VEML6070 sensor measures radiation from round about 300 - 400 nm, so it can only detect UV-A radiation (for more precise information, consider the datasheet).

## Construction

Connect the VEML6070 sensor to the Arduino as shown in the graphic above.

## Program

To communicate with the sensor via the I²C bus, we need to import the Wire.h library. We also need some constants that define the sensor's I²C address and some configuration of the sensor. Additionally we define a reference value for the conversion of the measurement to a UV-index.

#include <Wire.h>

// integration times
#define IT_0_5 0x0 // 0.5 T
#define IT_1   0x1 // 1 T
#define IT_2   0x2 // 2 T
#define IT_4   0x3 // 4 T

// reference value: 0.01 W/m^2 corresponds to the UV-index 0.4
float refVal = 0.4;


Now we configure our sensor in the setup() function.

void setup() {
Serial.begin(9600);

Wire.begin();
Wire.write((IT_1<<2) | 0x02);
Wire.endTransmission();
delay(500);
}


In the loop() function we define the behaviour of our main program to read out the sensor at an interval:

void loop() {
byte msb=0, lsb=0; // first and second byte that will be read from the sensor
uint16_t uv;

delay(1);
if(Wire.available()) {
}

delay(1);
if(Wire.available()) {
}

uv = (msb<<8) | lsb; // combine bytes to an integer through a bitshift op

Serial.print("μW per cm²: ");
Serial.println(uv, DEC);     // log value as 16bit integer
Serial.print("UV-Index: ");
Serial.println(getUVI(uv));

delay(1000);
}


Attention: If you compile the program before defining the function getUVI() (see below), you will recieve a error message.

Because we can hardly relate power-per-area measurements in everyday life, we want to convert our measurements to the more widely used UV-index. To do this, we implement a function getUVI():

/*
* getUVI()
* expects the measurement value from the UV-sensor as input
* and returns the corresponding value on the UV-index
*/
float getUVI(int uv) {
float uvi = refVal * (uv * 5.625) / 1000;
return uvi;
}