Showing results for 
Search instead for 
Did you mean: 

Question about VL53L0X: "RangingMeasurementData.RangeMilliMeter" is always 0x1FFF = 8191

Associate II


I have a question about distance measuring with VL53L0:

Execution of initialization functions seem to work (all returning VL53L0X_ERROR_NONE):

if ( VL53L0X_DataInit( Dev ) != VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_StaticInit( Dev ) != VL53L0X_ERROR_NONE ) return false;

uint32_t refSpadCount;

uint8_t isApertureSpads;

if ( VL53L0X_PerformRefSpadManagement( Dev, &refSpadCount, &isApertureSpads ) != VL53L0X_ERROR_NONE ) return false;

uint8_t VhvSettings;

uint8_t PhaseCal;

if ( VL53L0X_PerformRefCalibration( Dev, &VhvSettings, &PhaseCal ) != VL53L0X_ERROR_NONE ) return false;

If ( VL53L0X_SetDeviceMode( Dev, VL53L0X_DEVICEMODE_SINGLE_RANGING ) != VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_SetLimitCheckEnable( Dev, VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1 ) !=  VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_SetLimitCheckEnable( Dev, VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1 ) != VL53L0X_ERROR_NONE ) return false;

FixPoint1616_t signalLimit;

FixPoint1616_t sigmaLimit;

uint32_t timingBudget;

uint8_t preRangeVcselPeriod;

uint8_t finalRangeVcselPeriod;


signalLimit = ( FixPoint1616_t ) (65536 / 10 );

sigmaLimit = ( FixPoint1616_t ) (65536 * 60 );

timingBudget = 33000;

preRangeVcselPeriod = 18;

finalRangeVcselPeriod = 14;

if ( VL53L0X_SetLimitCheckValue( Dev, VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, signalLimit ) != VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_SetLimitCheckValue( Dev, VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, sigmaLimit ) != VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_SetMeasurementTimingBudgetMicroSeconds( Dev, timingBudget ) != VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_SetVcselPulsePeriod( Dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, preRangeVcselPeriod ) != VL53L0X_ERROR_NONE ) return false;

if ( VL53L0X_SetVcselPulsePeriod( Dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, finalRangeVcselPeriod ) != VL53L0X_ERROR_NONE ) return false;


when I do

VL53L0X_RangingMeasurementData_t RangingMeasurementData;

if ( VL53L0X_GetRangingMeasurementData( Dev, &RangingMeasurementData ) != VL53L0X_ERROR_NONE ) return false;

the VL53L0X_GetRangingMeasurementData returns with VL53L0X_ERROR_NONE, the struct member "RangingMeasurementData.RangeStatus" is VL53L0X_ERROR_NONE,

but "RangingMeasurementData.RangeMilliMeter" is always 0x1FFF = 8191 (even with different distances to measure from 10 to 60 cm).


I found some old discussions ( e.g.: or but they do not work as solution.


So did I miss something?


Best Regards




ST Employee

something is odd. 

When you get RangingMeasurementData.RangeStatus not equal to 0, you generally get a range of 8192 minus the RangeStatus value. So your distance of 8191 should have corresponded with a RangeStatus =1. 

RangeStatus =1 is sigma failed. You are going to get this error if you demanded more accuracy that the number of photons can give. (it's a statistical process, so more photons gives a better answer.)

Try setting the sigma threshold higher. But 60 should have been high enough. 

At 10-60 cm, you should have no trouble. Especially if you use a normal target. (I always use white paper when starting out as I know it will return lots of photons.)

Could you verify that the sensor is running. Use a camera to look for the flashing. (Don't use an Iphone though. That I/R filter is too good.)

you didn't leave the protective film on did you? That could cause the sigma to go really high. 

could you send me the full structure of what you got back. And a description of what the sensor was looking at?

Or use a sheet of white paper as a target and dump the return struct. 

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. It helps the next guy.

Hi John

thanks for reply.

The values are:

TimeStamp: 0

MeasurementTimeUsec: 0

RangeMilliMeter: 8191

RangeDMaxMilliMeter: 0

SignalRateRtnMegaCps: 0x1fffe00

AmbientRateRtnMegaCps: 0x1fffe00

EffectiveSpadRtnCount: 0xffff

ZoneId: 0

RangeFractionalPart: 0

RangeStatus: 0

I removed the protective film (I thought this would be the reason)...


ST Employee

Those results make no sense. You simply cannot have an 8191 range and a RangeStatus of 0. So I'm thinking there is something wrong with your I2C interface. You think you are issuing commands but they might be byte-swapped or work swapped. All byte values are fine, but a word swap would be a huge issue. 

When you took that picture did you see the flash of the laser? (Remember, don't use an Iphone.)

I'm betting the sensor is not on, and you are reading non-sense. 

I have a bit of code to validate the byte and word swap, but it's written for the VL53L1X sensor. Perhaps you could adapt it. It is supposed to read the part ID, and then read and write values with differing byte-lengths to verify the access. 

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. It helps the next guy.
Associate II

Hello John,

Thanks for your reply.

To remove the possibility that my hardware is NOK, I bought a X-NUCLEO-53L0A1 board.

But unfortunately I had to realize that the 53L0 is not supported by X-CUBE-TOF1 software. Is there a plan to support it in future?

In addition the old STM32CubeExpansion_VL53L0X_V1.2.0 package is not usable with STM32CubeIDE 1.14 (incompatible driver defines, many  compile errors, missing BSP files etc.).

Thus what would really help is a functioning sample software on

* hardware X-NUCLEO-53L0A1 + NUCLEO-L476RG (or better NUCLEO-WB55RG for me)

* development environment STM32CubeIDE 1.14 (I will go to 1.15.1 soon)

Today, a customer cannot use the 53L0 as component without heavy low level development...

Best regard