VL53L0X code to minimize latency

Hello!

I am using several VL53L0X’s with Pololu’s library on an ESP32. I am attempting to retrieve ToF ranging measurements with as low latency as possible. I am then sending data wirelessly over UDP.

I’ve noticed that the while loop in readRangeContinuousMillimeters effectively creates a delay when included in my main loop code. This is because the function initiates a reading and then we must wait until the results are in, 20-30ms.

Instead I would like to turn on startContinuous in setup and then pool the VL53L0X to see when new data is ready in my main loop, sending it immediately if this is the case. I cannot find a library function to do this and thus have modified code from readRangeContinuousMillimeters to achieve this.

Could anyone confirm if this is 1) stable and 2) as low latency as possible? Do I need to worry about replicating the timeout portion of the code from VL53L0X::readRangeContinuousMillimeters?

My setup:
ToFSensor.setTimeout(100);
ToFSensor.setMeasurementTimingBudget(20000);
ToFSensor.startContinuous(100);

My loop:
// see if a reading is ready…
if ((ToFSensor.readReg(ToFSensor.RESULT_INTERRUPT_STATUS) & 0x07) != 0) {
uint16_t range = ToFSensor.readReg16Bit(ToFSensor.RESULT_RANGE_STATUS + 10);
ToFSensor.writeReg(ToFSensor.SYSTEM_INTERRUPT_CLEAR, 0x01);
// send range data…
}

Hello.

Your approach seems fine. We actually added support for non-blocking reads to our VL53L1X Arduino library in a similar fashion, but we have not gotten to adding that functionality to the L0X library yet.

Alternatively, if you want to avoid polling over I2C, you might consider looking into using the sensor in interrupt mode where GPIO1 sends an interrupt whenever a new measurement is available. We do not have any example programs demonstrating that, and our library does not have direct support for it. However, the VL53L0X API user manual (UM2309), which you can find on the product page under the “Resources” tab, has information about that, and it should be possible to augment our library to add that kind of functionality since it is based on the VL53L0X API.

- Patrick

Thanks for the helpful reply Patrick.

I can see the non blocking function in the 1X library. And thanks for the tip on perhaps ditching I2C to achieve minimal latency; I shall see how things progress.

I also noted that there seems to be another useful addition in the next gen library: VL53L1X::getRangingData, which sends data that could help judge the trustworthiness of the range_mm value. Am I correct in assuming that I could get similar data using the VL53L0X library by looking at the following register data variables?

RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN, RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF, RESULT_CORE_RANGING_TOTAL_EVENTS_RTN, RESULT_CORE_RANGING_TOTAL_EVENTS_REF,
RESULT_PEAK_SIGNAL_RATE_REF

In preliminary tests I have found that RESULT_CORE_RANGING_TOTAL_EVENTS_REF seems to be useful in filtering out erroneous measurements.

Best, Ben

Our VL53L0X library does not currently check or directly give access to the status reported by the sensor, but that would probably be a good improvement. If you want to add that functionality yourself, the VL53L0X API has a VL53L0X_GetRangingMeasurementData() that among other things returns a RangeStatus value, so I would recommend looking at how that works. You can find a basic summary of it in the “Get a result” section of the API user manual I mentioned in my previous post (UM2309).

- Patrick