vl53l8cx Status always 0 but Distance works and is always different
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?
