VL53L0X 测距传感器使用记录

发布于:2024-10-09 ⋅ 阅读:(239) ⋅ 点赞:(0)
VL53L0X 测距传感器测试使用说明...... by 矜辰所致

前言

最近代理商告知以前使用的测距传感器 VL6180 公司已经宣告停产了,那么咱就得找一款替代品作为测距产品的探头了,推荐了 VL53L4 和 VL53L0X 系列,考虑到功耗问题,决定选用低功耗的 VL53L0X 。

那本文的我们的内容就是来说明一下 VL53L0X 的测试使用情况。

以前关于 TOF 测距传感器相关的文章有:
ToF 测距传感器 VL6180 使用踩坑记(软件 I2C)
ToF 测距传感器 VL6180 测量范围修改(软件 I2C)
ToF 测距传感器 VL53L5CX 使用记录
使用 C# 设计ToF测距传感器 VL53L5CX 上位机软件
.
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

一、 基本准备

其实在此之前我已经使用过 VL6180 和 VL53L5CX 系列,我们知道对于这些传感器, ST 官方都已经给出了 SDK 包,有些甚至可以直接使用 STM32CUBEMX 就可以一键生成测试代码。

本次的测试首先肯定是在 STM32 上面进行基本的测试,方便调试。 但是因为后期需要在 51 单片机上使用这个传感器,所以还必须研究下怎么移植一下代码。

因为有了前面使用传感器的经验,所以我们也不去买某宝现成的模块了,因为本来也不复杂,直接就结合自己产品需要,直接自己画板子测试了。

1.1 传感器板子设计

根据 VL53L0X 的使用手册,有使用原理图:

在这里插入图片描述

这里实际上和以前我们画过的 VL6180 也差不多:

在这里插入图片描述

所以我们直接在以前传感器小板子的原理图上修改一下:

在这里插入图片描述

改完以后看了下资料发现有点小纠结。

1.2 设计上的一点小纠结

为什么会有一点小纠结,因为我测试使用 STM32 ,用的是 3.3V 的系统,而我最终要用的平台是一款 51单片机,1.8V 的系统。

我们可以看到以前的VL6180 的原理图推荐:

在这里插入图片描述

在 VL53L0X 的推荐图上用写的是 IOVDD,然后通过搜索找到 IOVDD 的相关说明,发现默认为 1.8V 模式,感觉上来说,GPIO1 和 XSHUT 处于默认上拉倒 1.8V 模式,如果上拉倒2.8V还需要额外设置:

在这里插入图片描述

通过 VL53L0X 的手册来说,SDA,SCL,XSHUT 和 GPIO1 好像需要保存在同一电平,要么都是 2.8V 要么都是 1.8V ?

看上去和 VL6180 差不多,但是在以前 VL6180 的手册上面好像没有特别的说明,要保持在同一电平,所以在上面原理图可以看到 SDA SCL 小板子上是直接输出的,没有上拉,而 GPIO1 和 XSHUT 是上拉到 2.8V 的,因为以前的 VL6180 是这么设计来用的,在底板上,以前的VL6180 的 SDA 和 SCL 是上拉到 1.8V 的,也能正常使用。

某宝买的 VL53L0 小模块他都是上拉到 2.8V ,所以它上面会做好电平转换,它做的电平转换,主要是针对大部分 3.3V 的供电系统的。但是对于主要需要设计的产品,我使用的 MCU 的 IO 口是1.8V的, 即便做电平转换,方向与某宝的模块也是反的,因为我的 MCU 这边是电压低的一边,无法直接用某宝的模块。 而且我的 MCU 电压而且我也可以提供 1.8V 的电源以供 SDA 和 SCL 上拉,而且如果使用 1.8V 做 VL53L0 的 IOVDD ,我都可以省去电平转换。

想来想去,干脆小板子传感器 IO 都不上拉,在MCU 端自己做上拉和根据需要做电平转换。

所以图直接画成这样:

在这里插入图片描述

最后

在这里插入图片描述

1.3 MCU底板设计

传感器小板子简单的搞好了,那么我们测试板子还是用最常用的 STM32F103系列,那整体来说就是下面的图片,因为最小系统图我以前方案都上过了,这里简单看看:

在这里插入图片描述

其中与 VL53L0X 有关的部分我放大如下图,做了下电平转换,唯一需要注意的就是 电平转换的方向问题:

在这里插入图片描述

其中I2C接口连接到了硬件 I2C 的 PB6、PB7引脚上,这样我们还开始可以直接使用 ST 提供的软件包直接测试。

当然,我们除了使用标准的 SDK 包测试,我们还需要实现软件 I2C 的测试,因为我还需要一直到 51 单片机上去使用。

二、程序设计

传感器的测试,我们首先是通过 ST 官方提供的软件包测试的,我的计划是参考 VL53L5CX 使用记录 来进行。

2.1 STM32CubeMX 设置

基本设置我们就不在赘述了,以前好些文章都讲得很详细,时钟,调试接口,串口,根据原理图需要用到的 IO 口,硬件 I2C 接口等等。

在这里插入图片描述

完成上述步骤,我本想着直接在 CubeMX 里面找软件包,但是发现居然没有:

在这里插入图片描述

没有软件包的话,查了一下资料,只能自己移植官方的 API了。

既然要移植的话,那我们得修改一下 I2C 接口,不使用硬件 I2C ,直接把 SDA 和 SCL 设置为开漏输出,同时把 XSHUT 的 IO 口也定义一下,GPIO1 是传感器采集成功后的中断输出 IO ,我们移植包括后期使用基本都是单次测量,所以也不用。

修改完成后先生成工程,博主采用的是 GCC + VScode 开发 STM32 ,所以最后生成工程,稍微改一下 Makefile ,然后编译一下:

在这里插入图片描述

OK,程序基本框架准备好了,下面要开始官方 API 移植。

2.2 ☆ API 移植 ☆

我们先下载 VL53L0 软件包,ST官方的下载地址:ST官方 VL53L0 传感器API

下载好 解压出来有一个 VL53L0X_1.0.4 文件夹,这些年 API 都是这个版本没变过。

移植的装备工作其实我也参考了很多文章和视频,这里细节就不多赘述,我们直接开始尝试。

第一步,把 Api 文件夹拷贝至我们的工程,当然你可以重命名一下,我这里就直接拷贝过来:

在这里插入图片描述

然后我们添加文件尝试编译一下,因为已经参考过资料,所以先把 core 下面的文件添加,按理来说,这部分是直接编译没有问题的,如下图:

在这里插入图片描述

添加完以后编译一下,有警告,但是能够编译通过:

在这里插入图片描述

接下来就是来添加看看 platform 下面的东西了,根据参考过的资料,所谓移植,也就是我们要将 platform 下面的东西根据自己的硬件调整。 对于上面 通用的 API ,我们不用去修改,到时候直接调用。

移植的时候我也参考过很多文章和下载了很多的代码,都有可以直接用的,但是确实没有一步一步怎么操作来说明的,所以我这边还是根据自己的想法来走了一遍,当然,有些例程其实稍微修改一下 IO 口,直接跑人家的示例出结果还是不难的。只是我要考虑到后期,我还得放在 51 平台,必须得自己走一遍整的。

自己也走了一些弯路,中间一些过程省略,我们直接删除 platform 下面的几个文件,只留 2 个,其实一个不留也是可以,完全按照我们自己的来也没问题,但是这里考虑到和 API 的连接性,我们还是按照 platform 下面的函数原型来修改。

如下图,我们只留下2个文件, 其中vl53l0x_i2c_platform.c 是操作 I2C 读取相关 和一些延时什么的,而 vl53l0x_platform.c 主要用于提供 API 库通过 IIC 访问 VL53L0X 的操作函数 ,它会调用到vl53l0x_i2c_platform.c 里面的一些函数。

  • 我们直接把 vl53l0x_i2c_platform.c 所有的函数内容都删除(不是删除函数,是直接返回值,当然记得要备份,后期还要一点一点加上去)防止报错,主要修改的就是这个文件,我后面直接上代码;
  • 不需要的那些头文件,比如那个什么 Windows.h 都去掉。
  • 当然头文件路径什么的不要忘了添加,我这里在 Makefile 里面添加。

在这里插入图片描述

vl53l0x_platform.c 里面,去掉了 Windows.h ,去掉了打印 LOG 相关,还有一个延时函数,也给他改掉:
在这里插入图片描述

保证编译没有错误了,我们再开始添加代码:

在这里插入图片描述

在添加代码之前我们要明白,我们使用软件 I2C 通讯,我们分为 I2C 通讯的通用驱动 和 与传感器有关的驱动,通用驱动就包括了 ,I2C 启动,结束,发送等待 ACK ,发送不等待 ACK ,读取,等待 ACK 等等这些函数,这些在我以前一直 I2C 通讯的文章中都有提到,当然,通用驱动与我们的硬件是有关系的,直接操作 硬件的 IO 口实现的。

大家手头肯定也有以往的可以参考的 I2C 驱动代码,就不太多说,我们直接新建 2 个文件,放 I2C 通用驱动。

放在 API 文件夹下面:

在这里插入图片描述

这里就直接上一下源码,其实基本和以前的一样。

2.2.1 通用驱动

my_i2c_com.c

#include "my_i2c_com.h"

void delay_us(uint32_t Delay)
{
  uint32_t cnt = Delay * 12;   // 72Mhz ,其他频率其他倍数
  uint32_t i = 0;
  for(i = 0; i < cnt; i++)__NOP();
}

// ------------------------------------------------------------------
void i2c_init(void)  {
  
// the SDA and SCL pins are defined as input with pull up enabled
  // pins are initialized as inputs, ext. pull => SDA and SCL = high

}
// ------------------------------------------------------------------
// send start sequence (S)

void i2c_start(void)  {                                    
  	SDA_HIGH; 
		delay_us(5);
  	SCL_HIGH;		
		delay_us(5);
  	SDA_LOW;	
		delay_us(5);
	SCL_LOW;                                                   
		delay_us(5);
}

// ------------------------------------------------------------------
// send stop sequence (P)
void i2c_stop(void)  { 
	SCL_LOW;                             
  	SDA_LOW;                                                                          
		// delay_us(5);                                 
		delay_us(5);                                 
  	SCL_HIGH;                                         
		delay_us(5);                                       
  	SDA_HIGH;
		delay_us(5);
}


/******************************************************************
 * 函 数 返 回:0有应答  1超时无应答
******************************************************************/
u8 i2c_wait_ack(void)
{
    u8 ucErrTime=0;
	
    SDA_HIGH;delay_us(5);       //MCU DATA 置高,外面高就是高,外面低就是低
    SCL_HIGH;delay_us(5);       //CLK 高电平期间数据有效
    while(IIC_DATA_STATE)             //低电平为有应答,高电平无应答    
    {
      ucErrTime++;
		if(ucErrTime>250)
		{
			i2c_stop();
			return 1;
		}  
    }
	
    SCL_LOW;
	delay_us(5);
    return 0;
}


void iic_ack(void)
{
	SCL_LOW;    //SCL为低,SDA为低,SCL为高,SDA为低,应答低电平有效,SCL为低,产生应答信号
	// MYSDA_OUT;
	SDA_LOW;
	delay_us(5);
	SCL_HIGH;
	delay_us(5);
	SCL_LOW;
	delay_us(5);
	SDA_HIGH;
}

void iic_nack(void)
{
	SCL_LOW;     //SCL为低,SDA为高,SCL为高,SCL为低
	// MYSDA_OUT;
	SDA_HIGH;
	delay_us(5);
	SCL_HIGH;
	delay_us(5);
	SCL_LOW;
}


//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 i2c_read_byte(unsigned char ack)
{
	unsigned char i,receive=0;
	// MYSDA_IN;//SDA设置为输入
   	for(i=0;i<8;i++)
	{
        SCL_LOW;    //SCL为由低变高,在SCL高的时候去读 SDA的数据
        delay_us(4);
		SCL_HIGH;
        receive<<=1;  //第一次这里还是0,第二次开始每次接收的数据做移动一位,从高位开始接收
        if(IIC_DATA_STATE)receive++;   //如果数据为1,++以后就是1,数据为0,不执行就是0; 
		delay_us(5); 
   	}					 
   if (!ack)
        iic_nack();//发送nACK
   else
        iic_ack(); //发送ACK   
   return receive;
}

//IIC发送一个字节
	  
void i2c_send_byte(u8 txd)
{                        
   u8 t;   
	// MYSDA_OUT; 	    
   SCL_LOW;  //拉低时钟开始数据传输   ,SCL为低,SDA变高或者变低(数据位),SCL变高,SCL变低,期间SDA为1既1,为0既0
   for(t=0;t<8;t++)  //一个字节8位,一位一位发送
    {              
        SCL_LOW;
		if((txd&0x80)>>7)   //从最高位开始发送,如果是1,发送高电平
			SDA_HIGH;
		else
			SDA_LOW;
		
		delay_us(5);   //对TEA5767这三个延时都是必须的
		SCL_HIGH;
		delay_us(5); 
		SCL_LOW;	
		delay_us(5);
		txd<<=1; 	      //SDA处理完毕,此时可以将SCL拉高接受数据,拉高以后延时拉低
    }	 
}


my_i2c_com.h

#ifndef _I2C_H_INCLUDED
#define _I2C_H_INCLUDED

#include "main.h"
#include "Datadef.h"
                         
// ------------------------
#define DONOTHING()          {;}

// ------------------------
// command's
#define I2C_WRITE             0 
#define I2C_READ              1
#define I2C_ACK               0
#define I2C_NACK              1


#define SCL_HIGH                HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_SET) 
#define SCL_LOW  	            HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_RESET) 

#define SDA_HIGH                HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_SET) 
#define SDA_LOW                 HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_RESET)
#define IIC_DATA_STATE          HAL_GPIO_ReadPin(SDA_GPIO_Port,SDA_Pin)
#define sda_read()              HAL_GPIO_ReadPin(SDA_GPIO_Port,SDA_Pin)

void delay_us(uint32_t Delay);

void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);

u8 i2c_wait_ack(void);
void iic_nack(void);
void iic_ack(void);
void i2c_send_byte(u8 txd);
u8 i2c_read_byte(unsigned char ack);

#endif

2.2.2 vl53l0x_i2c_platform.c

写好通用的 I2C 驱动以后,我们还需要使用我们的通用驱动把 vl53l0x_i2c_platform.c 里面的函数补充完整。

这里有个问题需要说明,就是 地址变量 address 在函数中是否要左移一位的问题,这个要注意自己移植的程序把 VL53L0X 的地址定义为 0x29 还是定义为 0x52 ,因为不同人移植的驱动习惯不一样,要不要把读写位定义在地址上这个看自己,不要盲目的直接移植而忽略这个地方导致移植不成功 。

直接上一下 vl53l0x_i2c_platform.c 代码 :

/*

*/

#include <stdio.h>    // sprintf(), vsnprintf(), printf()

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

#include "vl53l0x_i2c_platform.h"
#include "vl53l0x_def.h"
#include "my_i2c_com.h"

char  debug_string[VL53L0X_MAX_STRING_LENGTH_PLT];

#define MIN_COMMS_VERSION_MAJOR     1
#define MIN_COMMS_VERSION_MINOR     8
#define MIN_COMMS_VERSION_BUILD     1
#define MIN_COMMS_VERSION_REVISION  0

#define STATUS_OK              0x00
#define STATUS_FAIL            0x01


int32_t VL53L0X_comms_initialise(uint8_t comms_type, uint16_t comms_speed_khz)
{
    // 这里是硬件初始化,我们在 GPIO 口初始化的时候已经把这个完成了,这里就空着
    return STATUS_OK;
}

int32_t VL53L0X_comms_close(void)
{
    return STATUS_OK;
}


int32_t VL53L0X_write_multi(uint8_t address, uint8_t index, uint8_t *pdata, int32_t count)
{
    int32_t i; 
    i2c_start();
    // i2c_send_byte((address << 1) | 0);
    i2c_send_byte(address| 0);
    if (i2c_wait_ack() == 1)
    {
        i2c_stop();
        return STATUS_FAIL;
    }
    i2c_send_byte(index);
    if (i2c_wait_ack() == 1)
    {
        i2c_stop();
        return STATUS_FAIL;
    }
    for (i=0; i<count; i++)
    {
        i2c_send_byte(pdata[i]);
        if (i2c_wait_ack() == 1)
        {
            i2c_stop();
            return STATUS_FAIL;
        }
    }
    i2c_stop();

    return STATUS_OK;
}

int32_t VL53L0X_read_multi(uint8_t address, uint8_t index, uint8_t *pdata, int32_t count)
{
    i2c_start();
    // i2c_send_byte((address << 1) | 0);
    i2c_send_byte(address| 0);
    if (i2c_wait_ack() == 1)
    {
        i2c_stop();
        return STATUS_FAIL;
    }
    i2c_send_byte(index);
    if (i2c_wait_ack() == 1)
    {
        i2c_stop();
        return STATUS_FAIL;
    }
    i2c_start();
    // i2c_send_byte((address << 1) | 1);
    i2c_send_byte(address| 1);
    if (i2c_wait_ack() == 1)
    {
        i2c_stop();
        return STATUS_FAIL;
    }
    while (count)
    {
        *pdata = i2c_read_byte((count > 1) ? 1 : 0);
        count--;
        pdata++;
    }
    i2c_stop();
    return STATUS_OK;
}


int32_t VL53L0X_write_byte(uint8_t address, uint8_t index, uint8_t data)
{
    int32_t status = STATUS_OK;
    const int32_t cbyte_count = 1;
    status = VL53L0X_write_multi(address, index, &data, cbyte_count);
    return status;

}


int32_t VL53L0X_write_word(uint8_t address, uint8_t index, uint16_t data)
{
    int32_t status = STATUS_OK;
    
    uint8_t  buffer[BYTES_PER_WORD];
    
    // Split 16-bit word into MS and LS uint8_t
    buffer[0] = (uint8_t)(data >> 8);
    buffer[1] = (uint8_t)(data &  0x00FF);
    
    status = VL53L0X_write_multi(address, index, buffer, BYTES_PER_WORD);
    
    return status;
}


int32_t VL53L0X_write_dword(uint8_t address, uint8_t index, uint32_t data)
{
    int32_t status = STATUS_OK;
    uint8_t buffer[BYTES_PER_DWORD];
    
    // Split 32-bit word into MS ... LS bytes
    buffer[0] = (uint8_t) (data >> 24);
    buffer[1] = (uint8_t)((data &  0x00FF0000) >> 16);
    buffer[2] = (uint8_t)((data &  0x0000FF00) >> 8);
    buffer[3] = (uint8_t) (data &  0x000000FF);
    
    status = VL53L0X_write_multi(address, index, buffer, BYTES_PER_DWORD);
    
    return status;
}


int32_t VL53L0X_read_byte(uint8_t address, uint8_t index, uint8_t *pdata)
{
    int32_t status = STATUS_OK;
    int32_t cbyte_count = 1;
    
    status = VL53L0X_read_multi(address, index, pdata, cbyte_count);
    
    return status;
}



int32_t VL53L0X_read_word(uint8_t address, uint8_t index, uint16_t *pdata)
{
    int32_t status = STATUS_OK;
    uint8_t buffer[BYTES_PER_WORD];
    
    status = VL53L0X_read_multi(address, index, buffer, BYTES_PER_WORD);
    *pdata = ((uint16_t)buffer[0]<<8) + (uint16_t)buffer[1];
    
    return status;
}

int32_t VL53L0X_read_dword(uint8_t address, uint8_t index, uint32_t *pdata)
{
    int32_t status = STATUS_OK;
    uint8_t buffer[BYTES_PER_DWORD];
    
    status = VL53L0X_read_multi(address, index, buffer, BYTES_PER_DWORD);
    *pdata = ((uint32_t)buffer[0]<<24) + ((uint32_t)buffer[1]<<16) + ((uint32_t)buffer[2]<<8) + (uint32_t)buffer[3];
    
    return status;
}

int32_t VL53L0X_platform_wait_us(int32_t wait_us)
{
    delay_us(wait_us);
    return STATUS_OK;
}


int32_t VL53L0X_wait_ms(int32_t wait_ms)
{
    HAL_Delay(wait_ms);
    return STATUS_OK;
}


int32_t VL53L0X_set_gpio(uint8_t level)
{
    return STATUS_OK;
}


int32_t VL53L0X_get_gpio(uint8_t *plevel)
{
    return STATUS_OK;
}


int32_t VL53L0X_release_gpio(void)
{
    return STATUS_OK;
}

int32_t VL53L0X_cycle_power(void)
{
    return STATUS_OK;
}


int32_t VL53L0X_get_timer_frequency(int32_t *ptimer_freq_hz)
{
       *ptimer_freq_hz = 0;
       return STATUS_FAIL;
}


int32_t VL53L0X_get_timer_value(int32_t *ptimer_count)
{
       *ptimer_count = 0;
       return STATUS_FAIL;
}

2.2.3 vl53l0x_platform.c

前面也说到过 vl53l0x_platform.c 大多都是对 vl53l0x_i2c_platform.c 函数的应用,只需要修改下头文件包含,和一个延时函数,其他的大家可以自己修改也没什么问题。

到这里,基本上驱动移植算是完成了,但是呢,我们也要知道怎么用起来。

三、测试

实际上,怎么用起来应该是驱动移植前要了解的事情,要说起来,其实细节也挺多的,大家可以自己参考官方的文档研究,也可以去网上找找前人的细节分析,这里有一篇文章讲解得比较细,大家可以参考一下:

激光测距芯片VL53L0X的使用与代码

对于我们测试来说,这里有两个图说明一下,一个是传感器的工作流程图,如下图:

在这里插入图片描述

还有一个是传感器工作模式,如下图:

在这里插入图片描述

上面两个都关系到我们程序中的配置,所以确定了这个,我们在调用函数的时候,有一些参数也知道怎么设置,也知道什么意思了。

但是我测试的时候,参考了网上很多版本的代码,刚开始也遇到了莫民奇妙的问题,本来想着自己根据流程理解,一步一步的写一下,发现花费了好些精力却没成功… 这个过程其实也没太大意义,自己花费时间自己琢磨,这里就不细说了。

后来一不做二不休,直接在别人代码上面修改测试成功的。

基本上网上所有有关 VL53L0X 有关能用的示例我都下载了 = =! 正点原子,野火,包括一些博客论坛上人家推荐的,基本上我都测试过,最后我成功的测试移植了 “ 表面上看起来4个不同的示例 ”。

于是我的工程目录变成这样:

在这里插入图片描述

用起来的话,直接调用示例函数即可(整个工程包,我会上传至资源,大家可以下载):

在这里插入图片描述

3.1 测试效果展示

下面上一下我测试成功过的不同的示例效果:

vl53l0_demo1:

在这里插入图片描述

vl53l0_demo2:

在这里插入图片描述

vl53l0_demo3:

在这里插入图片描述

vl53l0_demo4:

在这里插入图片描述

3.2 一些使用说明

3.2.1 校准问题

上面的示例只要能够读到数据,还是很准确的,我也没有校准 。

那这里正好说明一个问题,不校准能不能测量? 答案当然是可以的。

ST 官方出厂的时候就做好了校准,实际使用中会有偏差是因为我们的被测物体的面不是那么完美,比如表面的反射率,和颜色等问题都会影响测量。

但是如果现场环境误差过大,还是需要校准的,具体校准的步骤,我这边也没有研究过,大家可以根据上面推荐的博文自行研究。

根据我实际测试的情况来看,出厂的校准已经是很好的。

3.2.2 使用环境问题

对于 VL53L0X 来说,他的使用环境也是有一定要求的,具体如下:

  • 黑暗无红外,目标为白色,且被测物面积要覆盖整个测量区域;
  • 在室内裸露测量,环境内的红外光会影响测量精度;
  • 不是随便找个物体就能测的,目标为白色时误差最小,颜色越深误差越大;
  • datasheet 上注明了测量角度是25°,1m 远的白色物体要求面积在 0.45㎡ 以上才能保证测量精度,当然面积不够也能测,就是误差大一点,在被测区域内最好没有其他物体干扰。

3.2.3 测量盲区

此类测距的传感器都会有一个测量盲区,就是小于多少距离是测量不出来的(距离太小,激光无法走一个正常的来回),以前的 VL6180 的盲区大概在 4mm 以内。

VL53L0X 的测量盲区是 在 40mm 以内。

结语

本文跨度时间有点久,因为从一开始的硬件设计就开始写了,然后等到板子到了以后的测试,都花了一定的时间,不过最终也算是测试成功了。

虽然测试完了,但是有些小细节其实也没有搞明白,比如工作 1.8V 模式,还是 2.8V 模式的问题,在一直期间去看过源码,是根据是否有宏定义来判断工作在什么模式,但是测试起来,并没有注意到哪里有特意的去修改,或许是因为网络上绝大多数的例程和大多数人的使用场景,基本都是2.8V 模式,所以没有特意的去说明。

还有一个因为我目前的使用场景需要的距离不远,所以我只测试了小于 500mm 的距离,对于再远一点的距离,因为没有用到,也没有特意的去测量。

那么这些细节,如果在以后有遇到再来补充说明,好歹 VL53L0X 传感器我们也成功用起来了。

另外,最后整个工程我上传到了资源,大家有需要自行下载:

VL53L0X 测试项目(by 矜辰所致)

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


网站公告

今日签到

点亮在社区的每一天
去签到