2023-11-08 01:36 AM - last edited on 2024-02-15 01:11 AM by Peter BENSCH
Hi,
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).
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;
}
Solved! Go to Solution.
2023-11-20 12:26 AM
Hi Seb,
An update, my problems where related to hardware and noise while calibrating. after making some changes to the calibration sequence and room variables (block out external light etc.) the sensor is now measuring beyond the 1,2m and shows accurate data.
I am currently polling for data ready so i don't use the interrupt status value.
Kind regards,
Richard
2023-11-08 02:24 AM - last edited on 2024-02-15 01:13 AM by Peter BENSCH
HI,
An update, after looking through the API code i see the '\CurrentParameters.dmax_lut.dmax_mm[0]' is initialized at a max value of 1200 so this can't possibly return a value higher than 1200 >> do we need to change some things in the API before the long range mode of 2000 (2m) is enabled?
Below is the API's initialization of the Data_init function:
VL53L0X_Error VL53L0X_DataInit(VL53L0X_Dev_t *Dev)
{
VL53L0X_Error Status = VL53L0X_ERROR_NONE;
VL53L0X_DeviceParameters_t CurrentParameters;
int i;
uint8_t StopVariable;
/*by default the I2C is running at 1V8 if you want to change it you
*need to include this define at compilation level.
*/
#
ifdef USE_I2C_2V8
Status = VL53L0X_UpdateByte(Dev,
VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV,
0xFE,
0x01);#
endif
/*Set I2C standard mode */
if (Status == VL53L0X_ERROR_NONE)
Status = VL53L0X_WrByte(Dev, 0x88, 0x00);
VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, ReadDataFromDeviceDone, 0);
#
ifdef USE_IQC_STATION
if (Status == VL53L0X_ERROR_NONE)
Status = VL53L0X_apply_offset_adjustment(Dev);#
endif
/*Default value is 1000 for Linearity Corrective Gain */
PALDevDataSet(Dev, LinearityCorrectiveGain, 1000);
/*Set Default static parameters
*set first temporary values 9.44MHz *65536 = 618660
*/
VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, OscFrequencyMHz, 618660);
/*Set Default XTalkCompensationRateMegaCps to 0 */
VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, 0);
/*Get default parameters */
Status = VL53L0X_GetDeviceParameters(Dev, &CurrentParameters);
if (Status == VL53L0X_ERROR_NONE)
{
/*initialize PAL values */
CurrentParameters.DeviceMode =
VL53L0X_DEVICEMODE_SINGLE_RANGING;
CurrentParameters.HistogramMode =
VL53L0X_HISTOGRAMMODE_DISABLED;
/*Dmax lookup table */
/*0.0 */
CurrentParameters.dmax_lut.ambRate_mcps[0] = (FixPoint1616_t) 0x00000000;
/*1200 */
CurrentParameters.dmax_lut.dmax_mm[0] = (FixPoint1616_t) 0x04B00000;
/*0.7 */
CurrentParameters.dmax_lut.ambRate_mcps[1] = (FixPoint1616_t) 0x0000B333;
/*1100 */
CurrentParameters.dmax_lut.dmax_mm[1] = (FixPoint1616_t) 0x044C0000;
/*2 */
CurrentParameters.dmax_lut.ambRate_mcps[2] = (FixPoint1616_t) 0x00020000;
/*900 */
CurrentParameters.dmax_lut.dmax_mm[2] = (FixPoint1616_t) 0x03840000;
/*3.8 */
CurrentParameters.dmax_lut.ambRate_mcps[3] = (FixPoint1616_t) 0x0003CCCC;
/*750 */
CurrentParameters.dmax_lut.dmax_mm[3] = (FixPoint1616_t) 0x02EE0000;
/*7.3 */
CurrentParameters.dmax_lut.ambRate_mcps[4] = (FixPoint1616_t) 0x00074CCC;
/*550 */
CurrentParameters.dmax_lut.dmax_mm[4] = (FixPoint1616_t) 0x02260000;
/*10 */
CurrentParameters.dmax_lut.ambRate_mcps[5] = (FixPoint1616_t) 0x000A0000;
/*500 */
CurrentParameters.dmax_lut.dmax_mm[5] = (FixPoint1616_t) 0x01F40000;
/*15 */
CurrentParameters.dmax_lut.ambRate_mcps[6] = (FixPoint1616_t) 0x000F0000;
/*400 */
CurrentParameters.dmax_lut.dmax_mm[6] = (FixPoint1616_t) 0x01900000;
PALDevDataSet(Dev, CurrentParameters, CurrentParameters);
}
/*Sigma estimator variable */
PALDevDataSet(Dev, SigmaEstRefArray, 100);
PALDevDataSet(Dev, SigmaEstEffPulseWidth, 900);
PALDevDataSet(Dev, SigmaEstEffAmbWidth, 500);
PALDevDataSet(Dev, targetRefRate, 0x0A00); /*20 MCPS in 9:7 format */
/*Use internal default settings */
PALDevDataSet(Dev, UseInternalTuningSettings, 1);
Status |= VL53L0X_WrByte(Dev, 0x80, 0x01);
Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01);
Status |= VL53L0X_WrByte(Dev, 0x00, 0x00);
Status |= VL53L0X_RdByte(Dev, 0x91, &StopVariable);
PALDevDataSet(Dev, StopVariable, StopVariable);
Status |= VL53L0X_WrByte(Dev, 0x00, 0x01);
Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
Status |= VL53L0X_WrByte(Dev, 0x80, 0x00);
/*Enable all check */
for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++)
{
if (Status == VL53L0X_ERROR_NONE)
Status |= VL53L0X_SetLimitCheckEnable(Dev, i, 1);
else
break;
}
/*Disable the following checks */
if (Status == VL53L0X_ERROR_NONE)
Status = VL53L0X_SetLimitCheckEnable(Dev,
VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, 0);
if (Status == VL53L0X_ERROR_NONE)
Status = VL53L0X_SetLimitCheckEnable(Dev,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0);
if (Status == VL53L0X_ERROR_NONE)
Status = VL53L0X_SetLimitCheckEnable(Dev,
VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC, 0);
if (Status == VL53L0X_ERROR_NONE)
Status = VL53L0X_SetLimitCheckEnable(Dev,
VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE, 0);
/*Limit default values */
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckValue(Dev,
VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
(FixPoint1616_t)(18 *65536));
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckValue(Dev,
VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
(FixPoint1616_t)(25 * 65536 / 100));
/*0.25 * 65536 */
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckValue(Dev,
VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
(FixPoint1616_t)(35 *65536));
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckValue(Dev,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
(FixPoint1616_t)(0 *65536));
}
if (Status == VL53L0X_ERROR_NONE)
{
PALDevDataSet(Dev, SequenceConfig, 0xFF);
Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
0xFF);
/*Set PAL state to tell that we are waiting for call to
*VL53L0X_StaticInit
*/
PALDevDataSet(Dev, PalState, VL53L0X_STATE_WAIT_STATICINIT);
}
if (Status == VL53L0X_ERROR_NONE)
VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, RefSpadsInitialised, 0);
return Status;
}
Kind regards,
Richard
2023-11-08 02:36 AM
Hi,
After throwing away the RangeDMaxMillimeter variable problem i am now left with the reason why my sensor does not measure beyond 1,2m. as soon as the measurement goes beyond 1,2m i get the following resulting measurement data:
Can anybody help me make sens of the values to check where the problem is (in software or surrounding noise etc).
The RangeMillimeter variable holds a value 8190 if i go beyond 1,2m from the sensor, before the 1,2m it holds an accurate value.
Kind regards,
Richard
2023-11-18 01:17 AM
hi, did you triy to read the register 0x14 who is Result interrupt status and decode it ?
Seb
2023-11-20 12:26 AM
Hi Seb,
An update, my problems where related to hardware and noise while calibrating. after making some changes to the calibration sequence and room variables (block out external light etc.) the sensor is now measuring beyond the 1,2m and shows accurate data.
I am currently polling for data ready so i don't use the interrupt status value.
Kind regards,
Richard
2024-02-16 10:11 AM
DMAX is a very mis-understood number.
It's a function of ambient light. It says, "Given the amount of ambient light seen, a target can only be detected up to this distance." Said another way, "I cannot see beyond DMAX due to conditions".
The sensor can 'see' to 2M in ideal conditions. Near a window, there could be enough sunlight to reduce that max distance to that Dmax range.
Cellphone companies wanted that number to start an autofocus search at DMAX. So even if the sensor saw no target, they could save a lot of time, not needing to autofocus at the short distances.
As to your startup, I would always toggle the Xshut down line at the start.
Something like this, but please check your pins to make sure you are hitting the XShut pin.
This code is from my VL53L4CD setup.
/* Toggle Xshut pin to reset the sensor */
HAL_GPIO_WritePin(GPIOB, TOF_C_XSHUT_Pin, GPIO_PIN_RESET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOB, TOF_C_XSHUT_Pin, GPIO_PIN_SET);
HAL_Delay(5);
/* Print the software version */
status = VL53L4CD_GetSWVersion(&sw_version);
printf("Starting VL53L4CD driver version %u.%u.%u\n",
sw_version.major,
sw_version.minor,
sw_version.build);