Qwiic Ambient Light Sensor (VEML6030) Hookup Guide

Pages
Contributors: Elias The Sparkiest
Favorited Favorite 1

Example 2 and 3: Ambient Light Interrupt

The SparkFun Ambient Light Sensor can issue an interrupt whenever the ambient light readings cross high or low thresholds. In this example, we'll talk about setting those thresholds and reading when those thresholds have been crossed in two different ways:

  • the on-board hardware interrupt pin labeled INT
  • through software monitoring

The code for both Example 2 and 3 only differ in the main loop() and these differences are highlighted under Example 2 - Hardware Interrupt and Example 3 - Software Interrupt sections below.

Again as in example one, at the top we see the gain, time and luxVal variables. The gain and integration times are vital for setting the tolerance for light and resolution of your sensor - see the Gain and Integration Time table under Hardware Overview above. The luxVal variable holds the ambient light readings further down in the code. Just below we see the interrupt settings lowThresh, highThresh and numbValues. The first two set the low and high threshold variables that will trigger the interrupt when the ambient light crosses the given values. The last variable is the number of times a value must cross a threshold to trigger an interrupt. I have the variables set to 20 Lux for the lower end, 400 Lux for the upper end, and that an interrupt must be issued after the ambient light crosses one of these thresholds once.

language:c
#include <Wire.h>
#include "SparkFun_VEML6030_Ambient_Light_Sensor.h"


// Close the address jumper on the product for addres 0x10.
#define AL_ADDR 0x48

SparkFun_Ambient_Light light(AL_ADDR);

// Possible values: .125, .25, 1, 2
// Both .125 and .25 should be used in most cases except darker rooms.
// A gain of 2 should only be used if the sensor will be covered by a dark
// glass.
float gain = .125;

// Possible integration times in milliseconds: 800, 400, 200, 100, 50, 25
// Higher times give higher resolutions and should be used in darker light. 
int time = 100;
long luxVal = 0; 


// Interrupt settings. 
long lowThresh = 20; 
long highThresh = 400; 
int numbValues = 1;

// Interrupt pin
int intPin = 3;
// -- OR -- if not using interrupt pin:
int interrupt;

Again, as in the first example, we start communication with the sensor with light.begin(), set the gain (light.setGain()) and integration time settings (light.setIntegTime()), and read them back by printing them out to the serial monitor with the respective read functions. But just below we see where we set the two thresholds. First the low threshold with light.setIntLowThresh() and then the high threshold with light.setIntHighThresh(), giving these functions the values we set in the variables above. We then read those settings back to make sure that they're set correctly.

Now we set how many values will need to cross the threshold with the light.setProtect() function call and read it back. This setting is optional and defaults to one. Finally, we enable the interrupt with light.enableInt(). While the sensor knows our thresholds it does not quite know we want the interrupt to be enabled until we tell it to.

language:c
void setup(){

  Wire.begin();
  Serial.begin(115200);
  pinMode(intPin, INPUT);

  if(light.begin())
    Serial.println("Ready to sense some light!"); 
  else
    Serial.println("Could not communicate with the sensor!");

  // Again the gain and integration times determine the resolution of the lux
  // value, and give different ranges of possible light readings. Check out
  // hoookup guide for more info. The gain/integration time also affects 
  // interrupt threshold settings so ALWAYS set gain and time first. 
  light.setGain(gain);
  light.setIntegTime(time);

  Serial.println("Reading settings..."); 
  Serial.print("Gain: ");
  float gainVal = light.readGain();
  Serial.print(gainVal, 3); 
  Serial.print(" Integration Time: ");
  int timeVal = light.readIntegTime();
  Serial.println(timeVal);

  // Set both low and high thresholds, they take values in lux.
  light.setIntLowThresh(lowThresh);
  light.setIntHighThresh(highThresh);
  // Let's check that they were set correctly. 
  // There are some rounding issues inherently in the IC's design so your lux
  // may be one off. 
  Serial.print("Low Threshold: ");
  long lowVal = light.readLowThresh();
  Serial.print(lowVal);
  Serial.print(" High Threshold: ");
  long highVal = light.readHighThresh();
  Serial.println(highVal);

  // This setting modifies the number of times a value has to fall below or
  // above the threshold before the interrupt fires! Values include 1, 2, 4 and
  // 8. 
  light.setProtect(numbValues);
  Serial.print("Number of values that must fall below/above threshold before interrupt occurrs: ");
  int protectVal = light.readProtect();
  Serial.println(protectVal);

  // Now we enable the interrupt, now that he thresholds are set. 
  light.enableInt();
  Serial.print("Is interrupt enabled: ");
  int enabInt = light.readIntSetting();
  if( enabInt == 1 )
    Serial.println("Yes"); 
  else
    Serial.println("No");

  Serial.println("-------------------------------------------------");

  // Give some time to read our settings on startup.
  delay(3000);
}

Example 2: Hardware Interrupt

Now let's read some light! Since we're just using a hardware interrupt we have a pin attached to PIN 3. When the ambient light reading passes either threshold the pin will go LOW. When an interrupt fires we check to see which threshold was crossed and print it out in the serial monitor.

language:c 
void loop(){

  luxVal = light.readLight();
  Serial.print("Ambient Light Reading: ");
  Serial.print(luxVal);
  Serial.println(" Lux");  

  if (digitalRead(intPin) == LOW){
    int intVal = light.readInterrupt();
    if (intVal == 1)
      Serial.println("High threshold crossed!");
    else if (intVal == 2){
      Serial.println("Low threshold crossed!");
    }
  }

  delay(200);

Example 3: Software Interrupt

If you're committed to keeping this Qwiic then we can look for an interrupt by monitoring the Ambient Light Sensor directly rather than through a digital pin. In the code we'll use the light.readInterrupt() function call directly to see if there's been an interrupt issued. That's it!

language:c
void loop(){

  luxVal = light.readLight();
  Serial.print("Ambient Light Reading: ");
  Serial.print(luxVal);
  Serial.println(" Lux");  

  interrupt = light.readInterrupt();
  if (interrupt == 1)
    Serial.println("High threshold crossed!");
  else if (interrupt == 2){
    Serial.println("Low threshold crossed!");

  delay(200);

}