Skip to Content

UV Index Meter With VEML6070 and Arduino

UV Index Meter With VEML6070 and Arduino

In this tutorial you will learn how to build a UV Index Meter with an VEML6070 UV light sensor, an OLED and an Arduino Uno.

The UV Index is a measure of the strength of ultraviolet (UV) radiation from the sun. The purpose of the UV index is to help people protecting themselves from UV radiation, which can cause sunburn, skin aging, DNA damage, skin cancer, immunosuppression, and eye damage.

Our UV Index Meter will read the UV light intensity from an VEML6070 UV sensor and will display it along with a risk level on an OLED screen to keep you informed of the current UV risk. For context, the recommendations of the Cancer Council are to check the UV Index when you are:

  • planning or participating in an outdoor activity or event
  • undertaking recreational activities such as running, swimming, cycling or team sports
  • watching a spectator sport, such as tennis or cricket
  • working outdoors, or have responsibility for outdoor workers, or
  • responsible for young children and their outdoor activities.

Let’s get started with this project and have a look at the list of required parts first.

Required Parts

I used an Arduino Uno for this project, but any other Arduino or any ESP32/ESP8266 board will work as well. Note that VEML6070 Sensors can get very expensive. I listed the cheapest one I could find on Amazon but I recommend that you shop around a bit and compare prices.

VEML6070 UV Light Sensor

Arduino

Arduino Uno

USB Data Sync cable Arduino

USB Cable for Arduino UNO

Dupont wire set

Dupont Wire Set

Half_breadboard56a

Breadboard

OLED display

OLED Display

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.

The VEML6070 UV light Sensor

The VEML6070 UV light sensor is a digital sensor that measures the intensity of ultraviolet (UV) light. It uses a photodiode to convert UV light into an electrical signal, which is then processed by an internal circuit to provide a digital output. It has a peak sensitivity for UVA light at a wavelength of 355nm. The plot below shows the Spectral Response of the VEML6070:

Spectral Response of VEML6070
Spectral Response of VEML6070 (source)

The VEML6070 sensor is designed to be easily integrated into various electronic devices and projects due to its small size and low power consumption. It has power shutdown mode, which reduces the power consumption to be less than 1 μA.

Block Diagram

The sensor communicates with microcontrollers via an I2C interface, making it compatible with popular development boards like Arduino and ESP32. The picture below shows the block diagram of the internal components and the IO pins:

Block Diagram of VEML6070
Block Diagram of VEML6070 (source)

SDA and SCL are the pins for the I2C interface. Vdd and GND are for the power supply and the sensor runs on 2.7 V to 5.5 V. The VEML6070 has a temperature compensation that ensures a linear sensitivity to solar UV light. The sensitivity can be adjusted by an external resistor connected to RSET. The active acknowledge (ACK) pin allows the sensor to send out an UV Index alert signal if the a threshold is exceeded. For more details have a look at the datasheet:

This sensor is commonly used in applications, where monitoring UV light exposure is important, such as in wearable devices, UV index meters, and UV sterilization systems. Its high sensitivity and accuracy make it a valuable tool for measuring UV light levels in both indoor and outdoor environments.

Breakout Board

If you want to use the raw sensor with a microcontroller you would need a few extra parts (resistors, capacitors). See the Typical Application Circuit of the VEML6070 according to the datasheet.

Typical Application Circuit of VEML6070
Typical Application Circuit of VEML6070 (source)

To avoid the hassle, you can get breakout boards that have these parts already integrated. The picture below shows a typical breakout board for the VEML6070, with the I2C interface (SCL, SDA), power supply (VCC, GND) and the acknowledge (ACK) output.

Breakout board for VEML6070
Breakout board for VEML6070

In the following, we will use such a breakout board to connect the VEML6070 sensor to an Arduino.

Connecting VEML6070 to Arduino

Due to the I2C interface, connecting the VEML6070 sensor to an Arduino Uno is very easy. Just connect the SCL and SDA pins of the VEML6070 breakout board to the corresponding pins on the Arduino board as shown below.

Wiring of VEML6070 sensor with Arduino
Wiring of VEML6070 sensor with Arduino

Next, connect ground and VCC. You can use 5V or 3.3V for VCC; I went with 3.3V.

And that is all you need to do to connect the sensor.

Code to read UV Index from VEML6070

In this section we will write a tiny bit of code to test the sensor. First we will need to install a suitable library.

There are three libraries to read VEML6070 sensor data. There is the Adafruit_VEML6070 library, the Seeed_VEML6070 library, and the arduino-VEML6070 library. I used the last one, since it is easy to use and computes risk index and level. You can install it as usual via the Library Manager and after installation it should look like this:

arduino-VEML6070 library installed in Library Manager
arduino-VEML6070 library installed in Library Manager

Now we can write some code. The following, very simple example reads the measured UV intensity from the VEML6070 sensor and prints it to the Serial Monitor:

#include "VEML6070.h"

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

void loop() {
  uint16_t uvs = VEML.read_uvs_step();
  Serial.print("UVS:");
  Serial.println(uvs);
  delay(1000);
}

If you upload this code and open your Serial Plotter, you should see a curve for UVS appearing. And when you expose the sensor to a light source (e.g. a torch light) you should see a bump:

Serial Plotter showing response of VEML6070 to light
Serial Plotter showing response of VEML6070 to light

As you can see, reading data from the VEML6070 sensor is very simple. To make things a bit more interesting, we are going to add an OLED in the next section.

Adding an OLED

Instead of displaying the UV intensity data on the Serial Monitor it would be nicer to show them on a separate display. This would allow us to build a portable UV Index Meter. In this section, we therefore add an OLED to the circuit and display the UV data on it.

Connecting OLED to Arduino

Since the OLED is also an I2C device, connecting it is straightforward. We simply connect SDA and SCL to the same pins the VEML6070 sensor is connected to. Since the OLED runs on 3.3V, we can also share the power supply lines. The picture below shows the complete wiring.

Wiring of OLED & VEML6070 with Arduino
Wiring of OLED & VEML6070 with Arduino

If you have any difficulties with the OLED, have a look at the tutorial How to Interface the SSD1306 I2C OLED Graphic Display With Arduino.

And here is how the running circuit looks in reality 😉

Wiring of OLED & VEML6070 with Arduino
Wiring of OLED & VEML6070 with Arduino

Code to show UV Index on OLED

In this section we will write the code to show the UV data on the OLED. To control the OLED we will use the Adafruit_SSD1306 library. You will have to install it via the Library Manager and after installation it should look like this:

Adafruit_SSD1306 library installed in Library Manager
Adafruit_SSD1306 library installed in Library Manager

And here is the complete code. Have a look first and then we discuss its details.

#include "VEML6070.h"
#include "Adafruit_SSD1306.h"

Adafruit_SSD1306 oled(128, 64, &Wire, -1);

void oled_init() {
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.clearDisplay();
  oled.setTextSize(2);
  oled.setTextColor(WHITE);
}

void centered(const char* text, int y) {
  int16_t x1, y1;
  uint16_t w, h;
  oled.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
  oled.setCursor(64 - w / 2, y);
  oled.print(text);
}

void display_uvs() {
  static char text[30];
  uint16_t uvs = VEML.read_uvs_step();
  int risk_level = VEML.convert_to_risk_level(uvs);
  char* risk = VEML.convert_to_risk_char(risk_level);

  oled.clearDisplay();
  centered(risk, 15);
  sprintf(text, "%d", uvs);
  centered(text, 45);
  oled.display();
}

void setup() {
  oled_init();
  VEML.begin();
}

void loop() {
  display_uvs();
  delay(1000);
}

The code above reads the UV light intensity from the sensor and displays it along with a risk level on the OLED screen, whereby the UV radiation are levels:

  • low (1-2)
  • moderate (3-5)
  • high (6-7)
  • very high (8-10)
  • extreme (11 and above).

Libraries and Display Initialization

We start by including the necessary libraries for the VEML6070 sensor and the Adafruit SSD1306 OLED display. We then initialize the OLED display in the oled_init() function. This function sets up the display, clears it, sets the text size, and color for the text.

#include "VEML6070.h"
#include "Adafruit_SSD1306.h"

Adafruit_SSD1306 oled(128, 64, &Wire, -1);

void oled_init() {
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.clearDisplay();
  oled.setTextSize(2);
  oled.setTextColor(WHITE);
}

Note that the I2C address for the OLED display is set to 0x3C in oled.begin(). Most of these small OLEDs use this address but yours might be different. If you don’t see anything on the OLED, it most likely has a different I2C address and you have change the address passed on to oled.begin(). If you don’t know the I2C address have a look at the How to Interface the SSD1306 I2C OLED Graphic Display With Arduino tutorial.

Display Functions

The centered() function is used to print text centered on the OLED display at a specified y-coordinate. The display_uvs() function reads the UV light intensity from the sensor, calculates the risk level, and displays it along with the UV intensity on the OLED screen.

void centered(const char* text, int y) {
  // Function to center text on OLED display
}

void display_uvs() {
  // Function to display UV index and risk level on OLED display
}

Setup Function

In the setup() function, we initialize the serial communication for debugging purposes, initialize the OLED display, and begin communication with the VEML6070 sensor.

void setup() {
  oled_init();
  VEML.begin();
}

Loop Function

The loop() function continuously calls the display_uvs() function to update and display the UV index and risk level on the OLED screen. It then adds a delay of 1 second before the next update.

void loop() {
  display_uvs();
  delay(1000);
}

Output on OLED

If you upload the code, you should see the following output on the OLED. The top line shows the risk level and the number below is the UV intensity.

VEML6070 Output on OLED
VEML6070 Output on OLED

Conclusions

This tutorial showed you how to build a UV Index Meter with an VEML6070 UV light sensor. We used an Arduino Uno and an OLED screen in this project. But you could easily use a battery-powered ESP32 and an e-Paper display to construct a portable, low-energy UV Index meter.

Alternatively, a UV Index Meter would also make a nice addition to a Weather Station to warn about high UV light exposure. For technical details on how to realize this have a look at the Simple ESP32 Internet Weather Station and the Weather Station on e-Paper Display tutorials.

Finally, if you just want to measure light (and not specifically UV light), you can use the BH1750 sensor. How to use it, is described in the tutorial: Ambient Light Sensor BH1750 with Arduino.

If you have any other questions, feel free to ask.

Happy tinkering ; )