2025-04-09 6:28 AM
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,
Solved! Go to Solution.
2025-04-23 4:20 AM
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().
2025-04-14 1:47 PM
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
2025-04-15 6:49 AM
Thanks, i already found a solution!
2025-04-17 5:11 AM
Can you share your solution to help other people who may encounter the same issue?
Thanks
2025-04-23 4:20 AM
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().