Issues with the SparkFun UV light sensor breakout output

Hi,

I recently began a project building a cheap UV data logger. I have hooked up a SparkFun UV light sensor breakout to an Uno R3 (SKU: CE05629) via a data logging shield (SKU: TA0078). No filter was used, just these items.

Everything seems to work okay but I am very confused by the data I’m getting in the output, using your library - I’m a rookie so I’m suspecting I could have made an error with the programming. All I am really doing with the code is floating the raw UVA, UVB, and UVI values, then logging to a csv file on the SD card with a timestamp. I used most of the important code from this arduino experiment: https://www.arduino.cc/en/IoT-Prime/Experiment03

I tested this sensor outside and under UV lamps by comparing it to a calibrated UV-B and UVA+B radiometer. Outside, the raw counts for UVB=5662 and UVA=5996. Using the VEML6075 I converted these counts to irradiance (everything reported here is in µW cm²): UVB=2696 and UVA 6447. These values are alarmingly incorrect. Using the calibrated radiometer, I got far more realistic readings of UV irradiance: UVB=61 and UVA=3089. The UV index calculated by the breakout was around 6.8 in full sun, but it should have been between 9-10 according to the local weather station in my area. I know these values are not so trustworthy when measuring UV locally, but I do know the irradiance values for UVA and UVB are way off.

The exact same issue occurred when comparing sensor outputs from underneath a UV lamp at different distances - the veml6075 gives readings far higher than it should for UVA and UVB, but these readings are incredibly high for UVB. I was hoping you may be able to offer some guidance, as I am looking to get at least relatively accurate measurements of UV in situ.

Thanks,

Coen

Hi Coen,

Have you tested with just the examples from our [Arduino Library and observed similar results just printing to a serial terminal from your Arduino? If not, give that a try. That will help identify if it is a problem with the UV Sensor or something with the code from the Arduino experiment you linked.](GitHub - sparkfun/SparkFun_VEML6075_Arduino_Library: Arduino library for the VEML6075 UVA/UVB/UV index sensor)

Hi Mark,

I haven’t tested with your examples, thanks for your suggestion. I will try that next. I have also realised that the sensitivity for the UVA and UVB channels is for specific types of lights. For measurements under direct sunlight, as is my aim, I will need to redetermine this sensitivity using a reference meter under sunlight, after which the sensor output values can be scaled accordingly (rather than using the counts provided). I will also need to create a ‘golden sample’ prior, as outlined in the hookup guide for this breakout, to weight the UVA and UVB channels accurately. I will attempt this calibration using your codes and see how it goes! Thanks for your help.

Cool! Let us know what you find out when testing with the examples from our Arduino library. Just one note, the sensor’s readings can be saturated by high intensities of UV light so you might run into readings similar to [this issue on the GitHub repository.](Example 4 sometimes returns negative values for UV index values · Issue #2 · sparkfun/SparkFun_VEML6075_Arduino_Library · GitHub)

Hi Mark,

I have been trying this with your code. It turns out the raw UV measurements are incorrect because the sensor doesn’t come pre-calibrated to the light source the user is using. To measure the true UVB irradiance I need to redetermine the sensitivity using a reference meter, as the values Vishay give are for a given light source. I will need to redetermine them under the light source I wish to use (the sun rather than a UVTOP310 LED). At least this is what Vishay tells me!

Assuming I can figure out how to calibrate the raw UV readings to match actual UV irradiance of the sun, I plan on having 4 of these sensors on a MCU, in combination with 4 MCP9808 temperature sensors, using the I2C bus. I am completely new to this and still learning how to program I2C. I wanted to ask if you thought I’d be able to accomplish this goal, in theory?

You can absolutely have four of both the VEML6075 breakouts and MCP9808 on a single I2C bus but you will need something like a MUX to address each sensor individually since the VEML6075 has a hardware-controlled I2c address (0x10). The [Qwiic MUX would work for communicating with up to eight I2c slave devices sharing a single I2C address. The [Hookup Guide has a quick example for controlling an accelerometer that you can adapt to talk to the UV Light Sensor Breakouts.](Qwiic MUX Hookup Guide - SparkFun Learn)](https://www.sparkfun.com/products/14685)

Hi, I apologise for the late reply. I put this project down and just picked it up again. I have currently been trying to connect 4 VEML6075 breakouts to an Adafruit TCA9548A multiplexer, as I was unsure how to use the Qwiic system and therefore the Qwiic Mux.

I have the VEML6075s connected to SD/SC ports 0, 3, 5, and 7 on the Adafuit TCA9548A multiplexer, When plugged in all UV sensors are lighting up and appear to be connected properly. However, upon running the code below, it prints:

Failed to communicate with VEML6075 sensor2, check wiring?

The other sensors all read the same error message. I’m interested to know if this is likely a fault of my wiring, or if my code is incorrect. I noticed somebody else had literally the exact same problem on the arduino forums (adafruit multiplexor and 4 sparkfun VEML6075s) in February but there was no solution. If youcould offer some advice I would greatly appreciate it!

Here is my code:

#include <SparkFun_VEML6075_Arduino_Library.h>
#include <Adafruit_Sensor.h>
#include "Wire.h"
#define TCAADDR 0x70

/* Assign a unique ID to the sensors*/
VEML6075 uv1 = VEML6075();
VEML6075 uv2 = VEML6075();
VEML6075 uv3 = VEML6075();
VEML6075 uv4 = VEML6075();

/* Set up the 8 ports on multiplexor */
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

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

    /* Initialise the 1st sensor */
  tcaselect(0);
if(! uv1.begin())
{
    // There was a problem detecting the VEML6075 ... check your connections
    Serial.println("Failed to communicate with VEML6075 sensor1, check wiring?");
    while(1);
  }
    /* Initialise the 2nd sensor */
  tcaselect(2);
  if(! uv2.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Failed to communicate with VEML6075 sensor2, check wiring?");
    while(1);
  }
   /* Initialise the 3rd sensor */
  tcaselect(4);
  if(! uv3.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Failed to communicate with VEML6075 sensor2, check wiring?");
    while(1);
  }
   /* Initialise the 4th sensor */
  tcaselect(6);
  if(! uv4.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Failed to communicate with VEML6075 sensor2, check wiring?");
    while(1);
  }
}

void loop() {
  static unsigned int numReadings = 1;
  static boolean powerOnState = true;
  const unsigned int READINGS_BETWEEN_SHUTDOWN = 50; // take 50 readings before shutdown?
  
  if ((numReadings % READINGS_BETWEEN_SHUTDOWN) == 0) {
    if (powerOnState) {
      // Use shutdown to disable sensor readings. The sensor will consume less power in this state.
      uv1.shutdown(); 
      uv2.shutdown(); 
      uv3.shutdown(); 
      uv4.shutdown(); 
      Serial.println("Shut down");
      powerOnState = false;   
    } else {
      // Use powerOn to enable sensor readings.
      uv1.powerOn();
      uv2.powerOn();
      uv3.powerOn();
      uv4.powerOn();
      Serial.println("Power up!");
      powerOnState = true;
    }
  }

  /* Display the results */
tcaselect(0);
  Serial.print("Sensor #1 - ");
  Serial.print("Raw UVA reading:  "); Serial.println(uv1.rawUva());
  Serial.print("Raw UVB reading:  "); Serial.println(uv1.rawUvb());
tcaselect(2);
  Serial.print("Sensor #2 - ");
  Serial.print("Raw UVA reading:  "); Serial.println(uv2.rawUva());
  Serial.print("Raw UVB reading:  "); Serial.println(uv2.rawUvb());
tcaselect(4);
  Serial.print("Sensor #3 - ");
  Serial.print("Raw UVA reading:  "); Serial.println(uv3.rawUva());
  Serial.print("Raw UVB reading:  "); Serial.println(uv3.rawUvb());
tcaselect(6);
  Serial.print("Sensor #4 - ");
  Serial.print("Raw UVA reading:  "); Serial.println(uv4.rawUva());
  Serial.print("Raw UVB reading:  "); Serial.println(uv4.rawUvb());

  delay(100);
}

Unfortunately we can not assist with code, but are you sure you’re selecting the correct ports on the TCA9548A?

Hi Chris, okay no problem, sorry about that! I think I’m selecting the right ports. I ran some code which tried to figure out if any of the sensors were detected by any of the 8 ports - they are all not detected. I was hoping it was a simple issue with my code as I am a novice with programming.