cancel
Showing results for 
Search instead for 
Did you mean: 

vl53l8cx Status always 0 but Distance works and is always different

AA.16
Associate III

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?

1 ACCEPTED SOLUTION

Accepted Solutions

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


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. It helps the next guy.

View solution in original post

3 REPLIES 3
John E KVAM
ST Employee

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


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. It helps the next guy.
AA.16
Associate III

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:

 

Screenshot_15.png

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.

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


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. It helps the next guy.