cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L3 measured distance decreases when object distance increases

Tvan .13
Associate III

I use a VL53L3 with the STSW-IMG033 Ultra Low Power API.

I use the settings in the settings mentioned in AN5769 "Using the VL53L3CX under ultralow-power mode" for maximum detection under daylight:

Full ROI
Macro period 200
Signal limit 1500
Sigma limit 60
Valid distance 400mm
Using interrupt mode: generate only an interrupt when these criteria are met

I need reliable detection of a human standing in front of the sensor at max 400mm.

Without any cover, the sensor functions just right.

WIth a cover glass (I used the cover glass shipped with the VL53L3 Nucleo addon) I get strange results.
The reason I used this cover glass for this test is that it is shipped by ST to use with their reference design.

Upto about 200 mm the measurement is quite reliable. 
When the object distance is increased, the measured distance starts to decrease. Becasue of this I get "valid measurement" interrupts upto 1200mm.

With another cover, the measurement can be 400mm at a distance of about 200mm so the total range is decreased a lot.

I tried a lot of parameter variations, but it does not get better.

 

My question:

1. How can I get a more reliable distance measurement of upto 400 mm (and not beyond) ?
2. How is it possible that a TOF sensor produces a decreasing distance measurement while the actual distance increases?
3. How is it possible that another cover glass can reduce the measured distance so much?

Please note that the ULP API does not provide anything like RefSPADS/Xtalk/Offset calibration options.
And as my core processor has 8K words of flash, the full blown API is no option, also not because of current requirements.

 

1 ACCEPTED SOLUTION

Accepted Solutions
John E KVAM
ST Employee

It’s a classic case of crosstalk.

There are photons hitting your coverglass and bouncing back.

 

For example, let’s say 100K photons do this.

With a close object you get say 20M photons at 285mm.

That 200K at zero averaged with 20M photons at 285 averages to 282. No big issue.

But let move your target farther away.

Because light dissipates as a square of the distance you will now be getting

0.5M photons at 750mm.

And you have to still average in that 200K at 0.

And 500*750/700 = 535. Now you are significantly short. And it gets worse.

Based on your complaint, I think your crosstalk is a lot worse than 200K.

Your solution is to do the crosstalk calibration. It’s in the user manual for your sensor.

 

Or you can make a better coverglass.

Move the sensor closer to the glass. Make the glass thinner. Make it more optically clear.

Or you can place a gasket between the TX side of the sensor and the RX side.

But the best solution is to place an opaque barrier between the two sides.

But start with the crosstalk calibration. See if that fixes you right up.

Note that the VL53L3 has crosstalk issue until about 80cm. After that the crosstalk does not interfere. Beyond 80cm the zero-distance photons are distinguishable from the target. 

But there is a limit to crosstalk correction. Every photon that bounces back from the glass is one that does not hit the target. So having a quality glass is a must. 

  • 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.

View solution in original post

11 REPLIES 11
John E KVAM
ST Employee

It’s a classic case of crosstalk.

There are photons hitting your coverglass and bouncing back.

 

For example, let’s say 100K photons do this.

With a close object you get say 20M photons at 285mm.

That 200K at zero averaged with 20M photons at 285 averages to 282. No big issue.

But let move your target farther away.

Because light dissipates as a square of the distance you will now be getting

0.5M photons at 750mm.

And you have to still average in that 200K at 0.

And 500*750/700 = 535. Now you are significantly short. And it gets worse.

Based on your complaint, I think your crosstalk is a lot worse than 200K.

Your solution is to do the crosstalk calibration. It’s in the user manual for your sensor.

 

Or you can make a better coverglass.

Move the sensor closer to the glass. Make the glass thinner. Make it more optically clear.

Or you can place a gasket between the TX side of the sensor and the RX side.

But the best solution is to place an opaque barrier between the two sides.

But start with the crosstalk calibration. See if that fixes you right up.

Note that the VL53L3 has crosstalk issue until about 80cm. After that the crosstalk does not interfere. Beyond 80cm the zero-distance photons are distinguishable from the target. 

But there is a limit to crosstalk correction. Every photon that bounces back from the glass is one that does not hit the target. So having a quality glass is a must. 

  • 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.

Thank you for the extensive reply.

I have some restrictions as mentioned:
- I have to stay with the VL53L3 ULP API as my core has no flash for the full API
- therefore the crosstalk calibration is no option, the ULP API does not support that
- The cover glass used for testing is borrowed from the Nucleo VL53L3 demo so I'd expect high transparency
- The production cover glass is manufactured especially for infrared communication applications.

 

What you write makes sense. Although for me it is still hard to grasp that, when measuring time of flight, these "valid detections" happen when the range is way further than the limit.

Anyway, I designed and 3d printed a cover gasket with 2 holes to fill the gap between the VL53L3 and the cover glass. The hole size does matter so it seems. When I take the exclusion cones from the datasheet, take the 2mm distance between sensor and cover glass and calculate the hole diameter at 2 mm, then the crosstalk still appears to happen. The detection is not cut off at the physical distance limit, but this unwanted effect is less, as expected.

Making the holes smaller makes the crosstalk effects disappear. Positive side effect is that the field of view is narrowed, which is good in my application.

My answer is more elaborate than "thanks, a gasket works" because I struggled a lot to get the detections reliable. And most probably others could benefit.

 

Thank you, a gasket works :)

John E KVAM
ST Employee

Even though you have a solution, you mentioned that having a narrower field of view would be better. 

We have a VL53L4CX which is the same chip, but with an 18-degree FoV. Software is the same - once you get past the different ChipID. 

I might also suggest you can do crosstalk testing on a few of your parts as they come off the line. Then switch over to the real software and put those numbers in your entire production run. 

Or you can just take a guess at your crosstalk numbers and use that. If you still have the issue, increase the crosstalk number until your under-ranging just goes away. 

If you do it this way, make sure your glass quality is good and the air gap between sensor and glass is consistent.

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

During a small production series it appear that still something extra is required in order to get the product reliable.

Crosstalk calibration or entering general values that match this setup appears to be necessary.

What I make of your suggestion about guessing numbers is that that would be just a handful of variables. The GUI application also suggests a handful of numbers.

When I look at the full API, the caldata struct is this (used by VL53LX_SetCalibrationData):

typedef struct {

uint32_t struct_version;

VL53LX_CustomerNvmManaged_t customer;

VL53LX_additional_offset_cal_data_t add_off_cal_data;

VL53LX_optical_centre_t optical_centre;

VL53LX_xtalk_histogram_data_t xtalkhisto;

VL53LX_gain_calibration_data_t gain_cal;

VL53LX_cal_peak_rate_map_t cal_peak_rate_map;

VL53LX_per_vcsel_period_offset_cal_data_t per_vcsel_cal_data;

uint32_t algo__xtalk_cpo_HistoMerge_kcps[VL53LX_BIN_REC_SIZE];

} VL53LX_CalibrationData_t;

 

I have been looking quite extensively into this, but this structure is huge.

Which variables and/or VL53L3 registers actually contain the  relevant crosstalk, refSPAD and offset calibration data?

So I know which vaules from the structure to extract in the test setup, and in which registers I write them in my small firmware.

The easiest way to go is to buy the P-Nucleo-53L3A1 evaluation kit and use that to simulate your device. (In the US it's only $56 dollars and ST is a European company, it should be available at your parts distributor.)

Take your coverglass, and using the spacers provided, simulate your air gap. 

Use the GUI to do the crosstalk test and have a look at the results. 

You will end up with a file that looks like this:

[GENERAL_INFO]
RANGING_MODE=Ranging
REF_SPADS_CALIBRATED=True
XTALK_CALIBRATED=True
OFFSET_CALIBRATED=True
[REF_SPADS]
REF_SPADS_CAL_STATUS=0
REF_SPAD_ENABLES=BF EF FF FF 6F 0F
REF_SPAD_ENABLE_COUNT=7
REF_SPAD_LOCATION=1
[OFFSET]
OFFSET_CAL_STATUS=0
INNER_OFFSET=18
OUTER_OFFSET=18
REF_PEAK_SIGNAL_RATE=0
REF_ACTUAL_EFF_SPADS=0
REF_DISTANCE=0
REF_REFLECTANCE=0
COVERGLASS_TRANSMISSION=0
HISTO_GAIN_FACTOR=0.986328
STD_RANGING_GAIN_FACTOR=0.981934
[XTALK]
XTALK_CAL_STATUS=0
XTALK_PLANEOFFSET_KCPS=13.00586
XTALK_XPLANE_GRADIENT_KCPS=0
XTALK_YPLANE_GRADIENT_KCPS=0
XTALK_SHAPE_ZONE_ID=0
XTALK_SHAPE_TIMESTAMP=0
XTALK_SHAPE_FIRST_BIN=0
XTALK_SHAPE_BUFFER_SIZE=12
XTALK_SHAPE_NUMBER_OF_BINS=12
XTALK_SHAPE_PHASE_CAL_RESULT_REF_PHASE=5.208984
XTALK_SHAPE_PHASE_CAL_RESULT_VCSEL_START=6
XTALK_SHAPE_CAL_CONFIG_VCSEL_START=9
XTALK_SHAPE_VCSEL_WIDTH=2.5
XTALK_SHAPE_FASTOSC_FREQUENCY=11.80981
XTALK_SHAPE_ZERO_DISTANCE_PHASE=2.208984
XTALK_SHAPE_BIN_DATA=0 0.378906 0.436523 0.18457 0 0 0 0 0 0 0 0

The XTALK_SHAPE_BIN_DATA is the number of photons received from the coverglass - normalized.)

The XTALK_PLANEOFFSET_KCPS is the scale factor. Increase or decrease as you wish. This is the adjustment. 

The RefSpad cal can be run every bootup. The offset needs to be done on every part for absolute accuracy, but you can skip that as well if you want to. 

But if you can get your eval system to be pretty close to your actual system, you can use the Xtalk numbers you get and use those.

If you are still not satisfied, with the results, then increase the XTALK_PLANEOFFSET_KCPS=13.00586 value and leave the rest alone. 

 

But consider increasing the quality of your coverglass. Read the article:

https://community.st.com/t5/mems-and-sensors/time-of-flight-cover-glass/ta-p/49259

With an OK coverglass you might noticed you are under-ranging, but if the numbers are going down, you have a pretty bad coverglass configuration. You are making the problem kind of hard.

And it really will cut down on how far you can range.


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.

Using the P-Nucleo-53L3A1 and the GUI is exactly what I planned to do.
Use one of the side sensor PCB's and replace the sensor on the breakout board with a sensor mounted on my own PCB. That way I can mount it exactly the way it is going to be used.

I read the article about the cover glass. The result that I am getting is basically identical to the results I get with the cover glass of the P-Nucleo-53L3A1 kit. But I'll double check on that.

So if I understand properly, XTALK_PLANEOFFSET_KCPS is the only parameter I have to adjust if I am not satisfied with the crosstalk results, correct?

What I plan to do is to have a grey reflective object at a set distance (100mm), compare with the average measured distance and then use the difference as offset value. 

Are the registers INNER_OFFSET and OUTER_OFFSET the ones to write the new offset value to?
Or are there other parameters involved for the offset calibration?

 

John E KVAM
ST Employee

The INNER and OUTER offsets will be the same for the VL53L3. (It's in there for the VL53L1 - which has a lens).

Make them the same. 

Once you have the shape:

XTALK_SHAPE_BIN_DATA=0 0.378906 0.436523 0.18457 0 0 0 0 0 0 0 0

you need only to change the XTALK_PLANEOFFSET_KCPS to increase or decrease the crosstalk.

And note, you can do the crosstalk measurement simply by pointing the sensor straight up - assuming you have a ceiling a couple of meters away or so.

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

I did the calibration using the P-Nucleo-53L3A1 and the GUI.
Also I validated the effects of the calibration and the result is a proper distance measurement. So far so good.

And dug deep in the full API to see where which variables should be written in the VL53L3.

INNER_OFFSET goes to register VL53LX_MM_CONFIG__INNER_OFFSET_MM (address 0x0020-0x0021)
OUTER_OFFSET goes to register VL53LX_MM_CONFIG__OUTER_OFFSET_MM (address 0x00220x0023) 
tested this and the offset of the measurement actually changes accordingly.

I think.XTALK_PLANEOFFSET_KCPS must go to register VL53LX_ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS (address 0x0016-0x0017) 

But in which registers do I write the XTALK_SHAPE_BIN_DATA ?

 

John E KVAM
ST Employee

I think you might be working too hard. We have a function that writes the calibration for you. 

VL53LX_Error VL53LX_SetCalibrationData(VL53LX_DEV Dev,
		VL53LX_CalibrationData_t *pCalibrationData)

Just populate what you want in the calibration structure, and call this. 

Otherwise you are going to get wrapped up in what format we use to right floating-point data as integers. 

You don't want to go there. It's too hard. 

Just fill in the structure with what you have and put zeros in for the rest. 

then call the function. 

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