cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L8CX: Histograms manipulation and Interpretation.

kgb
Associate III

Hello Everyone,

I am currently working on a project to determine if it is possible to differentiate between a glass cup and other types of cups using VL53L8CX sensor data histograms, and also to detect the fill level. I have already collected data from the sensor using Example 12 provided in the Ultra Lite Driver, and I have written a small Python script to visualize my data.

My first challenge is switching between the 4x4 histogram data format and the 8x8 format. The second challenge is interpreting the incoming bins_data to understand the differences between, for example, a ceramic cup (which is already possible using just the distance data) and an empty glass cup (using the histogram data to make a distinction, detect the edge, and determine the fill level).  Here below is my code stmIDE  Code

//__________MY CODE ___________

 p_dev.platform.address = 0x52;


 Reset_Sensor();

 if (status != VL53LMZ_STATUS_OK){
 		printf("vl53lmz_init failed : %d\n");
 		return status;
 	}

	/* (Mandatory) Initialise the VL53LMZ sensor */
	status = vl53lmz_init(&p_dev);
	if(status)
	{
		printf("VL53LMZ ULD Loading failed\n");
		return status;
	}

	printf("VL53LMZ ULD ready ! (Version : %s)\n",
			VL53LMZ_API_REVISION);

	status = vl53lmz_set_resolution(&p_dev, 64);
	status |= vl53lmz_set_ranging_mode(&p_dev, VL53LMZ_RANGING_MODE_AUTONOMOUS);
	status |= vl53lmz_set_ranging_frequency_hz(&p_dev, 5);
	status |= vl53lmz_set_integration_time_ms(&p_dev, 20);
	if(status)
	{
		printf("ERROR - Failed basic configuration sequence, status=%u\n", status);
		return status;
	}

	status = vl53lmz_cnh_init_config( &cnh_config,
											0,		/* StartBin 	*/
											18,		/* NumBins   	*/
											4 );	/* SubSample 	*/

	if (status != VL53LMZ_STATUS_OK){
			printf("VL53LMZ CNH init config failed\n");
			return status;
		}

	status = vl53lmz_cnh_create_agg_map( &cnh_config,
												64,				/* Resolution. Must match value used in vl53lmz_set_resolution() */
												0,				/* StartX 		*/
												0,				/* StartY 		*/
												1,				/* MergeX		*/
												1,				/* MergeY		*/
												4,				/* Cols			*/
												4 );			/* Rows 		*/

	if (status != VL53LMZ_STATUS_OK){
			printf("VL53LMZ CNH set aggregate map failed\n");
			return status;
		}

	status = vl53lmz_cnh_calc_required_memory( &cnh_config, &cnh_data_size );
	if (status != VL53LMZ_STATUS_OK){
		printf("VL53LMZ CNH calc required memory failed\n");
		if (cnh_data_size < 0){
			printf("Required memory is too high : %d. Maximum is %d!\n", (int)-cnh_data_size, (int)VL53LMZ_CNH_MAX_DATA_BYTES);
		}
		return status;
	}


	/* Send this CNH configuration to the sensor.										*/
	status = vl53lmz_cnh_send_config(&p_dev,&cnh_config);
	if (status != VL53LMZ_STATUS_OK){
		printf("VL53LMZ CNH send config failed\n");
		return status;
	}

	/* First create the standard data upload(output) configuration. 						*/
	status = vl53lmz_create_output_config(&p_dev);
	if (status != VL53LMZ_STATUS_OK){
		printf("VL53LMZ CNH create output config failed\n");
		return status;
	}

	/* Next, add the CNH data block, sized correctly for the configuration we are using. */
	union Block_header cnh_data_bh;
	cnh_data_bh.idx = VL53LMZ_CNH_DATA_IDX;
	cnh_data_bh.type = 4;
	cnh_data_bh.size = cnh_data_size / 4;
	status = vl53lmz_add_output_block(&p_dev, cnh_data_bh.bytes);
	if (status != VL53LMZ_STATUS_OK){
		printf("VL53LMZ CNH add output block failed\n");
		return status;
	}

	status = vl53lmz_send_output_config_and_start(&p_dev);

	   	printf("Started ranging\n");



  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	   	while (1)

	   	{

	   		   		// __________________ MY CODE _______________
	   		   	    uint8_t buffer[512];
	   		   	    uint8_t *ptr = buffer;
	   		   	    size_t buffer_index = 0;  // To keep track of the actual size of the data

	   		   	    status = vl53lmz_check_data_ready(&p_dev, &isReady);
	   		   	    if (isReady)
	   		   	    {
	   		   	        vl53lmz_get_ranging_data(&p_dev, &Results);

	   		   	        printf("Print data no : %3u\n", p_dev.streamcount);
	   		   	        for (i = 0; i < 64; i++)
	   		   	        {


	   		   	            uint16_t zone = i;
	   		   	            uint16_t distance = Results.distance_mm[VL53LMZ_NB_TARGET_PER_ZONE * i];
                            /*
	   		   	            memcpy(ptr + buffer_index, &zone, sizeof(uint16_t));
	   		   	            buffer_index += sizeof(uint16_t);
	   		   	            memcpy(ptr + buffer_index, &distance, sizeof(uint16_t));
	   		   	            buffer_index += sizeof(uint16_t);
                             */
	   		   	           printf("Zone : %3d, Status : %3u, Distance : %4d mm\n",
	   		   	                   i,
	   		   	                   Results.target_status[VL53LMZ_NB_TARGET_PER_ZONE * i],
	   		   	                   distance);
	   		   	        }

	   		   	        status = vl53lmz_results_extract_block(&p_dev, VL53LMZ_CNH_DATA_IDX, (uint8_t *)cnh_data_buffer, cnh_data_size);
	   		   	        if (status != VL53LMZ_STATUS_OK)
	   		   	        {
	   		   	            printf("ERROR at %s(%d) : vl53lmz_results_extract_block failed : %d\n", __func__, __LINE__, status);
	   		   	            return status;
	   		   	        }

	   		   	        for (agg_id = 0; agg_id < cnh_config.nb_of_aggregates; agg_id++)
	   		   	        {
	   		   	            vl53lmz_cnh_get_block_addresses(&cnh_config,
	   		   	                                            agg_id,
	   		   	                                            cnh_data_buffer,
	   		   	                                            &(p_hist), &(p_hist_scaler),
	   		   	                                            &(p_ambient), &(p_ambient_scaler));

	   		   	            amb_value = ((float)*p_ambient) / (2 << *p_ambient_scaler);

	   		   	            printf("Agg, %2d, Ambient, % .1f, Bins, ", agg_id, amb_value);

	   		   	            for (bin_num = 0; bin_num < cnh_config.feature_length; bin_num++)
	   		   	            {
	   		   	                bin_value = ((float)p_hist[bin_num]) / (2 << p_hist_scaler[bin_num]);
	   		   	                printf("% .1f, ", bin_value);
	   		   	            }
                             /*
	   		   	            uint16_t Agg_id = agg_id;
	   		   	            float ambient = amb_value;
	   		   	            float bins_val = bin_value;

	   		   	            memcpy(ptr + buffer_index, &Agg_id, sizeof(uint16_t)); buffer_index += sizeof(uint16_t);
	   		   	            memcpy(ptr + buffer_index, &ambient, sizeof(float));  buffer_index += sizeof(float);
	   		   	            memcpy(ptr + buffer_index, &bins_val, sizeof(float)); buffer_index += sizeof(float);
                              */
	   		   	            // Now transmit only the actual data in the buffer
	   		   	            //HAL_UART_Transmit(&huart2, sizeof(buffer) , buffer, HAL_MAX_DELAY) ;

	   		   	            printf("\n");
	   		   	        }

	   		   	        loop++;
	   		   	    }

	   		   	    // Wait a few ms to avoid too high polling
	   		   	   // WaitMs(&(p_dev.platform), 5);
	   		   	    HAL_MAX_DELAY;
	   		   	}




}

 

 

 

And here is the example of what the sensor give me i only have bins_data for 16 zone and not 64 as expected and i am also thinking that i am getting wrong distance value

Zone :   0, Status :   5, Distance : 6472 mm

Zone :   1, Status :   5, Distance : 6716 mm

Zone :   2, Status :   5, Distance : 6678 mm

Zone :   3, Status :   5, Distance : 6662 mm

Zone :   4, Status :   5, Distance : 6486 mm

Zone :   5, Status :   5, Distance : 6526 mm

Zone :   6, Status :   5, Distance : 6516 mm

Zone :   7, Status :   5, Distance : 6535 mm

Zone :   8, Status :   5, Distance : 6475 mm

Zone :   9, Status :   5, Distance : 6506 mm

Zone :  10, Status :   5, Distance : 6513 mm

Zone :  11, Status :   5, Distance : 6556 mm

Zone :  12, Status :   5, Distance : 6577 mm

Zone :  13, Status :   5, Distance : 6559 mm

Zone :  14, Status :   5, Distance : 6597 mm

Zone :  15, Status :   5, Distance : 6622 mm

Zone :  16, Status :   5, Distance : 6474 mm

Zone :  17, Status :   5, Distance : 6529 mm

Zone :  18, Status :   5, Distance : 6611 mm

Zone :  19, Status :   5, Distance : 6613 mm

Zone :  20, Status :   5, Distance : 6623 mm

Zone :  21, Status :   5, Distance : 6630 mm

Zone :  22, Status :   5, Distance : 6650 mm

Zone :  23, Status :   5, Distance : 6650 mm

Zone :  24, Status :   5, Distance : 6527 mm

Zone :  25, Status :   5, Distance : 6596 mm

Zone :  26, Status :   5, Distance : 6641 mm

Zone :  27, Status :   5, Distance : 6702 mm

Zone :  28, Status :   5, Distance : 6720 mm

Zone :  29, Status :   5, Distance : 6732 mm

Zone :  30, Status :   5, Distance : 6709 mm

Zone :  31, Status :   5, Distance : 6673 mm

Zone :  32, Status :   5, Distance : 6592 mm

Zone :  33, Status :   5, Distance : 6598 mm

Zone :  34, Status :   5, Distance : 6687 mm

Zone :  35, Status :   5, Distance : 6731 mm

Zone :  36, Status :   5, Distance : 6744 mm

Zone :  37, Status :   5, Distance : 6730 mm

Zone :  38, Status :   5, Distance : 6745 mm

Zone :  39, Status :   5, Distance : 6735 mm

Zone :  40, Status :   5, Distance : 6591 mm

Zone :  41, Status :   5, Distance : 6644 mm

Zone :  42, Status :   5, Distance : 6705 mm

Zone :  43, Status :   5, Distance : 6768 mm

Zone :  44, Status :   5, Distance : 6799 mm

Zone :  45, Status :   5, Distance : 6789 mm

Zone :  46, Status :   5, Distance : 6790 mm

Zone :  47, Status :   5, Distance : 6804 mm

Zone :  48, Status :   5, Distance : 6610 mm

Zone :  49, Status :   5, Distance : 6667 mm

Zone :  50, Status :   5, Distance : 6754 mm

Zone :  51, Status :   5, Distance : 6766 mm

Zone :  52, Status :   5, Distance : 6789 mm

Zone :  53, Status :   5, Distance : 6815 mm

Zone :  54, Status :   5, Distance : 6749 mm

Zone :  55, Status :   9, Distance : 6716 mm

Zone :  56, Status :   5, Distance : 1542 mm

Zone :  57, Status :   5, Distance : 1646 mm

Zone :  58, Status :   5, Distance : 6635 mm

Zone :  59, Status :   9, Distance : 6472 mm

Zone :  60, Status :   5, Distance : 6491 mm

Zone :  61, Status :   5, Distance : 5826 mm

Zone :  62, Status :   5, Distance : 5588 mm

Zone :  63, Status :   9, Distance : 5293 mm

Agg,  0, Ambient,  1.3, Bins, -1.3, -1.2, -0.6,  0.3,  0.3, -0.1, -0.1,  0.0, -0.0, -0.1, -0.1,  7.8,  13.0,  6.3, -0.4, -0.3, -0.1, -0.2, 

Agg,  1, Ambient,  2.9, Bins, -2.9, -2.8,  0.1,  0.1, -0.4,  0.3, -0.6,  0.1, -0.0, -0.3, -0.1,  4.3,  13.0,  7.3,  1.1, -0.2,  0.1, -0.2, 

Agg,  2, Ambient,  4.0, Bins, -4.0, -3.3,  0.2, -0.1,  0.2, -0.7, -0.1,  0.4, -0.4, -0.7, -0.9,  7.8,  11.9,  4.3, -0.4, -0.2,  0.1, -0.5, 

Agg,  3, Ambient,  4.7, Bins, -4.7, -3.8, -0.4,  0.2, -0.0,  0.1,  0.4, -0.3, -0.7, -0.7,  2.0,  9.8,  12.7,  5.8, -0.6, -0.4, -0.5, -0.4, 

Agg,  4, Ambient, -0.9, Bins, -0.9, -0.9,  0.4, -0.1, -0.2, -0.2, -0.3, -0.1, -0.0, -0.2, -0.9,  12.2,  15.9,  2.8,  0.0,  0.1, -0.4, -0.3, 

Agg,  5, Ambient,  1.2, Bins, -1.2, -1.2,  0.3, -0.3, -0.4,  0.2,  0.2,  0.2, -0.2, -0.5,  2.1,  16.7,  14.0,  1.8, -0.3, -0.2,  0.4, -0.1, 

Agg,  6, Ambient,  1.3, Bins, -1.3, -1.3, -0.5,  0.2, -0.0, -0.6, -0.1, -0.6,  0.1, -0.0,  6.0,  17.2,  10.6,  1.6, -0.4,  0.1,  0.1, -0.3, 

Agg,  7, Ambient,  1.1, Bins, -1.1, -1.1,  0.0, -0.1,  0.0, -0.1, -0.5, -0.3,  0.1, -0.2,  6.2,  17.9,  12.3,  1.2, -0.3, -0.3,  0.0, -0.6, 

Agg,  8, Ambient,  1.5, Bins, -1.5, -1.5,  0.4,  0.0,  0.1,  0.2,  0.3,  0.3, -0.5, -0.1,  1.5,  13.9,  12.2,  1.6, -0.2,  0.2, -0.0,  0.2, 

Agg,  9, Ambient,  1.1, Bins, -1.1, -1.1,  0.1, -0.1, -0.1, -0.2, -0.3, -0.1, -0.1, -0.5,  4.7,  16.5,  12.1,  1.2, -0.7, -0.3, -0.1, -0.6, 

Agg, 10, Ambient,  4.9, Bins, -4.9, -3.3,  0.3,  0.5,  0.0, -0.7, -0.5, -0.3, -0.6, -0.4,  5.2,  17.9,  10.0,  1.5,  0.0, -0.6, -0.9, -0.3, 

Agg, 11, Ambient, -0.7, Bins, -0.7, -0.7, -0.1,  0.0, -0.0, -0.2,  0.2, -0.1,  0.1, -0.3,  6.8,  19.0,  10.3, -0.9, -0.2, -0.2,  0.2, -0.4, 

Agg, 12, Ambient, -0.8, Bins, -0.8, -0.8,  0.1,  0.0,  0.2,  0.2, -0.2,  0.2, -0.2,  0.0,  2.7,  15.2,  13.3,  1.3, -0.2,  0.1,  0.2, -0.0, 

Agg, 13, Ambient,  1.3, Bins, -1.3, -1.3,  0.2, -0.1,  0.2, -0.1,  0.3, -0.0,  0.0,  0.1,  5.0,  16.9,  11.5,  1.3, -0.1,  0.3, -0.1, -0.0, 

Agg, 14, Ambient,  1.3, Bins, -1.3, -1.2,  0.1, -0.1, -0.2,  0.0,  0.4,  0.4, -0.1, -0.1,  8.4,  19.3,  10.1,  1.1, -0.6,  0.0, -0.3,  0.1, 

Agg, 15, Ambient, -0.9, Bins, -0.9, -0.9,  0.3,  0.0, -0.2, -0.1, -0.2,  0.0,  0.1,  0.1,  8.3,  18.1,  9.7,  2.0, -0.6, -0.1, -0.3, -0.3, 
1 ACCEPTED SOLUTION

Accepted Solutions

Hallo @Anne BIGOT ,

The code posted by @John E KVAM is a good hint of what could be the solution, but I am using the vl53mz_api. Therefore, there is no vl53l8cx_set_resolution, but instead vl53lmz_set_resolution, which works in the same way. Additionally, I need to use vl53lmz_cnh_create_agg_map(), and adjust it accordingly to the parameters used  in  vl53lmz_set_resolution().

View solution in original post

4 REPLIES 4
John E KVAM
ST Employee

If you only have 16 zones it's because you have 4x4 configured. (I think that's the default. They wanted to show off the frame rate, without the long printouts getting in the way. 

IN the VL53L8CX_api.c there should be a call to:

int8_t vl53l8cx_set_resolution(
		VL53L8CX_Configuration 		 *p_dev,
		uint8_t				resolution)

It should be what you want.

Then, when you want to make your printing, and calculations based on number of zones, call vl54L8cx_get_resoluiton() 

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

Thanks, i already found a solution!

Anne BIGOT
ST Employee

Can you share your solution to help other people who may encounter the same issue?

Thanks 


Our community relies on fruitful exchanges and good quality content. You can thank and reward helpful and positive contributions by marking them as 'Accept as Solution'. When marking a solution, make sure it answers your original question or issue that you raised.

ST Employees that act as moderators have the right to accept the solution, judging by their expertise. This helps other community members identify useful discussions and refrain from raising the same question. If you notice any false behavior or abuse of the action, do not hesitate to 'Report Inappropriate Content'

Hallo @Anne BIGOT ,

The code posted by @John E KVAM is a good hint of what could be the solution, but I am using the vl53mz_api. Therefore, there is no vl53l8cx_set_resolution, but instead vl53lmz_set_resolution, which works in the same way. Additionally, I need to use vl53lmz_cnh_create_agg_map(), and adjust it accordingly to the parameters used  in  vl53lmz_set_resolution().