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.
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.
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);
}
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.