VL53L4CD液位监测(2)----液位检测

概述

液位检测在工业自动化、环境监测和消费电子等领域中具有广泛的应用价值。随着技术的进步,基于飞行时间(Time-of-Flight, ToF)传感器的液位检测解决方案以其高精度、非接触式测量能力成为了热门选择。本文将介绍如何使用 STMicroelectronics 的 VL53L4CD ToF 传感器进行高精度液位检测,并重点探讨在不同液体和容器条件下如何通过非线性校正算法提升测量准确性。文中还将分析实验测试结果,并总结液位检测应用中可能面临的挑战及解决方案。

最近在弄ST的课程,需要样片的可以加群申请:615061293 。

在这里插入图片描述

视频教学

https://www.bilibili.com/video/BV1gj1BY1Ewe/

VL53L4CD液位监测(2)----液位检测

样品申请

https://www.wjx.top/vm/OhcKxJk.aspx#

完整代码下载

https://download.csdn.net/download/qq_24312945/89853013

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。
在这里插入图片描述
在这里插入图片描述

STSW-IMG039

该液位监测解决方案基于意法半导体渡越时间测距传感器,可与VL53L4CD渡越时间高精度接近传感器或具有宽视野的VL53L5CX渡越时间8x8多区测距传感器配合使用。
采用FlightSense技术的创新型意法半导体解决方案支持用户使用非机械传感器来测量液体的液位,以降低锈蚀风险。意法半导体解决方案可以十分精准地测量各种液体,包括透明的水和深色的燃料等等。
VL53L4CD适用于接近测量和短距离测量,可实现从仅仅1 mm到1300 mm的超精准距离测量。新一代激光发射器具有18°FoV(视场),提高了环境光下的性能,其测距速度高达100 Hz。

在这里插入图片描述

容器特性

AN5851 文件的内容,第二章主要讲解了 ST 的建议,该章节分为两个部分,讨论了容器的属性和反射率对测量精度的影响,并给出了相应的优化建议。

容器的尺寸和传感器的视场角 (FoV):VL53L4CD 传感器的视场角是锥形的(18°),因此,如果容器的直径小于传感器的视场角,测量信号可能会从容器的边缘反射回来,导致测量精度下降。为了避免这一问题,建议使用直径大于传感器视场的容器。

传感器与液体表面的距离:传感器应放置在液面最高点上方至少 30 毫米的位置,以避免水滴反弹或容器晃动时造成的信号干扰,从而影响测量准确性。

在这里插入图片描述

低反射率容器:建议使用底部低反射率的容器,因为当液面较低时,如果容器底部反射信号过强,可能会与从液面反射回来的信号混淆,导致测量错误。

透明或高反射率容器的影响:透明或高反射率的容器底部容易导致测量信号混乱,尤其是在液面较低时。因此,低反射率的底部设计能够减少信号干扰,提高测量精度。

在这里插入图片描述

包含必要的头文件

/* USER CODE BEGIN Includes */
#include "vl53l4cd_api.h" // VL53L4CD 传感器 API
#include "custom_ranging_sensor.h" // 自定义测距传感器头文件
/* USER CODE END Includes */

变量定义

/* USER CODE BEGIN 0 */
int status;// 存储操作状态
volatile int IntCount;// 中断计数器
uint8_t p_data_ready;// 数据准备标志
uint16_t dev, sensor_id;// 设备 ID 和传感器 ID
VL53L4CD_ResultsData_t results;		/* Results data from VL53L4CD */
VL53L4CD_Version_t sw_version;	/* Driver version */


/* Below code has to be updated depending on customer setup parameters */
/* Start: Measure liquid level application*/
/* Consider X indicator levels and define a structure to store level, expected result and compensation value*/
// 液位标志的数量,定义有 10 个级别
#define MAX_LABEL 10 /* Number of level indicators – To be updated depending on the number of levels in the OffGainVal.csv file */
typedef struct ogalgo_data
{
  uint8_t level ;// 液位级别
  uint16_t  expected_res;// 预期测量结果
  uint16_t  og_val;// 补偿值
}ogalgo_data;

/* Design a lookup table with a structure of compensate value data received from GUI once characterization is done*/
/* First column : indicator level , Second column: Expected result , Third column: compensate value*/
/* Example of values given below - To be updated with values from the GUI*/

/* 使用测量补偿数据初始化查找表 */
ogalgo_data ogalgo_data_inst[MAX_LABEL]={
		{ 9, 21, 4 },
		{ 8, 42, 4 },
		{ 7, 63, 2 },
		{ 6, 84, 1 },
		{ 5, 105, 5 },
		{ 4, 126, 14 },
		{ 3, 147, 25 },
		{ 2, 168, 30 },
		{ 1, 189, 20 },
	};


/* Ranging 函数的原型声明 */
int Ranging(Dev_t dev,uint16_t *ouputranging);

/* 开启算法标志 */
uint8_t algo_enable=1; /* algo_enable=1 to apply the lookup table - algo_enable=0 to not apply */
uint16_t totaldistance=270; /* 传感器到容器底部的高度,单位为毫米 */
uint16_t meanranging=0;// 平均测距值
uint16_t rangevalue_out=0;// 最终补偿后的测距值
uint16_t invalid_range=999;// 无效测距值


void get_data_by_polling(Dev_t dev);// 数据轮询获取函数
/* USER CODE END 0 */

测距函数 Ranging()

该函数执行 10 次测距操作并计算平均值,确保测量结果的稳定性。

/* Ranging 函数 - 获取测量数据并计算平均值 */
int Ranging(Dev_t dev,uint16_t *ouputranging)
{
	uint8_t cnt=0;uint16_t mean_distance=0;uint16_t meanranging=0;
	 /* 进行 10 次测量,取平均值 */
	for (cnt = 0; cnt < 10;)
	{
		status = VL53L4CD_CheckForDataReady(dev, &p_data_ready);
//		printf("status11=%d,data_ready=%d\n",status,p_data_ready);
		HAL_Delay(3);
		if (p_data_ready)
		{
			VL53L4CD_ClearInterrupt(dev);
			VL53L4CD_GetResult(dev, &results);


				if(results.range_status ==0)
				{
					mean_distance+=results.distance_mm;
					cnt++;
					HAL_Delay(3);
				}


		}
	}
//	printf("cnt=%d\n",cnt);
	meanranging=mean_distance/10;// 计算平均值
	*ouputranging =meanranging;
	return status;
}

液位误差补偿函数 Liquidlevelmeasureerrorcomponsate()

/* 液位测量误差补偿函数 */
void Liquidlevelmeasureerrorcomponsate(uint16_t rangevalue,uint16_t *rangevalue_out)
{

		uint16_t pos=0;
		uint16_t i=0; uint16_t value;

		for (i=0;i<MAX_LABEL;i++)
		{
			if  (rangevalue <totaldistance+5) //5 buffer
			{
				if (rangevalue < ogalgo_data_inst[i].expected_res)
				{

					//Check first
					if (i >0)
					{
						value = (ogalgo_data_inst[i].expected_res + ogalgo_data_inst[i-1].expected_res)/2;
					}
					else
						value = ogalgo_data_inst[i].expected_res;
					if(rangevalue <= value)
					{
						/* First position */
						if (i ==0 )
						{
							pos=1;
							break;
						}
						pos=1+(i-1); // adding one bcz position starts from 1
						break;
					}
					else
					{
						pos=1+i;
						break;
					}
				}
				else
				{
					if (rangevalue > totaldistance+5)
						pos=99;
					else
						pos=6;  // Need to find which one is max OG value or store it directly here

				}
			}
			else
				pos=99;

		}

		 /* 根据位置补偿测量值 *//
		switch(pos)
		{
			case 1:
					*rangevalue_out=rangevalue + ogalgo_data_inst[pos].og_val; // Category Underranging,
				break;
			case 2:
					*rangevalue_out=rangevalue + ogalgo_data_inst[pos].og_val; // Category Underranging, 30mm average b/w C3&C2
				break;
			case 3:
					*rangevalue_out=rangevalue + ogalgo_data_inst[pos].og_val; // Category Underranging, 25mm average b/w C4&C3
				break;
			case 4:
					*rangevalue_out=rangevalue + ogalgo_data_inst[pos].og_val; // Category Underranging, 12mm average b/w C2&C2
				break;
			case 5:
					*rangevalue_out=rangevalue - ogalgo_data_inst[pos].og_val; // Category Overranging, 4mm average b/w C2&C2
				break;
			case 6:
					*rangevalue_out=(uint16_t)(rangevalue - ogalgo_data_inst[pos].og_val); // Category Overranging,

				break;
			case 7:
					*rangevalue_out=(uint16_t)(rangevalue - ogalgo_data_inst[pos].og_val); //Category Overranging,
				break;
			case 8:
					*rangevalue_out=(uint16_t)(rangevalue - ogalgo_data_inst[pos].og_val); // Category Overranging,

				break;
			case 9:
					*rangevalue_out=(uint16_t)(rangevalue - ogalgo_data_inst[pos].og_val); // Category Overranging,
				break;
			default:
					printf("Valid water level not found\n");
			}

}
/* End:Measure liquid level application */

数据轮询函数 get_data_by_polling()

该函数不断轮询 VL53L4CD 传感器的数据,计算平均测距值并输出补偿后的液位数据。

/* 通过轮询获取数据 */
void get_data_by_polling(Dev_t dev){
	do
	{
		/* Liquid level Measure application */
		status=Ranging(dev,&meanranging);
			 if (!status)
			 {
				 if (algo_enable == 1)
				 {
					 Liquidlevelmeasureerrorcomponsate(meanranging,&rangevalue_out);
					 //printf("rg=%d %d\n",meanranging, rangevalue_out);
					 if (rangevalue_out>0)
					 	 printf("Liquid level is = %d mm\n",rangevalue_out);
					 else
						 printf("Invalid range is = %d mm\n",invalid_range);
				 }
				 else
					 printf("Mean ranging is = %d mm\n",meanranging);
			 }

	}
	while(1);
}

演示

水瓶大概19cm左右,当只剩下一点水时。

在这里插入图片描述

加水到7cm左右。

在这里插入图片描述

加水到11cm左右。

在这里插入图片描述

加水到14左右。

在这里插入图片描述

<think>嗯,用户问的是HC-SR04超声波测距模块使用什么通信方式。首先,我需要确认自己对HC-SR04的了解。HC-SR04是一种常见的超声波测距模块,通常用于测量距离,比如在机器人避障或者自动导航系统中使用。 接下来,用户想知道它的通信方式。这里需要明确通信方式指的是什么。一般来说,通信方式可能包括数字信号、模拟信号、串口通信(如UART)、I2C、SPI等。但HC-SR04的工作方式可能和这些标准通信协议不同,因为它可能使用简单的触发和回波信号来工作。 回想一下HC-SR04的工作原理,通常它需要外部微控制器(如Arduino)来触发一个脉冲信号,然后模块发送超声波,并检测回波,通过计算时间差来得到距离。所以它的通信可能基于简单的数字脉冲,而不是复杂的协议。也就是说,用户可能需要通过数字引脚发送触发信号,然后通过另一个数字引脚读取回波信号的高电平持续时间,再根据时间计算距离。 需要确认这一点是否正确。可能需要查阅HC-SR04的数据手册或者常见的应用笔记。根据记忆,HC-SR04的接口通常包括VCC、GND、Trig(触发)和Echo(回波)四个引脚。Trig用于启动测距,Echo用于返回高电平脉冲,其宽度与距离成正比。所以这更像是一种基于脉冲宽度的通信方式,而不是传统的串行通信协议。 用户可能想知道是否需要使用特定的通信协议,比如I2C或UART,但根据HC-SR04的设计,它不需要这些协议。它只需要通过数字IO口进行触发和读取脉冲宽度。因此,通信方式可以描述为非协议化的数字脉冲方式,或者基于脉冲宽度调制(PWM)的方式,但更准确的是触发-回波机制。 另外,用户可能想知道是否需要额外的库或硬件支持,但通常只需要基本的GPIO操作即可,不需要复杂的通信库。可能还要提到工作电压、测量范围、精度等参数,但用户的问题主要集中在通信方式上,所以重点应放在触发和回波的机制上。 总结来说,HC-SR04的通信方式是使用两个数字信号线:Trig和Echo。Trig接收一个10微秒的高电平脉冲来启动测距,然后Echo输出一个高电平脉冲,其持续时间与距离成正比。通过测量Echo脉冲的持续时间,可以计算出距离值。这种机制不依赖于标准的通信协议,而是基于时间测量的简单数字信号交互。</think>### 核心结论 **HC-SR04超声波测距模块使用基于数字脉冲的触发-回波机制(非标准通信协议)**,通过简单的电平信号交互完成距离测量,无需I&sup2;C、SPI或UART等复杂通信协议。 --- ### 通信方式详解 1. **接口定义** - **Trig(触发引脚)**:输入引脚,接收来自控制器(如单片机)的触发信号(需至少$10\mu s$的高电平脉冲) - **Echo(回波引脚)**:输出引脚,返回与距离成比例的高电平脉冲(持续时间$T$对应超声波往返时间- **VCC/GND**:供电($5V$直流)与接地 2. **工作流程** ```plaintext 控制器动作 HC-SR04响应 ┌───────────┐ ┌──────────────────┐ │发送10μs高电平脉冲→Trig│触发超声波发射(8个40kHz脉冲) │ │←Echo │检测回波并输出高电平脉冲 │测量Echo高电平时间T │ └───────────┘ ``` **距离计算公式**: $$ \text{距离} = \frac{T \times 340\text{m/s}}{2} $$ (340m/s为声速,实际需根据温度修正) --- ### 参数特性 | 参数 | 数值/描述 | |---------------------|-----------------------------------| | **工作电压** | $5V \pm 0.5V$ | | **测量范围** | $2\text{cm} \sim 400\text{cm}$ | | **测距精度** | $\pm 3\text{mm}$(理想条件下) | | **触发信号要求** | $10\mu s$以上高电平脉冲 | | **响应时间** | 最大$100ms$(无回波时超时) | --- ### 典型电路连接示例 ``` [Arduino UNO] [HC-SR04] Digital Pin 9 →→→→→ Trig Digital Pin 10 ←←←←← Echo 5V →→→→→ VCC GND →→→→→ GND ``` **注意事项**: - 若控制器电压为$3.3V$(如树莓派),需在Echo引脚串联$1k\Omega$电阻或使用电平转换模块 - 避免多个超声波模块同时工作,防止声波干扰 --- ### 代码实现(Arduino示例) ```cpp const int trigPin = 9; const int echoPin = 10; void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); } void loop() { // 发送触发信号 digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // 测量回波脉冲宽度 long duration = pulseIn(echoPin, HIGH); float distance = duration * 0.034 / 2; // 单位:厘米 Serial.print("Distance: "); Serial.print(distance); Serial.println(" cm"); delay(100); } ``` --- ### 常见问题与优化 1. **测量误差大** - **原因**:环境温度影响声速(温度每升高$1℃$,声速增加约$0.6m/s$) - **解决**:加入温度传感器(如DS18B20),动态修正声速: $$ v = 331.4 + 0.6 \times T_{℃} $$ 2. **近距离盲区** - **现象**:$<2cm$时无法检测 - **应对**:软件设置最小阈值或改用TOF飞行时间)传感器 3. **多模块干扰** - **方案**:分时复用(依次触发不同模块,间隔$>60ms$) --- ### 扩展应用场景 | 场景 | 实现方式 | |---------------------|-----------------------------------| | **智能小车避障** | 3个模块分别检测左/前/右障碍物 | | **液位监测** | 垂直安装于容器顶部测液面高度 | | **自动门控制** | 检测人体进入触发范围(1m内) | --- ### 替代方案对比 | 模块类型 | HC-SR04 | VL53L0X(激光ToF) | |----------------|---------------------------|---------------------------| | **测距原理** | 超声波 | 激光飞行时间 | | **最大距离** | $4m$ | $2m$ | | **精度** | $\pm 3mm$ | $\pm 1mm$ | | **抗光干扰** | 强(适用于黑暗环境) | 弱(强光下性能下降) | | **成本** | $1 \sim 2$美元 | $4 \sim 6$美元 | --- ### 总结 HC-SR04通过**数字脉冲触发+回波时间检测**实现测距,无需复杂通信协议。其低成本、易用性使其成为入门级项目的理想选择,但在高精度或复杂环境应用中需结合温度补偿、多模块协同等策略优化性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记帖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值