cancel
Showing results for 
Search instead for 
Did you mean: 

Does anyone have experience with measuring water / liquid levels? (Vl53L5CX)

SMaal.1
Associate

I am currently investigating two sensors (VL53L1X and Vl53L5X) for my bachelor thesis.

In my measurements, the VL53L1X was able to achieve a measuring accuracy of 5-8 % when it is mounted exactly vertically above the water surface.

However, the VL53L5 causes me great concern. It should actually detect the water level as shown in the video on the STM site (Video: Liquid Level Monitoring using ST's Time-of-Flight: Vl53L5CX). 

However, I have the problem that I don't know how to adjust the sensor. For example, if it measures with a 4x4 matrix, one of the 16 values is correct. But how can I filter this value or improve the result so that all 16 values approximately detect the liquid surface. Does anyone have any experience or tips? (Please do not use tips in the direction of float or similar, I am interested in the optimal settings of the sensor).

Currently the sensors are running on a Nucleo with the respective GUI for the expansion boards. (STSW-IMG024 and STSW-IMG008)

I would be very pleased to receive an answer.

Kind regards

Sophia 

8 REPLIES 8
John E KVAM
ST Employee

Sophia -

With the L5 you will find the zone with the STRONGEST signal is the most accurate one.

Photons that strike the surface of the water perpendicularly are much more likely to reflect back. All the other zones are gathering photons that have hit the water, penetrated, reflected off the bottom and returned. And of course the sided get involved as well.

In my experiments only the perpendicular zone is correct. And I used a long integration time to lessen the effect of bubbles and turbulence.

The other mandatory condition is that you must have a non-reflective bottom. Creating a Specular (mirror-like) bottom is going to reflect the photons that do penetrate. And those will make a mess of the data.

So only look to the one zone. The others are all going to be wrong based on the depth of the water.

I've also had fair luck with the VL53L4CD. This brand-new sensor has a more narrow field of view and if you can guarantee perpendicularity, it will also work for you. It's still not as good as the L5, but it costs a good bit less as it's a single zone sensor.


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.
John E KVAM
ST Employee

If you are already using the GUI, try enabling the Signal strength output. (It's a check-box on the lower right.) Then compare the distance of the zone with the strongest signal to the known distance.


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.
ALomb.1
Associate III

Hi @John E KVAM​,

like @SMaal.1​ I would like to use ToF for monitoring the level of liquids in a tank.

I have setup the 53L5A1_SimpleRanging Application in CubeIDE with NUCLEO-F401RE board and X-NUCLEO-53L5A1.

As you suggested to @SMaal.1​  I would like to find the zone with the STRONGEST signal.

So, after calling the function:

status = VL53L5A1_RANGING_SENSOR_GetDistance(VL53L5A1_DEV_CENTER, &Result);

I should look in all zone for the one it has:

	Result.ZoneResult[n].Status = 0
	Result.ZoneResult[n].Signal = <Max Value>

and get the "correct" distance from:

	Result.ZoneResult[n].Distance

It's correct ?

Is it necessary to configure the VL53L5A1 in a different way than the default one in the example?

To start I would like to replicate the demo shown in the "Liquid Level Monitoring" video in order to validate this solution.

It would be very useful to have an application note with the source code to replicate it !

King Regards

Antonello

John E KVAM
ST Employee

That is exactly correct. But use the zones that have status 5, 6 or 9. Those are the good status values.

I would create a print out that prints the status, distance and signal strength for each zone.

Then you can convince yourself this works.

The only real trick is that the reflectivity of the bottom is important. Black and optically dull works best.

  • 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.
ALomb.1
Associate III

This is the function I added in file app_tof.c and call in function print_result:

static int8_t MX_53L5A1_GetStrongestDistance(RANGING_SENSOR_Result_t *pResult)
{
	int8_t retValue = 0;
	int8_t j, k, l;
	uint8_t zones_per_line;
	uint32_t currentSignal = 0;
	uint8_t strongestZone = 0;
	uint32_t strongestDistance = 0;
 
	/* To find STRONGEST zone signal must be enabled */
	if ((Profile.EnableAmbient != 0) || (Profile.EnableSignal != 0))
	{
		zones_per_line = ((Profile.RangingProfile == RS_PROFILE_8x8_AUTONOMOUS) ||
		                  (Profile.RangingProfile == RS_PROFILE_8x8_CONTINUOUS)) ? 8 : 4;
 
		for (l = 0; l < RANGING_SENSOR_NB_TARGET_PER_ZONE; l++)
		{
			for (j = 0; j < pResult->NumberOfZones; j += zones_per_line)
			{
				for (k = (zones_per_line - 1); k >= 0; k--)
				{
					if ((pResult->ZoneResult[j+k].NumberOfTargets > 0) &&
					    (pResult->ZoneResult[j+k].Status[l] == 0))
					{
						if(pResult->ZoneResult[j+k].Signal[l] > currentSignal)
						{
							currentSignal = pResult->ZoneResult[j+k].Signal[l];
							strongestDistance = pResult->ZoneResult[j+k].Distance[l];
							strongestZone = j+k;
						}
					}
				}
			}
		}
		printf("Strongest Signal of %5ld at zone %2d: distance = %5ld\n", currentSignal, strongestZone, strongestDistance);
	}
	else
	{
		retValue = -1;
	}
	return retValue;
}

I have some doubts about the status.

In the file Drivers\ BSP\53L5A1\53l5a1_ranging_sensor.h line 119 there is the following comment:

typedef struct
{
  uint8_t NumberOfTargets;
  uint32_t Distance[RANGING_SENSOR_NB_TARGET_PER_ZONE]; /*!< millimeters */
  uint32_t Status[RANGING_SENSOR_NB_TARGET_PER_ZONE];   /*!< OK: 0, NOK: !0 */
  float_t Ambient[RANGING_SENSOR_NB_TARGET_PER_ZONE];   /*!< kcps / spad */
  float_t Signal[RANGING_SENSOR_NB_TARGET_PER_ZONE];    /*!< kcps / spad */
} RANGING_SENSOR_ZoneResult_t;

If the comment is correct, non-zero states are not ok!

John E KVAM
ST Employee

I had a mentor that said you should never read the comments in the code. When the code changes, programmers never update their code. Status 5,6,9 and maybe 12 are valid. All the others tell you want went wrong.


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

Nice, this thread has informed me of why I could never get the VL53L0/1/1x to measure water. Now if someone could find the 'Demo' from "Liquid Level Monitoring using ST’s Time-of-Flight: VL53L5CX"

and post a link it would be a good thing. Now I wait on Mouser for yet another X-NUCLEO-VL53Lxxx X-NUCLEO-53L5A1 & VL53L5CX-SATEL ..

Anne BIGOT
ST Employee

ST just published a FAQ about liquid level monitoring.

You can find it here.

There were also a webinar in November 2022.

You can find a SW package here with example code.


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'