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

news2024/10/7 1:20:49

VL53L4CD液位监测.2--液位检测

  • 概述
  • 视频教学
  • 样品申请
  • 完整代码下载
  • 硬件准备
  • STSW-IMG039
  • 容器特性
  • 包含必要的头文件
  • 变量定义
  • 测距函数 Ranging()
  • 液位误差补偿函数 Liquidlevelmeasureerrorcomponsate()
  • 数据轮询函数 get_data_by_polling()
  • 演示

概述

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

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

在这里插入图片描述

视频教学

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

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

样品申请

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

完整代码下载

硬件准备

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

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左右。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2193340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[git] github管理项目之环境依赖管理

导出依赖到 requirements.txt pip install pipreqs pipreqs . --encodingutf8 --force但是直接使用pip安装不了torch&#xff0c;需要添加源&#xff01;&#xff01; pip install -r requirements.txt -f https://download.pytorch.org/whl/torch_stable.htmlpython 项目中 …

使用树莓派搭建音乐服务器

目录 引言一、搭建Navidrome二、服务穿透三、音流配置 引言 本人手机存储空间128G&#xff0c;网易云音乐6个G&#xff0c;本就不富裕的空间更是雪上加霜&#xff0c;而且重点是&#xff0c;我根本没有听几首歌&#xff0c;清除缓存后&#xff0c;整个软件都还是占用了5个G左右…

5 个PPT设计技巧,让你的开题答辩脱颖而出!

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 开题答辩是论文写作的第一道关键关卡&#xff0c;开题报告不仅展示了你的研究计划和方向&#xff0c;还要让评审老师理解你的研究背景和目的。一个设计精良的开题答辩PPT&#xff0c;不仅可以帮助你更好地陈…

LeetCode Hot100 | Day1 | 二叉树:二叉树的直径

LeetCode Hot100 | Day1 | 二叉树&#xff1a;二叉树的直径 主要学习内容&#xff1a; 二叉树深度求法 深度的 leftright1 得到的是从根结点到叶子结点的节点数量 543.二叉树的直径 [543. 二叉树的直径 - 力扣&#xff08;LeetCode&#xff09;](https://leetcode.cn/prob…

二分查找算法——山脉数组的峰顶索引&寻找峰值

1.题目解析 题目来源&#xff1a;852.山脉数组的峰顶索引 测试用例 题目来源&#xff1a;162.寻找峰值 测试用例 2.算法原理 山脉数组的峰顶索引 根据二段性将山脉数组分为两段&#xff1a;上升段与下降段 1.当mid指针落入上升段&#xff0c;说明峰值在mid指针后&#xff0c;要…

Linux 系统五种帮助命令的使用

Linux 系统五种帮助命令的使用 本文将介绍 Linux 系统中常用的帮助命令&#xff0c;包括 man、–help、whatis、apropos 和 info 命令。这些命令对于新手和有经验的用户来说&#xff0c;都是查找命令信息、理解命令功能的有力工具。 文章目录 Linux 系统五种帮助命令的使用一…

19年408数据结构

第一题&#xff1a; 解析&#xff1a; 设程序执行了K次&#xff0c;则有x K&#xff0c;n<k^2,解得nn^(1/2) 答案选B。 第二题&#xff1a; 解析&#xff1a;这道题直接当作一个结论来记&#xff0c;因为已经出现过很多次了&#xff1a;树的后根遍历和对应二叉树的中序遍…

【异常记录Vue_20241006】使用TagsView后控制台报错

报错截图 报错原因 未将TagsView所依赖的组件permission组件注册到store中&#xff0c;导致TagsView组件在找permission.routes时没找到 解决方法&#xff1a;store注册相应组件

Linux:进程入门(进程与程序的区别,进程的标识符,fork函数创建多进程)

往期文章&#xff1a;《Linux&#xff1a;深入了解冯诺依曼结构与操作系统》 Linux&#xff1a;深入理解冯诺依曼结构与操作系统-CSDN博客 目录 1. 概念 2. 描述进程 3. 深入理解进程的本质 4. 进程PID 4.1 指令获取PID 4.2 geipid函数获取PID 4.3 kill指令终止进程 …

计算机毕业设计 校内跑腿业务系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

从零开始构建大型语言模型——实现注意力机制

本章内容&#xff1a; 使用注意力机制的原因基本的自注意力框架&#xff0c;逐步深入到增强的自注意力机制允许LLMs逐个生成词元的因果注意力模块通过dropout随机屏蔽部分注意力权重以减少过拟合将多个因果注意力模块堆叠为多头注意力模块 到目前为止&#xff0c;你已经了解了…

【GeekBand】C++设计模式笔记6_Decorator_装饰模式

1. “单一职责”模式 在软件组件的设计中&#xff0c;如果责任划分的不清晰&#xff0c;使用继承得到的结果往往是随着需求的变化&#xff0c;子类急剧膨胀&#xff0c;同时充斥着重复代码&#xff0c;这时候的关键是划清责任。典型模式 DecoratorBridge 2. Decorator 装饰模…

Android 内存优化:什么原因导致内存问题?通过内存工具进行分析;内存抖动和内存泄漏;MAT的使用;Profiler的使用;如何优化?

目录 一、为什么要进行内存优化呢&#xff1f; 我们开发一个App程序&#xff0c;如果不了解内存的使用情况&#xff0c;就是将稳定性弃之不管。因为你不知道他在什么时候会发生OOM问题&#xff0c;不知道为什么程序会卡顿&#xff0c;不知道为什么会发生问题。你也没有自信跟别…

算法题之香槟塔

香槟塔 我们把玻璃杯摆成金字塔的形状&#xff0c;其中 第一层 有 1 个玻璃杯&#xff0c; 第二层 有 2 个&#xff0c;依次类推到第 100 层&#xff0c;每个玻璃杯将盛有香槟。 从顶层的第一个玻璃杯开始倾倒一些香槟&#xff0c;当顶层的杯子满了&#xff0c;任何溢出的香槟…

【TypeScript】知识点梳理(三)

#void前面提到了代表空&#xff0c;但有个特殊情况&#xff0c;是空不是空&#xff0c;细谈是取舍&#xff0c;但我们不深究hhh# 代码示例&#xff1a; type func () > voidconst f1: func function() {return true; } 定义了空&#xff0c;返回非空值&#xff0c;理论…

Windows搭建RTMP服务器

这里写自定义目录标题 1 Nginx-RTMP服务器搭建1.1 下载Nginx1.2 下载Nginx的RTMP扩展包1.3 配置Nginx1.4 启动Nginx1.5 查看Nginx状态 2 FFmpeg推流2.1 下载FFmpeg2.2 配置FFmpeg环境变量2.3 验证FFmpeg配置 3 视频推流3.1 OBS推流3.2 FFmpeg推流 4 VLC拉流4.1 VLC4.2 打开网络…

vue3+PPTXjs 在线ppt预览

- 使用PPTXjs做ppt预览&#xff0c;有完整的代码包&#xff0c;基于jquery - vue3使用iframe引入用于预览ppt的网页&#xff0c;通过url参数传递需要预览的ppt链接 - 通过网页选择文件上传也可以通过下面的函数把文件转换成链接&#xff0c;实现在文件上传到服务器前就可以预…

【深度强化学习】DDPG实现的4个细节(OUNoise等)

文章目录 前言一、论文内容简述创新点&#xff08;特点&#xff0c;与DQN的区别&#xff09;&#xff1a;可借鉴参数&#xff1a;细节补充&#xff1a; 二、细节1&#xff1a;weight_decay原理代码 三、细节2&#xff1a;OUNoise原理代码 四、细节3&#xff1a;ObsNorm原理代码…

PostgreSQL分区表,实战细节满满

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、My…

茄子病虫害数据集。四类:果肉腐烂、蛀虫、健康、黄斑病。4000张图片,已经按照8:2的比例划分好训练集、验证集 txt格式 含类别yaml文件 已经标注好

茄子病虫害数据集。可用于筛选茄子品质、质量&#xff0c;训练采摘机器人视觉算法模型……数据集大部分图片来源于真实果园拍摄的图片&#xff08;生长在果树之上的&#xff09;&#xff0c;图片分辨率高&#xff0c;数据集分为四类&#xff1a;果肉腐烂、蛀虫、健康、黄斑病。…