Skip to main content
Associate
August 3, 2026
Question

VL53L4CX calibration value instability

  • August 3, 2026
  • 4 replies
  • 41 views

Hello, we have obtained some VL53L4CX sensors and are having a hard time calibrating them. We have created a 3D printed test jig which positions the sensor exactly 100mm away from a 17% greycard as instructed by the datasheet. We’re running the ULD driver. It all appears to work correctly, but now we would like to calibrate the offset and xtalk. The methods run correctly but the returned values appear to shift over time and between runs. We modified the ULD driver to inject debugging statements to see the measured values. Attached are 4 different runs showing how the values have some trend/wave pattern to them, which biases the averaging and results in a wrong computed offset, and one that changes over time. This calibration is done inside a box which is in near absolute darkness so it’s not ambient light that’s affecting it.

 

 

Advise would be highly appreciated, as this is a major blocker to our product thus far.

 

Best regards

4 replies

ST Technical Moderator
August 21, 2026

Hi,

According to   UM2923 (A guide to using the VL53L4CX Time-of-Flight sensor with extended distance measurement - User manual), a complete VL53L4CX customer factory calibration   should be performed in   three steps, and the order is important:

1.   RefSPAD calibration   
2.   Xtalk calibration   
3.   Offset calibration  

So, the sequence is:

  RefSPAD → Xtalk → Offset  

 1. complete calibration flow

After power-up, the standard initialization should be:

VL53LX_WaitDeviceBooted();
VL53LX_DataInit();
   
Then run the three calibrations in the following order:

VL53LX_PerformRefSpadManagement();
VL53LX_PerformXTalkCalibration();

VL53LX_PerformOffsetSimpleCalibration(...); or VL53LX_PerformOffsetPerVCSELCalibration(...);
   

After calibration, the results should be retrieved and stored on the host side:

VL53LX_GetCalibrationData();

At every next startup, instead of recalibrating, the saved calibration data should be reloaded after  DataInit()  using:

VL53LX_SetCalibrationData();
   

Please also note that the calibration flow changes the distance mode internally, so if the sensor is used immediately after calibration, it is mandatory to call: VL53LX_SetDistanceMode() again, before normal ranging.

2. RefSPAD calibration

RefSPAD calibration optimizes the number and location of SPADs used by the device. 
ST recommends performing it in the final product configuration, especially if a cover glass is present.

Setup
No special target is needed. 
The only requirement is: No target in front of the sensor  

Function

VL53LX_PerformRefSpadManagement(&Dev);

This step must be executed first.

3. Xtalk calibration

Xtalk calibration compensates for the parasitic signal caused by internal reflections in the cover glass.

Required setup
According to   UM2923  , Xtalk calibration should be performed with:

-   17% grey target  
-   600 mm distance  
-   Dark environment  
-   No IR contribution  

Function

VL53LX_PerformXTalkCalibration(&Dev);

This step must be executed   after RefSPAD calibration   and   before offset calibration .

Important note
Xtalk compensation is   disabled by default  , so after calibration or after loading saved calibration data, it should be explicitly enabled:

VL53LX_SetXTalkCompensationEnable(&Dev, 1);

4. Offset calibration

Offset calibration compensates for the distance shift introduced by PCB soldering, mechanical assembly, and/or cover glass integration.

Required setup
For offset calibration, the setup is more flexible:

-   Any chart reflectance  
-   Any known distance  
-   Dark environment / no IR contribution  

However, one important condition must be respected: 2MCps<Signal Rate<80MCps
So the target distance and reflectance can be chosen freely, as long as the measured signal rate stays within this range.

Function:
Standard offset calibration:

VL53LX_PerformOffsetSimpleCalibration(&Dev, CalDistanceMilliMeter);

More accurate per-VCSEL offset calibration:

VL53LX_PerformOffsetPerVCSELCalibration(&Dev, CalDistanceMilliMeter);
   
Recommendation
The   PerVCSEL   method is recommended by default because it provides better accuracy, although it takes longer.

If this method is used, the correction mode must also be set explicitly:

VL53LX_SetOffsetCorrectionMode(&Dev, VL53LX_OFFSETCORRECTIONMODE_PERVCSEL);
   
If the simple offset calibration is used instead, then the mode should be:

VL53LX_SetOffsetCorrectionMode(&Dev, VL53LX_OFFSETCORRECTIONMODE_STANDARD);
   

5. Saving and reloading calibration data

After all three calibration steps are completed, the full calibration structure should be read back and stored in host non-volatile memory:

VL53LX_GetCalibrationData(&Dev, &cal_data);
   
At each next power-up, the recommended startup flow is:
VL53LX_WaitDeviceBooted();
VL53LX_DataInit();
VL53LX_SetCalibrationData(&Dev, &cal_data);
VL53LX_SetXTalkCompensationEnable(&Dev, 1);
VL53LX_SetOffsetCorrectionMode(&Dev, VL53LX_OFFSETCORRECTIONMODE_PERVCSEL); // if per VSCEL offset was used
VL53LX_SetDistanceMode(&Dev, ...);
   
This avoids repeating the factory calibration every time.

6. Important practical notes

A few common points to pay attention to:

- The calibration order must remain   RefSPAD → Xtalk → Offset  
- If calibrations are done individually, the previous calibration data must be loaded first
- Xtalk compensation is   not automatically enabled  
- Offset correction mode is   not automatically selected  
- After calibration,  distance mode must be set again  
- For offset calibration, the key condition is not the absolute distance itself, but keeping the signal rate within the valid range

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.
zek_krisAuthor
Associate
August 21, 2026

Hello,

 

Thank you for your response. When you say no target in front of the sensor what does that actually entail? A specific distance in front of the sensor or over the sensor’s maximum range (for this one 6m). Would then pointing it up at the sky suffice or does it need to be in dark conditions?

 

Our current test setup consists of a dark box in which the sensor is positioned exactly 100mm away from a 17% greycard.

 

Best regards.

 

zek_krisAuthor
Associate
August 21, 2026

After doing this calibratio (with refspad pointing at nothing), results improved somewhat however we still see this waveform repeat every time we start the sensor up. 

 

ST Technical Moderator
August 25, 2026

Hello,

Thank you for your feedback.

Regarding the behavior you observed, please find below a few clarifications:

  1. RefSPAD calibration and Xtalk calibration are typically part of the same complete factory calibration flow.
    Since different customers may use different mechanical assemblies and different cover glass configurations, calibration is recommended in the final product setup.
    In this flow, RefSPAD calibration must be performed first, and one of its purposes is to prepare the device configuration for the subsequent Xtalk calibration step.

  2. RefSPAD calibration requires no target in front of the sensor.
    In practice, this means that during the RefSPAD calibration step, there should be no intended close target in front of the sensor, and no significant target return should be present in the effective field of view. the setting of Xtalk calibration (17% grey target,600 mm distance, Dark environment, No IR contribution) is ok for RefSPAD calibration, just make sure there are no targets within a range of 100mm.

  3. It is recommended to treat calibration and normal ranging as two separate phases.
    A typical flow is the following:

Step 1: Perform RefSPAD calibration and Xtalk calibration, then read back and store the calibration data

Step 2: Perform Offset calibration, then store the corresponding offset data

At this point, the calibration phase is complete

Step3: At the next power-up, the recommended approach is to reload the saved calibration data instead of repeating the full calibration flow.

The recommended startup sequence is:

VL53LX_WaitDeviceBooted();

VL53LX_DataInit();
VL53LX_SetCalibrationData(&Dev, &cal_data);
VL53LX_SetXTalkCompensationEnable(&Dev, 1);
VL53LX_SetOffsetCorrectionMode(&Dev, VL53LX_OFFSETCORRECTIONMODE_PERVCSEL); // if per-VCSEL offset was used
VL53LX_SetDistanceMode(&Dev, ...);

 

Hope this 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.