2022-08-05 02:13 PM
Hi ST Team,
I just integrated ULD driver of VL53L1X but it keeps returning range status: 4. What could be the problem?
Settings:
Timing: 100
Inter Measurement: 100
Distance Mode: Short
ROI: 16x16
Signal: Default ( 1026 something )
Sigma: 90
The I2C communication is tested to be working correctly and I’m successfully able to get all the reference register values. I don’t know why it keeps returning range status 4.
2022-08-05 02:45 PM
A status 4 is a "phase error". In order to detect something called Radar Aliasing, we actually do two ranges with different pulse repetition intervals. And these ranges do NOT return the same range.
I'm going to guess that if you use a larger target or a more reflective one, you will get a status = 0.
At whatever size and range you are using, it is past the limit of what the sensor can 'see'.
Moving in a bit will make the problem go away as well.
2022-08-05 03:08 PM
If the problem is resolved, please mark this topic as answered by selecting Select as best. This will help other users find that answer faster.
2022-08-06 01:38 AM
@John E KVAM
Thanks for the quick reply!
I've tried different lengths ( 750mm ~ 250mm ) and target reflectances ( Marble, Black Tile, Hand, and Cloth ), In all of the cases it returns a range status 4 which is pretty weird, I've worked with VL53L0X in past and it was far reliable than this sensor.
Here's how the code is behaving ( I'm attaching my test code below :(
It tries to do 10 samples in a loop.
1st Reading: Range Status 4
2nd Reading: Stuck... It can't get the data ready flag again
Do you still think it could be due to radar aliasing?
static void get_tof_reading() {
uint8_t res = 0;
uint8_t byteData, sensorState=0;
uint16_t wordData;
res = VL53L1_RdByte(TOF_I2C_ADDRESS, 0x010F, &byteData);
LOG(LVL_INFO, "VL53L1X Model_ID res:%d: 0x%X\n\r", res, byteData);
res = VL53L1_RdByte(TOF_I2C_ADDRESS, 0x0110, &byteData);
LOG(LVL_INFO, "VL53L1X Module_Type res:%d: 0x%X\n\r", res, byteData);
res = VL53L1_RdWord(TOF_I2C_ADDRESS, 0x010F, &wordData);
LOG(LVL_INFO, "VL53L1X - res:%d: 0x%X\n\r", res, wordData);
while(sensorState==0){
VL53L1X_BootState(TOF_I2C_ADDRESS, &sensorState);
VL53L1_WaitMs(TOF_I2C_ADDRESS, 2);
}
LOG(LVL_INFO, "Chip booted\n\r");
res = VL53L1X_SensorInit(TOF_I2C_ADDRESS);
if(res == 0){
LOG(LVL_INFO, "Initialized ToF\n\r", res);
} else {
LOG(LVL_INFO, "Failed to initialize ToF - %d\n\r", res);
}
res += VL53L1X_SetDistanceMode(TOF_I2C_ADDRESS, 2);
// VL53L1X_SetDistanceThreshold(TOF_I2C_ADDRESS, 0, 1300, 3, 1);
res += VL53L1X_SetTimingBudgetInMs(TOF_I2C_ADDRESS, 33);
res += VL53L1X_SetInterMeasurementInMs(TOF_I2C_ADDRESS, 33);
// VL53L1X_SetSignalThreshold(TOF_I2C_ADDRESS, 256);
uint16_t signal_threshold;
res += VL53L1X_GetSignalThreshold(TOF_I2C_ADDRESS, &signal_threshold);
LOG(LVL_INFO, "ToF Signal Threshold: %u\n\r", signal_threshold);
// VL53L1X_SetSigmaThreshold(TOF_I2C_ADDRESS, 40);
uint16_t sigma_threshold;
res += VL53L1X_GetSigmaThreshold(TOF_I2C_ADDRESS, &sigma_threshold);
LOG(LVL_INFO, "ToF Sigma Threshold: %u\n\r", sigma_threshold);
int16_t offset;
res += VL53L1X_GetOffset(TOF_I2C_ADDRESS, &offset);
LOG(LVL_INFO, "ToF Offset: %i\n\r", offset);
// VL53L1X_SetROICenter(TOF_I2C_ADDRESS, 199);
// VL53L1X_SetOffset(TOF_I2C_ADDRESS, 20); /* offset compensation in mm */
res += VL53L1X_SetROI(TOF_I2C_ADDRESS, 8, 16); /* minimum ROI 4,4 */
uint8_t roi;
res += VL53L1X_GetROICenter(TOF_I2C_ADDRESS, &roi);
LOG(LVL_INFO, "ToF ROI Center: %u\n\r", roi);
// VL53L1X_CalibrateOffset(TOF_I2C_ADDRESS, 140, &offset); /* may take few second to perform the offset cal*/
// VL53L1X_CalibrateXtalk(TOF_I2C_ADDRESS, 1000, &xtalk); /* may take few second to perform the xtalk cal */
res += VL53L1X_StartRanging(TOF_I2C_ADDRESS);
if (res != 0) {
LOG(LVL_INFO, "Error in operating the device\n\r");
}
for (int i=0; i < 10; i++){
uint16_t SignalRate;
uint16_t AmbientRate;
uint16_t SpadNum;
uint8_t RangeStatus;
uint8_t dataReady = 0;
VL53L1X_ClearInterrupt(TOF_I2C_ADDRESS); /* clear interrupt has to be called to enable next interrupt*/
LOG(LVL_INFO, "Reading [%i]\n\r", i);
while (dataReady == 0) {
VL53L1X_CheckForDataReady(TOF_I2C_ADDRESS, &dataReady);
VL53L1_WaitMs(TOF_I2C_ADDRESS, 1);
}
VL53L1X_GetRangeStatus(TOF_I2C_ADDRESS, &RangeStatus);
VL53L1X_GetDistance(TOF_I2C_ADDRESS, &tof_reading);
VL53L1X_GetSignalRate(TOF_I2C_ADDRESS, &SignalRate);
VL53L1X_GetAmbientRate(TOF_I2C_ADDRESS, &AmbientRate);
VL53L1X_GetSpadNb(TOF_I2C_ADDRESS, &SpadNum);
VL53L1X_ClearInterrupt(TOF_I2C_ADDRESS); /* clear interrupt has to be called to enable next interrupt*/
LOG(LVL_INFO, "ToF Reading: R: %u, D: %u, %u, %u, %u\n\r", RangeStatus, tof_reading, SignalRate, AmbientRate, SpadNum);
}
VL53L1X_StopRanging(TOF_I2C_ADDRESS);
}
2022-08-06 01:58 AM
Here's the output:
2022-08-06 06:47 AM
@John E KVAM
My bad! I took a look at my platform file again, the RdByte function was correct that's why I was getting all the reference registers correctly but I was overwriting the I2C buffer in some functions ( RdWord & WrWord ). Resolving that issue fixed this range status 4 error. Hurray!
Now I'm getting results with approximately correct distance but it's all range status "2". Can you give me some insight on what could cause this?
2022-08-08 07:44 AM
Range status 2 is a:
"2 VL53L1_RANGESTATUS_SIGNAL_FAIL Raised if signal value is below the internal
defined threshold"
The status returns are in the API user manual which is delivered as part of the API when you download it.
Status 2 is the most common status when the sensor does not get enough photons to get a range. And it happens whenever there is no target, the target is too small, or the target is not reflective enough.
It's a good sensor but it's never going to spot knats at a thousand yards.
Place your hand in front of the sensor and slowly back up.
Use that data as sort of a reference.
Everyone is about 50% reflective at 940nm light, and for the most part hands are similar in size.
The data sheet states what the max range is, but the hand range is a more practical indicator.
2022-08-13 05:42 AM
Hi John,
The sensor does seem to be stable after the driver is implemented without any flaws. Thanks for the help!
Just a small question: The results are within + or - 15mm, Is this normal for short distance mode?
Regards,
Ayush
2022-08-15 07:19 AM
In order to shoot out enough light to reach 4Meters, the sensor generates way more that one needs for the very short distances. And physics gets involved as well.
If you know you are going to range a very short distance, setting the FoV to a 4x4 area in the center can help.
But you are correct in those accuracy numbers. (it's in the data sheet.)
You will find darker targets work better at the very short distances. As do matte finish ones.
But at the very short distances you are a bit at the mercy of the physics involved.
I've had better luck at the very short distances using the VL53L4CX. Oddly it's more accurate than the VL53L4CD. (And the CD is our 'close distance' sensor). The L4's have a different laser that works a touch better at short distances, and the Histogram mode of the software is an advantage.
Same footprint, and the code interface is almost identical, so switching my be an idea.