Skip to main content
Associate II
June 28, 2026
Question

VL53L1X interrupt not configurable

  • June 28, 2026
  • 1 reply
  • 6 views

Hello,

 

I have attempted to set up threshold interrupts with the VL53L1X using the library from pololu, but the lesser known version implementing the ST API.

 

As such, my code looks like this:

 

#include <Wire.h>
#include "vl53l1_api.h"
#include <Arduino.h>

// Timing budget set through VL53L1_SetMeasurementTimingBudgetMicroSeconds().
#define MEASUREMENT_BUDGET_MS 50

// Interval between measurements, set through
// VL53L1_SetInterMeasurementPeriodMilliSeconds(). According to the API user
// manual (rev 2), "the minimum inter-measurement period must be longer than the
// timing budget + 4 ms." The STM32Cube example from ST uses 500 ms, but we
// reduce this to 55 ms to allow faster readings.
#define INTER_MEASUREMENT_PERIOD_MS 55

VL53L1_Dev_t dev;
VL53L1_DEV Dev = &dev;

int status;

void printRangingData();

void setup()
{
uint8_t byteData = 0;
uint16_t wordData = 0;

Wire.begin(5, 6);
Wire.setClock(400000);
Serial.begin(115200);

delay(3000);

Serial.println("starting");

Dev->I2cDevAddr = 0x52;

VL53L1_software_reset(Dev);

Serial.println(F("Autonomous Ranging Test"));
status = VL53L1_WaitDeviceBooted(Dev);
if(!status) status = VL53L1_DataInit(Dev);
if(!status) status = VL53L1_StaticInit(Dev);
if(!status) status = VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_LONG);
if(!status) status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, (uint32_t)MEASUREMENT_BUDGET_MS * 1000);
if(!status) status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev, INTER_MEASUREMENT_PERIOD_MS);

pinMode(20, INPUT_PULLUP);

static VL53L1_DetectionConfig_t detectionConfig = {
.DetectionMode = VL53L1_DETECTION_DISTANCE_ONLY,
.IntrNoTarget = false,
.Distance = {
.CrossMode = VL53L1_THRESHOLD_CROSSED_LOW,
.Low = 100,
},
};

if(!status) status = VL53L1_SetThresholdConfig(Dev, &detectionConfig);

if(!status) status = VL53L1_StartMeasurement(Dev);

if(status)
{
Serial.println(F("VL53L1_StartMeasurement failed"));
delay(999999);
}
}

void loop()
{
static long lastInterrupt = 0;

bool triggered = !digitalRead(20);
if (triggered) {
printf("interrupt! %ld\n", millis() - lastInterrupt);
lastInterrupt = millis();
VL53L1_ClearInterruptAndStartMeasurement(Dev);
}
}

 

The issue is that even after calling VL53L1_SetThresholdConfig, I receive interrupt every 107 / 108 milliseconds, regardless of whether anything is present in front of the sensor or not.

 

It does not matter whether I place my hand in front of the sensor or not.

 

How could I enable interrupts only when the threshold criteria are met?

 

Cheers!

1 reply

dakhnodAuthor
Associate II
June 29, 2026

I think I have figured something out:

 

Regardless of threshold settings, the sensor keeps on firing “data available” interrupt until the data is read out.

So, in order to make threshold interrupts work, the following has to be done:

  1. Configure interrupt settings
  2. Start measurement
  3. Wait for interrupt
  4. Read out the distance measurement
  5. Check distance by code (since the interrupt fires immediately)
  6. Jump back to 3.

Relying threshold crossing detection just by interrupt (without reading out the data) is not enough.

 

As can be observed, the reading out of data is missing in the loop of my example code.

 

Can anyone confirm this? I did not read anything about this anywhere...

ST Technical Moderator
June 29, 2026

Hi:

Actually, we have complete driver code, here is the link: STSW-IMG009 | Product - STMicroelectronics

At the same time, I want to tell you that what you summarized is correct. You can refer to the official driver code and UM file to get the entire process. A guide to using the VL53L1X ultra lite driver - User manual

Hope this information can help you, thanks.

Best regards,
Bin FAN

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.