cancel
Showing results for 
Search instead for 
Did you mean: 

Explanation of VL53L0X_GetRangingMeasurementData() output

RBerk.1
Associate III

Hi,

We are currently in a project where we want to use the VL53L0X chip for ranging. And the example code with PC application seems to work quite good. the next step is to create a PoC using our own system (where we are now).

I am currently reading up on the sensor guidelines, API documentation and code examples and can't really explain the return values of the 'VL53L0X_GetRangingMeasurementData' function.

According to the documentation it returns the following:

RangeMilliMeter

RangeDMaxMilliMeter:

SignalRateRtnMegaCps

AmbientRateRtnMegaCps

EffectiveSpadRtnCount

RangeStatus:

I can explain the 'RangeMilliMeter', 'RangeDMaxMilliMeter' and 'RangeStatus' variables but the other ones i dont fully understand.

The code example says the following:

SignalRateRtnMegaCps:

                       /*!< Return signal rate (MCPS)\n these is a 16.16 fix point

                       *         value, which is effectively a measure of target

                       *         reflectance.

                       */

AmbientRateRtnMegaCps

                       /*!< Return ambient rate (MCPS)\n these is a 16.16 fix point

                       *         value, which is effectively a measure of the ambien

                       *         t light.

                       */

EffectiveSpadRtnCount;

                       /*!< Return the effective SPAD count for the return signal.

                       *         To obtain Real value it should be divided by 256

                       */

Is there documentation available explaining the effective/acceptable ranges of these variables and their functionality.

Wit kind regards,

Richard

1 ACCEPTED SOLUTION

Accepted Solutions
Zhiyuan.Han
ST Employee

Hi Richrd

Megacps which means mege counts per seconds, it's a light energy unit. we use photonic counts number to indicate the light strength as we based on SPAD.

EffectiveSpadRtnCount which means the SPAD number this frame are using, normally if target is far from sensor, sensor will enable all the available SPADs, if target distace is short, system may use less SPADS.

SignalRateRtnMegaCps is signal energy indicator which shows how many photons bounce back from target to sensor. Normally short distance or high reflectance target will give high SignalRateRtnMegaCps vlaue. vice versa.

AmbientRateRtnMegaCps is noise energy indicator. there may some 940nm light in the surrounding, which means noise to TOF sensor, and this value indicate how much the noise it. if AMB is very high, then the maximum ranging distance will drop and accuracy will decrease.

Br

Zhiyuan.Han


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.

View solution in original post

8 REPLIES 8
Zhiyuan.Han
ST Employee

Hi Richrd

Megacps which means mege counts per seconds, it's a light energy unit. we use photonic counts number to indicate the light strength as we based on SPAD.

EffectiveSpadRtnCount which means the SPAD number this frame are using, normally if target is far from sensor, sensor will enable all the available SPADs, if target distace is short, system may use less SPADS.

SignalRateRtnMegaCps is signal energy indicator which shows how many photons bounce back from target to sensor. Normally short distance or high reflectance target will give high SignalRateRtnMegaCps vlaue. vice versa.

AmbientRateRtnMegaCps is noise energy indicator. there may some 940nm light in the surrounding, which means noise to TOF sensor, and this value indicate how much the noise it. if AMB is very high, then the maximum ranging distance will drop and accuracy will decrease.

Br

Zhiyuan.Han


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.
RBerk.1
Associate III

Hi Zhiyuan,

Thanks you for your explanation of these values, however i am not quite sure what to do with them. is there a guideline as how to use these values?

As it looks to me these values are indicative mostly and can only tell the user if the sensor is performing as expected but i dont know what kind of values to expect and where to draw thresholds for response actions.

Is there a way to determine what these values should be for a given condition or distance?

Kind regards,

Richard

Hi Zhiyuan,

Thanks you for your explanation of these values, however i am not quite sure what to do with them. is there a guideline as how to use these values?

As it looks to me these values are indicative mostly and can only tell the user if the sensor is performing as expected but i dont know what kind of values to expect and where to draw thresholds for response actions.

Is there a way to determine what these values should be for a given condition or distance?

Kind regards,

Richard

Zhiyuan.Han
ST Employee

Hi Richard

I suggest you follow the user manual for more detail, in simply, normally we suggest keep the ranging value with range status ==0, and discard other range status data.

VL53L0X API User_Manual.fm (st.com)

Br

Zhiyuan.Han​


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.
RBerk.1
Associate III

Hi ST,

I am currently actively debugging and working with the sensor and it shows correct measurement data when i set the profile to 'Long range' example (settings from the 'um2039' User manual).

 

RBerk1_0-1699428486679.png

however the sensor response for RangeDMaxMilliMeter: always show a value around 1200 which should be around 2000, is there another settings which i need to do before the profile is actively set to long range?

Measurement data is now also correctly measured until about 1200mm but higher results in invalid measurements.

below are my settings as they are performed in the code:

MyDevice.I2cDevAddr = 0x52;
MyDevice.comms_type = 1; // 1 should equal I2C
MyDevice.comms_speed_khz = 100;
MyDevice.hi2c = hi2c;
 
VL53L0X_DEV = &MyDevice;
 
if (VL53L0X_DataInit(VL53L0X_DEV) != VL53L0X_ERROR_NONE)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
if (VL53L0X_StaticInit(VL53L0X_DEV) != VL53L0X_ERROR_NONE)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Calibration steps
if (calibration->memory_valid != 0)
{
// SPADs calibration
VL53L0X_Error calibration_step = VL53L0X_SetReferenceSpads(VL53L0X_DEV,
calibration->refSpadCount,
calibration->isApertureSpads);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Temperature calibration
calibration_step = VL53L0X_SetRefCalibration(VL53L0X_DEV,
calibration->pVhvSettings,
calibration->pPhaseCal);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Offset calibration
calibration_step = VL53L0X_SetOffsetCalibrationDataMicroMeter(VL53L0X_DEV,
calibration->pOffsetMicroMeter);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Crosstalk calibration and enabling
calibration_step = VL53L0X_SetXTalkCompensationRateMegaCps(VL53L0X_DEV,
calibration->XTalkCompensationRateMegaCps);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
calibration_step = VL53L0X_SetXTalkCompensationEnable(VL53L0X_DEV, 1);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Configuration steps (!!!!!!!!!!!! Long range mode !!!!!!!)
 
// Limit check value >> 1
VL53L0X_Error configuration_step = VL53L0X_SetLimitCheckValue(VL53L0X_DEV,
VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
(FixPoint1616_t)(0.1*65536));
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Limit check value >> 2
configuration_step = VL53L0X_SetLimitCheckValue(VL53L0X_DEV,
VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
(FixPoint1616_t)(60*65536));
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
// Measurement timing budget
configuration_step = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(
VL53L0X_DEV, 33000);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// VCEL pulse period 1
configuration_step = VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV,
VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// VCEL pulse period 2
configuration_step = VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV,
VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Device mode
configuration_step = VL53L0X_SetDeviceMode(
VL53L0X_DEV, VL53L0X_DEVICEMODE_SINGLE_RANGING);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
Another problem i am facing is that when i connect the sensor to my devkit (NucleoF401RE) and initialize the sensor from bootup the first data i receive is incorrect and i need to power cycle the sensor before (and reinitialize) before i get correct measurement data, is there a sensor power on time before communications/configurations can start?
 
King regards,
 
Richard

Hi ST,

I am currently actively debugging and working with the sensor and it shows correct measurement data when i set the profile to 'Long range' example (settings from the 'um2039' User manual).

 

RBerk1_0-1699440434060.png

 

however the sensor response for RangeDMaxMilliMeter: always show a value around 1200 which should be around 2000, is there another settings which i need to do before the profile is actively set to long range?

Measurement data is now also correctly measured until about 1200mm but higher results in invalid measurements.

below are my settings as they are performed in the code:

MyDevice.I2cDevAddr = 0x52;
MyDevice.comms_type = 1; // 1 should equal I2C
MyDevice.comms_speed_khz = 100;
MyDevice.hi2c = hi2c;
 
VL53L0X_DEV = &MyDevice;
 
if (VL53L0X_DataInit(VL53L0X_DEV) != VL53L0X_ERROR_NONE)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
if (VL53L0X_StaticInit(VL53L0X_DEV) != VL53L0X_ERROR_NONE)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Calibration steps
if (calibration->memory_valid != 0)
{
// SPADs calibration
VL53L0X_Error calibration_step = VL53L0X_SetReferenceSpads(VL53L0X_DEV,
calibration->refSpadCount,
calibration->isApertureSpads);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Temperature calibration
calibration_step = VL53L0X_SetRefCalibration(VL53L0X_DEV,
calibration->pVhvSettings,
calibration->pPhaseCal);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Offset calibration
calibration_step = VL53L0X_SetOffsetCalibrationDataMicroMeter(VL53L0X_DEV,
calibration->pOffsetMicroMeter);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Crosstalk calibration and enabling
calibration_step = VL53L0X_SetXTalkCompensationRateMegaCps(VL53L0X_DEV,
calibration->XTalkCompensationRateMegaCps);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
calibration_step = VL53L0X_SetXTalkCompensationEnable(VL53L0X_DEV, 1);
if (calibration_step == VL53L0X_ERROR_CALIBRATION_WARNING)
{
g_tof_state = tof_sensor_reset_sensor;
return HAL_TIMEOUT;
}
else if (calibration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Configuration steps (!!!!!!!!!!!! Long range mode !!!!!!!)
 
// Limit check value >> 1
VL53L0X_Error configuration_step = VL53L0X_SetLimitCheckValue(VL53L0X_DEV,
VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
(FixPoint1616_t)(0.1*65536));
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Limit check value >> 2
configuration_step = VL53L0X_SetLimitCheckValue(VL53L0X_DEV,
VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
(FixPoint1616_t)(60*65536));
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
// Measurement timing budget
configuration_step = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(
VL53L0X_DEV, 33000);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// VCEL pulse period 1
configuration_step = VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV,
VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// VCEL pulse period 2
configuration_step = VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV,
VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
// Device mode
configuration_step = VL53L0X_SetDeviceMode(
VL53L0X_DEV, VL53L0X_DEVICEMODE_SINGLE_RANGING);
if (configuration_step != VL53L0X_ERROR_NONE)
{
// Some error
g_tof_state = tof_sensor_reset_sensor;
return HAL_ERROR;
}
 
King regards,
 
Richard
John E KVAM
ST Employee

Dmax is the most mis-understood range result.

But say you had a lot of ambient light - and saw basically nothing. Dmax says "in these light conditions, I could only 'see' this far." Which means if you DMAX was 1.2 meters and you had no target the sensor could guarentee that there was nothing up to 1.2 meters. 

If you have a target DMAX is kind of meaningless. 

The intent was for a autofocus application. With no data to go on, where whould you start the focus operation. 

Just start at DMAX and see if the camera can use it's algo to focus. But you don't have to search for focus points below DMAX.

-john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
RBerk.1
Associate III

HI John,

Thank you for your reply, i was under the impression that DMAX was the max amount of distance the sensor could detect with the given settings. (e.g. for long range profile this would then be higher).

Then ill change the softwares implementation of DMAX.

furthermore, our problem turned out to be a HW issue with our cover glass, without it and the above code/settings the sensor can measure beyond the 1,2m.

I was expecting DMAX to show a value of about 2000 so that threw me off in searching the problem.

 

Kind regards,

Richard