ToF 测距传感器 VL6180 测量范围修改(软件 I2C)

news2024/11/21 0:19:29
TOF 测距传感器 VL6180 传感器修改测量范围  ...... by  矜辰所致

前言

之前写过一篇关于ToF 测距传感器 VL6180 使用的文章:

ToF 测距传感器 VL6180 使用踩坑记(软件 I2C)

之后有粉丝问我如何修改测量距离,当时我只回答让粉丝去找一下寄存器,最近找了点时间自己来测试了一下,发现其实直接找手册好像不那么容易解决问题,于是自己还是想着得写一篇文章来说明一下,所以本文的内容就是如何修改 VL6180 的测量距离。

我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • 一、 参考资料
  • 二、代码移植说明
  • 结语

一、 参考资料

在官方手册中,我们可以查到, 对于 VL6180 的测量范围说明如下:

在这里插入图片描述

默认情况下,缩放因子为1 ,测距的范围最大是 20cm ,我们想要测量更大需要进行设置 。

但是对于如何修改,其实从官方文档中我是没有找到很直接的答案,这里我还是在网上借鉴的大佬的文章:

添加链基于STM32CUBEMX驱动TOF模块VL6180与VL6180X(2)----修改测量范围描述

根据文章的指引,我也在官方的 SDK 包中找到了官方提供的修改测量范围的函数:

在这里插入图片描述

在本文中,我们也只需要根据根据大佬的文章和官方的API 来移植即可。

我自己测试起来,也遇到了一些小疑问,但是后来还是成功实现修改距离的,下面我来一一说明。

二、代码移植说明

我们移植的只有一个函数,就是 int VL6180_UpscaleSetScaling(VL6180Dev_t dev, uint8_t scaling)这个函数,在大佬的文章中,也说到了,官方的函数相对 “ 复杂 ”,在文章中大佬也给出了简化后的代码。

首先,我们我们根据文章中的指示,该定义的定于,该写的写:

uint8 scaling;
uint16 ScalerValues[] = {0, 253, 127, 84};

void VL6180x_UpscaleSetScaling(uint8 new_scaling)
{
	uint8 DefaultCrosstalkValidHeight = 20; // default value of SYSRANGE__CROSSTALK_VALID_HEIGHT
	// do nothing if scaling value is invalid
	if (new_scaling < 1 || new_scaling > 3) return;

	scaling = new_scaling;

	VL6180X_WriteByte_16Bit(RANGE_SCALER,ScalerValues[scaling]);

对于博主来说,产品上只会有一个 VL6180 探头,所以在代码中的函数,并没有 add 地址这个参数,因为对我来说,地址是固定的,直接写在了代码中。如果大家测试可能 I2C 上带多个传感器,是可能出现不同地址,需要多一个参数的。

所以在我给出的示例代码中,都没有add 这个参数,大家可以从我下面的代码中也能看出来,我在写数据的函数中,写的是固定地址。

到这里有一个VL6180X_WriteByte_16Bit,这个地方我们需要修改一下,因为在我原本的应用中并没有写 16bit 的函数,

官方的说明都是针对硬件 I2C ,我们需要使用的是软件 I2C ,所以我们自己还得写一下这个函数。 这里也很简单,直接上一下函数比较图,大家根据自己的writeByte 函数修改即可:

在这里插入图片描述

当然,在函数中的一些宏定义,我们可以直接从官方的 SDK 包中照样复制到自己的代码中,如下图:

在这里插入图片描述

然后接着往下写,有一个关键的语句:

...
VL6180X_WriteByte(add,SYSRANGE_PART_TO_PART_RANGE_OFFSET,ptp_offset / scaling);
...

这里有一个ptp_offset ,在推荐的文章中,其实也说得不是很清楚,我们无法追溯它是怎么来的,那么我们还是得去官方 API 对应的地方查看,我们找到写SYSRANGE_PART_TO_PART_RANGE_OFFSET 这个寄存器地址的地方,看一下官方是怎么处理的:

在这里插入图片描述

从上面我们可以看到,我们要实现的只是往SYSRANGE_PART_TO_PART_RANGE_OFFSET这个地址写入一个值,这个值 = 某一个数值 / 我们设置的 scaling 参数。 这个值是通过 VL6180DevDataGet 得到的,那么这个 VL6180DevDataGet 是什么东西,我们直接查找,如下图:

在这里插入图片描述

所以这么一分析,就是这样的:

Offset = VL6180DevDataGet(dev, Part2PartOffsetNVM) / scaling;
等于
Offset = SingleVL6180DevData.Part2PartOffsetNVM / scaling;

所以我们要确定的就是 SingleVL6180DevData.Part2PartOffsetNVM 这个等于多少,我们在 vl6180_api.c
中搜索 Part2PartOffsetNVM 这个值,我们可以找到设置这个值的地方,下图中也有对应的分析:

在这里插入图片描述

上面代码对 Part2PartOffsetNVM 赋值的地方在 VL6180_InitData 函数中,使用了 VL6180DevDataSet 宏定义, 和 Get 一样:

VL6180DevDataSet(dev, Part2PartOffsetNVM, offset);
等于
SingleVL6180DevData.Part2PartOffsetNVM = offset;

分析到这里,我们就知道了在 官方 API 中,在初始化的时候先读取SYSRANGE_PART_TO_PART_RANGE_OFFSET 的值,保存在 Part2PartOffsetNVM 这个结构体成员中。

在我们自己的代码中,并不需要那个复杂的结构体,我直接简单的处理:

在这里插入图片描述

好了,解决完了这条语句,后面几条语句直接按照大佬文章来就行了。

这里直接上一下我修改的代码主要部分:

#include "vl6180.h"

uint8 u8Ack;
uint8 scaling;
uint16 ScalerValues[] = {0, 253, 127, 84};
uint8  Part2PartOffsetNVM; 


uint8 VL6180X_WriteByte(uint16 reg,uint8 data1)
{
/*
防止内容太多省略
*/
}
uint8 VL6180X_WriteByte_16Bit(uint16 reg,uint16 data1)
{
/*
防止内容太多省略
*/
}
uint8 VL6180X_ReadByte(uint16 reg)
{
/*
防止内容太多省略
*/
}

void VL6180x_UpscaleSetScaling(uint8 new_scaling)
{
	uint8 DefaultCrosstalkValidHeight = 20; // default value of SYSRANGE__CROSSTALK_VALID_HEIGHT
	// do nothing if scaling value is invalid
	if (new_scaling < 1 || new_scaling > 3) return;

	scaling = new_scaling;

	VL6180X_WriteByte_16Bit(RANGE_SCALER,ScalerValues[scaling]);

	VL6180X_WriteByte(SYSRANGE_PART_TO_PART_RANGE_OFFSET,Part2PartOffsetNVM / scaling);

	VL6180X_WriteByte(SYSRANGE_CROSSTALK_VALID_HEIGHT, DefaultCrosstalkValidHeight / scaling);

	VL6180X_ReadByte(SYSRANGE_RANGE_CHECK_ENABLES);
	
	VL6180X_WriteByte(SYSRANGE_CROSSTALK_VALID_HEIGHT, DefaultCrosstalkValidHeight / scaling);
}

uint8 VL6180X_Read_ID(void)
{
	return VL6180X_ReadByte(VL6180X_REG_IDENTIFICATION_MODEL_ID);
}

uint8 VL6180X_Init(void)
{
	if(VL6180X_Read_ID() == VL6180X_DEFAULT_ID)
	{
		/*
		防止内容太多省略
		*/
		while(VL6180X_WriteByte(0x003e, 0x31));      //????	ALS??
									// to 500ms		
		while(VL6180X_WriteByte(0x0014, 0x24));       // Configures interrupt on 'New Sample
									// Ready threshold event'
//		VL6180X_WriteByte(VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00);
		Part2PartOffsetNVM = VL6180X_ReadByte(SYSRANGE_PART_TO_PART_RANGE_OFFSET);
		VL6180x_UpscaleSetScaling(3);
		return 0;
	}
	else return 1;
}

/*
VL6180X_Read_Range 不用变,但是值得注意的是,上面VL6180x_UpscaleSetScaling(3)
得到的距离的实际值是 下面返回的 range  的值 * 3。
*/
uint8 VL6180X_Read_Range(void)
{
	uint8 range = 0;
	uint16 count = 0;

	while(!(VL6180X_ReadByte(VL6180X_REG_RESULT_RANGE_STATUS)&0x01));   //发送 0 和 01001101   读到的是1   STM32读到的是2

	while(VL6180X_WriteByte(VL6180X_REG_SYSRANGE_START,0x01));	//??????	00011000	  正常,while(0);
	//???????????(New Sample Ready threshold event)
	while(!(VL6180X_ReadByte(VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO)&0x04))	//01001111	读到的是0
	{
		count++;
		if(count >= 100){
			count = 0;
			VL6180X_WriteByte(VL6180X_REG_SYSTEM_INTERRUPT_CLEAR,0x07);
			VL6180X_WriteByte(VL6180X_REG_SYSRANGE_START,0x01);
		}	
	}

	range = VL6180X_ReadByte(VL6180X_REG_RESULT_RANGE_VAL);

	while(VL6180X_WriteByte(VL6180X_REG_SYSTEM_INTERRUPT_CLEAR,0x07));	//0111b ?????????
	return range;
}

至于 .h 文件,都是宏定义和 函数声明:

#ifndef _VL6180_H_
#define _VL6180_H_

#include "EO3000I_API.h"
#include "EO3000I_CFG.h"
#include <stdlib.h>
#include "i2c.h"

#define	VL6180X_DEFAULT_ID						0xB4
//#define I2C_DEBUG
#define VL6180X_DEFAULT_I2C_ADDR 				0x29  ///< The fixed I2C addres
/*------------------VL6180X内部寄存器------------------*/
///! Device model identification number
#define VL6180X_REG_IDENTIFICATION_MODEL_ID    0x000
///! Interrupt configuration
#define VL6180X_REG_SYSTEM_INTERRUPT_CONFIG    0x014
///! Interrupt clear bits
#define VL6180X_REG_SYSTEM_INTERRUPT_CLEAR     0x015
///! Fresh out of reset bit
#define VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET  0x016
///! Trigger Ranging
#define VL6180X_REG_SYSRANGE_START             0x018
///! Trigger Lux Reading
#define VL6180X_REG_SYSALS_START               0x038
///! Lux reading gain
#define VL6180X_REG_SYSALS_ANALOGUE_GAIN       0x03F
///! Integration period for ALS mode, high byte
#define VL6180X_REG_SYSALS_INTEGRATION_PERIOD_HI  0x040
///! Integration period for ALS mode, low byte
#define VL6180X_REG_SYSALS_INTEGRATION_PERIOD_LO  0x041
///! Specific error codes
#define VL6180X_REG_RESULT_RANGE_STATUS        0x04d
///! Interrupt status
#define VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO       0x04f
///! Light reading value
#define VL6180X_REG_RESULT_ALS_VAL             0x050
///! Ranging reading value
#define VL6180X_REG_RESULT_RANGE_VAL           0x062

#define RANGE_SCALER                            0x096

#define SYSRANGE_CROSSTALK_VALID_HEIGHT       0x021
#define SYSRANGE_EARLY_CONVERGENCE_ESTIMATE   0x022
#define SYSRANGE_PART_TO_PART_RANGE_OFFSET    0x024

#define SYSRANGE_RANGE_CHECK_ENABLES          0x02D

#define VL6180X_ALS_GAIN_1         0x06  ///< 1x gain
#define VL6180X_ALS_GAIN_1_25      0x05  ///< 1.25x gain
#define VL6180X_ALS_GAIN_1_67      0x04  ///< 1.67x gain
#define VL6180X_ALS_GAIN_2_5       0x03  ///< 2.5x gain
#define VL6180X_ALS_GAIN_5         0x02  ///< 5x gain
#define VL6180X_ALS_GAIN_10        0x01  ///< 10x gain
#define VL6180X_ALS_GAIN_20        0x00  ///< 20x gain
#define VL6180X_ALS_GAIN_40        0x07  ///< 40x gain

#define VL6180X_ERROR_NONE         0   ///< Success!
#define VL6180X_ERROR_SYSERR_1     1   ///< System error
#define VL6180X_ERROR_SYSERR_5     5   ///< Sysem error
#define VL6180X_ERROR_ECEFAIL      6   ///< Early convergence estimate fail
#define VL6180X_ERROR_NOCONVERGE   7   ///< No target detected
#define VL6180X_ERROR_RANGEIGNORE  8   ///< Ignore threshold check failed
#define VL6180X_ERROR_SNR          11  ///< Ambient conditions too high
#define VL6180X_ERROR_RAWUFLOW     12  ///< Raw range algo underflow
#define VL6180X_ERROR_RAWOFLOW     13  ///< Raw range algo overflow
#define VL6180X_ERROR_RANGEUFLOW   14  ///< Raw range algo underflow
#define VL6180X_ERROR_RANGEOFLOW   15  ///< Raw range algo overflow


uint8 VL6180X_WriteByte(uint16 reg,uint8 data1);
uint8 VL6180X_Read_ID(void);
uint8 VL6180X_Init(void);
uint8 VL6180X_Read_Range(void);
uint8 VL6180X_ReadByte(uint16 reg);

#endif 

在上面代码中使用过程中有一点需要说明一下, 读取函数 VL6180X_Read_Range 不用变,但是值得注意的是,因为我们设置了 VL6180x_UpscaleSetScaling(3) ,所以得到的距离实际值是 VL6180X_Read_Range 函数的返回值 * 3。

结语

到这里大家应该都知道如何修改 VL6180 传感器的测量范围,本文还是比较简单的。

好了,本文就到这里,谢谢大家!

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

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

相关文章

【c语言】简单贪吃蛇的实现

目录 一、游戏说明 ​编辑 二、地图坐标​ ​编辑 三、头文件 四、蛇身和食物​ 五、数据结构设计​ 蛇节点结构如下&#xff1a; 封装一个Snake的结构来维护整条贪吃蛇&#xff1a;​ 蛇的方向&#xff0c;可以一一列举&#xff0c;使用枚举&#xff1a; 游戏状态&a…

QT播放gstreamer命令(三)---使用QMediaPlayer

前文: 因为之前听说过,QMediaPlayer已经集成了gstreamer,但是并没有什么接口来例子来说明,根本看不出来有任何gstreamer的形式,于是在QT5助手里面搜了一下,发现确实有gstreamer的痕迹,但是例子写的极其拉胯,经过自己尝试,终于发现了一种直接使用QMediaPlayer播放gstre…

uniapp中组件库Mask 遮罩层 的使用方法

目录 #平台差异说明 #基本使用 #嵌入内容 #遮罩样式 #API #Props #Events #Slot 创建一个遮罩层&#xff0c;用于强调特定的页面元素&#xff0c;并阻止用户对遮罩下层的内容进行操作&#xff0c;一般用于弹窗场景 #平台差异说明 AppH5微信小程序支付宝小程序百度小程…

将链表反转

反转链表在解决需要从尾节点开始遍历到头节点的地方很实用&#xff0c;是一种常用的解题技巧。在反转时&#xff0c;我们可以考虑从前向后反转和从后向前反转两种方式。 法一&#xff1a;递归 每次将链表的头节点的下一个节点作为新的头节点&#xff0c;然后对剩余部分调用递归…

阿里云OSS对象存储

一、前言 阿里云对象存储OSS作用&#xff1a;用于存储图片、视屏、文件等数据。 参考阿里云文档地址&#xff1a;阿里云对象存储教程 二、总体思路 说明&#xff1a;客户端给服务端发送请求&#xff0c;获取policy和signature等数据&#xff08;服务端提供&#xff09;&#…

前端小案例——导航回顶部(HTML+CSS+JS, 附源码)

一、前言 实现功能&#xff1a; 这个案例实现了页面滚动到一定位置时显示"回到顶部"按钮&#xff0c;并且点击按钮能够平滑滚动回页面顶部的功能。 实现逻辑&#xff1a; 页面结构&#xff1a;通过HTML标签定义了页面的基本结构。页面主要由多个div.content组成&am…

MySQL-----初识

一 SQL的基本概述 基本概述 ▶SQL全称: Structured Query Language&#xff0c;是结构化查询语言&#xff0c;用于访问和处理数据库的标准的计算机语言。SQL语言1974年由Boyce和Chamberlin提出&#xff0c;并首先在IBM公司研制的关系数据库系统SystemR上实现。 ▶美国国家标…

如何解决 docker registry x509 证书不信任问题?

最近想尝试一下极狐GitLab&#xff08;可以理解为 GitLab 在中国的发行版&#xff09;内置的容器镜像仓库&#xff0c;这样就不用自己安装 Harbor 之类的了。于是找了个服务器安装了一个极狐GitLab 的私有化部署版本&#xff0c;安装过程可以参考过往的技术文章使用Omnibus 安装…

刨析数据结构(二)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;数据结构————"带你无脑刨析" &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于数据结构的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎…

Day06-Linux下目录命令讲解及重要文件讲解

Day06-Linux下目录命令讲解及重要文件讲解 1. Linux目录文件1.1 Linux系统目录结构介绍1.1.1 Linux与Windows目录结构对比 1.2 重要的Linux配置文件介绍1.2.1 /etc系统初始化及设置相关重要文件1.2.2 /usr目录的重要知识介绍------应用程序目录1.2.3 /var目录下的路径知识-----…

Qt|制作简单的不规则窗体

通常我们用到的对话框基本上都是规则的&#xff0c;在有些特殊情况下&#xff0c;也会使用到不规则窗口&#xff0c;那么该如何实现不规则窗体呢&#xff1f; 在MFC框架下很难实现&#xff0c;应该说是难的都想放弃&#xff0c;但是&#xff0c;Qt框架下提供了一个叫做setMask…

【JAVA】守护线程是什么?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 正文 我的其他博客 正文 在计算机编程中&#xff0c;守护线程&#xff08;daemon thread&#xff09;是一种在程序运行时在后台提供服务的线程…

【正点原子STM32连载】 第四十七章 FATFS实验 摘自【正点原子】APM32E103最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子APM32E103最小系统板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/docs/boards/xiaoxitongban 第四…

【模型微调】| 各类微调模型总结 P-Tuning,Prefix,P-tuning v2,LoRA

文章目录 1 微调背景1.1 Full fine-tuning 全参数微调&#xff08;FFT&#xff09;1.2 parameter-Efficient-fine-tuning 部分参数微调&#xff08;PEFT&#xff09; 2 提示词调整训练法2.1 P-Tuning2.2 Prefix2.3 P-Tuning v2 3 结构调整训练法3.1 Adapter tuning3.2 LoRA 微调…

【2024年美国大学生数学建模竞赛】F题非法的野生动物贸易 完整数据

小云更新了全网最全的F题数据 另外也为大家分享&#xff1a; 技术文档&#xff0c;包括问题分析、建立模型、求解结果等&#xff0c;配套有思路分析视频、代码讲解视频。美赛官方限制总页数为25页&#xff0c;我们的思路长度为35页以上。所有模型都有求解代码和指标&#xff0…

数字化转型:企业适应新常态的关键之举_光点科技

在全球商业环境不断演变和技术日新月异的背景下&#xff0c;数字化转型已经成为企业不可回避的课题。它不仅关乎企业的未来生存与发展&#xff0c;更是适应新常态、提升竞争力的关键之举。但是&#xff0c;数字化转型并非一夜之间可以完成的任务&#xff0c;它需要全面的策略规…

九、显卡性能参数、接口

1、显卡说明 显卡的好坏直接影响画面的流畅度&#xff0c;一般大型游戏都会有一些电脑的推荐配置&#xff0c;里面就会说到显卡。 显卡&#xff0c;也称为显示卡&#xff08;Video Card&#xff09;&#xff0c;是个人计算机基础的组成部分之一&#xff0c;负责将计算机系统需要…

前缀和 差分

差分和前缀和都是算法里边比较重要的知识点&#xff0c;不过学习的难度并不高&#xff0c;这篇文章会讲解相关的内容。 1. 前缀和怎么玩 1&#xff09;一维前缀和 在该数之前&#xff0c;包括该数的所有数之和&#xff0c;有点类似高中学的数列的前n项和Sn。 2&#xff09;二维…

2024年美赛A题:资源可用性和性别比例 Resource Availability and Sex Ratios 思路模型代码解析

2024年美赛A题&#xff1a;资源可用性和性别比例 Resource Availability and Sex Ratios 思路模型代码解析 【点击最下方群名片&#xff0c;加入群聊&#xff0c;获取更多思路与代码哦~】 问题翻译 虽然一些动物物种存在于通常的雄性或雌性之外&#xff0c;但大多数物种在很大…

ncc匹配(二,补足旋转)

先看运行结果&#xff1a; 第一张图是基于形状匹配结果0.992&#xff0c;第二张是匹配结果的ncc结果&#xff0c;1 再看旋转后&#xff1a; 看到没&#xff0c;旋转后&#xff0c;基于形状匹配结果28度&#xff0c;0.517&#xff0c;根据匹配结果ncc结果是0.99 我们看到ncc以…