2024-02-23 05:49 AM - edited 2024-02-23 06:00 AM
Hello,
i have managed to get the vl53l8cx to run and it returns correct measurements. with the occasional wrong distance. i wanted to take advantage of the "Status" values to throw out bad measurements. however my status prints are always 0.
here is my code:
//begin a test measurement
int32_t s;
uint8_t frequency_hz;
vl53l8cx_get_ranging_frequency_hz(&conf, &frequency_hz);
uint32_t delay_frequency = 1000 / frequency_hz;
VL53L8CX_Start(&pObj, VL53L8CX_MODE_ASYNC_CONTINUOUS);
HAL_Delay(delay_frequency); // needs time for one measurement at least!
s = VL53L8CX_GetDistance(&pObj, &pResult);
// If unsuccessful, log the attempt
if (s != 0) {
APP_LOG(TS_ON, MDS_VLEVEL, "[ToF] Measurement attempt failed with status %d\n", s);
ToF_Disable_Measurement_Circuit();
ToF_Deinit_Measurement_Circuit();
return;
}
VL53L8CX_Stop(&pObj);
uint32_t mm;
APP_LOG(TS_ON, MDS_VLEVEL, "[ToF] Distance\n");
for (uint32_t var = 0; var < VL53L8CX_MAX_NB_ZONES; ++var) {
// Print each number with a width of 4 characters, right-aligned
mm = *(pResult).ZoneResult[var].Distance;
if ((mm/10) < 255) {
buffer[var] = mm/10;
}else{
buffer[var] = 255;
}
APP_LOG(TS_OFF, MDS_VLEVEL, "%4d ", mm);
if ((var + 1) % 8 == 0) {
APP_LOG(TS_OFF, MDS_VLEVEL, "\n");
}
}
APP_LOG(TS_ON, MDS_VLEVEL, "[ToF] Status\n");
uint32_t stat;
for (uint32_t var = 0; var < VL53L8CX_MAX_NB_ZONES; ++var) {
stat = *(pResult).ZoneResult[var].Status;
APP_LOG(TS_OFF, MDS_VLEVEL, "%3d ", stat);
if ((var + 1) % 8 == 0) {
APP_LOG(TS_OFF, MDS_VLEVEL, "\n");
}
}
APP_LOG(TS_ON, MDS_VLEVEL, "[ToF] pObj->IsSignalEnabled %d\n", pObj.IsSignalEnabled);
float_t sig;
for (uint32_t var = 0; var < VL53L8CX_MAX_NB_ZONES; ++var) {
sig = *(pResult).ZoneResult[var].Signal;
int32_t fixed_point_sig = (int32_t) (sig * 1000); // Cast to integer and multiply by 1000
int32_t whole_part = fixed_point_sig / 1000; // Extract whole part
// int32_t fractional_part = fixed_point_sig % 1000; // Extract fractional part // was always 0
APP_LOG(TS_OFF, MDS_VLEVEL, "%3d ", whole_part);
if ((var + 1) % 8 == 0) {
APP_LOG(TS_OFF, MDS_VLEVEL, "\n");
}
}
APP_LOG(TS_ON, MDS_VLEVEL, "[ToF] pObj->IsAmbientEnabled %d\n", pObj.IsAmbientEnabled);
float_t amb;
for (uint32_t var = 0; var < VL53L8CX_MAX_NB_ZONES; ++var) {
amb = *(pResult).ZoneResult[var].Ambient;
int32_t fixed_point_amb = (int32_t) (amb * 1000); // Cast to integer and multiply by 1000
int32_t whole_part = fixed_point_amb / 1000; // Extract whole part
// int32_t fractional_part = fixed_point_amb % 1000; // Extract fractional part // was always 0
APP_LOG(TS_OFF, MDS_VLEVEL, "%3d ", whole_part);
if ((var + 1) % 8 == 0) {
APP_LOG(TS_OFF, MDS_VLEVEL, "\n");
}
}
i am doing an example measurement. and then print the values
here is one possible output:
14:45:09.170 -> 300s317:[ToF] Device found at address: 0x52
14:45:19.401 -> 310s551:[ToF] vl53l8cx_get_ranging_mode 3
14:45:21.823 -> 312s854:[ToF] Distance
14:45:21.823 -> -7 733 752 760 752 739 726 760
14:45:21.823 -> -22 750 771 745 712 758 765 740
14:45:21.823 -> 761 744 740 753 751 759 725 736
14:45:21.823 -> 751 741 748 776 750 742 748 737
14:45:21.823 -> 717 739 751 764 748 746 731 754
14:45:21.823 -> 719 739 731 735 735 742 741 755
14:45:21.823 -> 733 737 755 759 735 724 731 732
14:45:21.823 -> 702 749 740 748 725 743 749 710
14:45:21.823 -> 312s856:[ToF] Status
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 0 0 0 0 0 0 0 0
14:45:21.823 -> 312s859:[ToF] pObj->IsSignalEnabled 1
14:45:21.823 -> 212 15 13 15 16 16 14 20
14:45:21.823 -> 28 16 15 15 14 16 18 14
14:45:21.823 -> 16 22 18 16 15 14 15 16
14:45:21.823 -> 15 16 16 15 16 20 22 21
14:45:21.823 -> 22 13 15 14 14 13 16 17
14:45:21.823 -> 21 21 16 16 13 16 17 14
14:45:21.823 -> 23 18 15 18 13 13 20 13
14:45:21.823 -> 27 17 15 17 17 19 22 15
14:45:21.823 -> 312s861:[ToF] pObj->IsAmbientEnabled 1
14:45:21.823 -> 1 1 0 1 0 1 2 0
14:45:21.823 -> 1 1 1 2 1 1 1 0
14:45:21.823 -> 1 1 1 2 0 0 0 0
14:45:21.823 -> 1 1 0 0 1 2 1 0
14:45:21.823 -> 1 2 0 0 0 1 1 1
14:45:21.823 -> 1 0 0 2 2 1 1 0
14:45:21.823 -> 1 1 0 0 0 1 2 2
14:45:21.823 -> 0 0 0 1 1 0 1 0
this code is called in a loop and if it runs again it will print different values. Also notice how some distance values are negative ... thats not possible :D
When setting up the code i had a status print that made sense. however i cant reproduce it. i changed all settings: here are some i tried. no change to status prints.
VL53L8CX_PROFILE_8x8_CONTINUOUS
VL53L8CX_RANGING_MODE_AUTONOMOUS
i need it to be 8x8.
EDIT:
I found the problem. the API is using this code:
static uint8_t vl53l8cx_map_target_status(uint8_t status) {
uint8_t ret;
if ((status == 5U) || (status == 9U)) {
ret = 0U; /* ranging is OK */
} else if (status == 0U) {
ret = 255U; /* no update */
} else {
ret = status; /* return device status otherwise */
}
return ret;
}
which threw me off since i was looking into the datasheet where a status 0 means that the value has not been updated. if i remove the mapping and just print the status itself. it always prints a 5. even for the negative values that are obviously wrong. So my questions is now. why the ngeative value and why can't i use the status to know if a value is bad?
Solved! Go to Solution.
2024-02-26 07:29 AM
When the sensor does not return a 5, a 6 or a 9 as status, the PC software does not plot it.
How to tell?
Use the logging feature. Turn logging on. Record a few frames, and stop the sensor.
There are two ways to look at the data.
If you simply click on the log file (you get there by clicking on the Log tab) you will open a log analysis window. It's pretty cool and you should try it.
You can also open the file with windows Excel. That way you can search through the data. There is one line for each zone and a header 'zone'.
You really should dig into the data.
- john
2024-02-23 07:41 AM
Some people just cannot stand a good status being anything other than 0. Unfortunately, this helpful bit of code gets you farther away from the data sheet.
I'm going to guess you have something in the upper left of the sensor. If an object is really close, it can appear to be outside the FoV and you still see it.
The reason is that the light is supposed to go out in a 45 degree pyramid. But light doesn't really work like that. At 45 degrees you have full strength, and the intensity of the light falls off rapidly, so that at 60, 70 and 80 degrees the light diminishes, but there still is some. And if you have a reflective surface that light will come sneaking in.
Notice all your signal strengths are in the teens and twenties. Except for the upper left. That signal is huge.
There is something there.
and good job solving your issue.
- john
2024-02-26 07:18 AM
I've recently discovered that during my test of the Time of Flight (ToF) sensor from my table to the ground, the sensor was positioned away from the table, facing downwards. While conducting the measurement, my knee was in close proximity, causing a variation in the measurement at the top left corner. Ideally, it should have displayed a distance of 250mm rather than a negative value of -2mm.
i also noticed that sometimes the "VL53L8CX_GUI" shows not all measurements:
As you can see where the LOGO "Flight Sense" is shown there are no measured pixels. I think the GUI software somehow evaluates which pixels have high confidence and which have little confidence. What is driving the decision? I think i would be fine if i could just use the same values as this example software.
2024-02-26 07:29 AM
When the sensor does not return a 5, a 6 or a 9 as status, the PC software does not plot it.
How to tell?
Use the logging feature. Turn logging on. Record a few frames, and stop the sensor.
There are two ways to look at the data.
If you simply click on the log file (you get there by clicking on the Log tab) you will open a log analysis window. It's pretty cool and you should try it.
You can also open the file with windows Excel. That way you can search through the data. There is one line for each zone and a header 'zone'.
You really should dig into the data.
- john