我是靠谱客的博主 粗心诺言,最近开发中收集的这篇文章主要介绍【12月】RT-Thread VL53L0X TOF传感器驱动实现前言1 简介2 传感器介绍3 软件实现4 使用说明5 代码仓库6 相关文章,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 前言
  • 1 简介
    • 1.1 目录结构
    • 1.2 许可证
  • 2 传感器介绍
    • 2.1 应用场合
    • 2.2 电路原理图
  • 3 软件实现
    • 3.1 支持情况
    • 3.2 vl53l0x 软件库
    • 3.3 vl53l0x 软件库适配
      • 3.3.1 platform微调
      • 3.3.2 实例化
    • 3.4 测量功能
      • 3.4.1 测量模式
      • 3.4.2 测量精度
      • 3.4.3 测量方式
      • 3.4.4 测量流程
  • 4 使用说明
    • 4.1 依赖
    • 4.2 获取软件包
    • 4.3 初始化
    • 4.4 读取数据
    • 4.5 msh/finsh测试
  • 5 代码仓库
  • 6 相关文章


前言

  Time of flight(TOF),中文翻译为“飞行时间”。飞行时间技术在广义上可理解为通过测量物体、粒子或波在固定介质中飞越一定距离所耗费时间(介质/距离/时间均为已知或可测量),从而进一步理解离子或媒介某些性质的技术。TOF的基本原理是通过灯光发射器发射光脉冲,遇到障碍物后反射;接收器接收反射回来的光脉冲,并根据光脉冲的往返时间计算与物体之间的距离。


在这里插入图片描述

TOF 测量原理


1 简介

  vl53l0x软件包是基于RT-Thread sensor框架实现的一个驱动包。基于该软件包,RT-Thread应用程序可以使用标准的sensor接口访问vl53l0x,获取传感器数据。源码地址,点击下载。


1.1 目录结构

名称说明
docs文档目录
vl53l0x官方库函数以及i2c platform对接
examples例子目录
inc头文件目录
src源代码目录
LICENSE许可证文件
SConscriptRT-Thread默认构建脚本

1.2 许可证

  vl53l0x软件包遵循 Apache license v2.0 许可,详见 LICENSE 文件。


2 传感器介绍

  vl53l0x是 STMicroelectronics(意法半导体)公司推出的新一代单点TOF(Time of Flight)传感器,具备体积小、测量精度高、测量距离远、无需增加外部光学器件、使用简单等优点;此外,vl53l0x采用940nm肉眼不可见光源,集成物理红外过滤器,提高对环境光的抗干扰特性,具备良好的鲁棒性和防光学串扰特性。


在这里插入图片描述

vl53l0x 框图


测量参数:

功能量程分辨率精度
距离0—2000mm1mm

2.1 应用场合

  vl53l0x 是一个单分辨率的TOF传感器,适用于一些功能比较单一的场合。

  • 相机对焦
  • 1D手势识别
  • 白色家电检测(额温枪、水龙头、皂液分配器)
  • 数码电子(笔记本、平板、手机)用户检测
  • 机器人避障

2.2 电路原理图

  vl53l0x 硬件原理图比较简单,只需单电源供电,与CPU通过i2c总线进行交互数据;XSHUT控制芯片睡眠/正常工作;GPIO1为芯片中断信号输出,开漏状态,可产生一个中断信号通知CPU读取数据。


在这里插入图片描述

vl53l0x 原理图


3 软件实现

3.1 支持情况

包含设备TOF
通信接口
IIC
SPI
工作模式
轮询
中断
FIFO
电源模式
掉电
低功耗
普通

注:

目前暂时只支持单次测量模式;后续增加:

  • 连续测量模式
  • 定时测量模式
  • 测距校准功能

3.2 vl53l0x 软件库

  ST并未给出vl53l0x 的详细寄存器描述手册,而是以开源库的方式提供给用户使用,即是vl53l0x 软件库。vl53l0x 软件库将芯片的功能封装成一个API接口,我们使用时无需关心其内部原理、实现及寄存器访问过程,直接调用其相关API即可实现具体功能。vl53l0x 软件库提供的功能包括:

  • 初始化
  • 校准
  • 测距控制
  • 精度设置
  • 测距模式选择
  • 以及内部计算核心算法、自定义字符串处理等等。


    在这里插入图片描述
vl53l0x 软件库

3.3 vl53l0x 软件库适配

  vl53l0x 提供了一套完整功能的API,正确使用这些API前,需把该库适配到我们的软件系统(RT-Thread)上。适配vl53l0x 库也非常简单,只需重写platform层的函数接口接口。


3.3.1 platform微调

  vl53l0x platform层提供了一个设备数据结构VL53L0X_Dev_t,vl53l0x 软件库中所有API都会调用到该设备,该设备定义位于vl53l0x_platform.h中,我们需实例化该数据结构。

typedef struct {
    VL53L0X_DevData_t Data;               /*!< embed ST Ewok Dev  data as "Data"*/

    /*!< user specific field */
    uint8_t   I2cDevAddr;	/* 器件地址 */
    char    DevLetter;
    int     Id;
    int     Present;
    int 	Enabled;
    int		Ready;

    uint8_t   comms_type;	  /* 总线类型,1表示i2c */
    uint16_t  comms_speed_khz;/* i2c总线速率 */

    int LeakyRange;
    int LeakyFirst;
    uint8_t RangeStatus;
    uint8_t PreviousRangeStatus;
    FixPoint1616_t SignalRateRtnMegaCps;
    uint16_t EffectiveSpadRtnCount;
    uint32_t StartTime;
	reg_wr_t RegRead;	/* 读寄存器函数 */
	reg_wr_t RegWrite;  /* 写寄存器函数 */
} VL53L0X_Dev_t;

  对于该数据结构,这里我们做了稍微改动,以适配RT-Thread, RegReadRegWrite是新增的寄存器访问函数指针,最终会调用RT-Thread的i2c设备接口访问。
/* 寄存器访问函数指针声明 */
typedef int32_t (*reg_wr_t)(uint8_t slave_addr, uint8_t reg_addr,
		uint8_t *data, uint16_t len);
  • slave_addr,器件地址
  • reg_addr,寄存器地址
  • data,读/写数据内存起始地址
  • len,读/写数据长度

  因此, 对于VL53L0X_Dev_t数据结构,我们关注而且需要实现的成员包括几个。
  • 器件地址I2cDevAddr
  • i2c总线速率comms_speed_khz
  • 读寄存器函数指针RegRead
  • 写寄存器函数指针RegWrite

  其次,调整vl53l0x_platform.cvl53l0x_platform.c提供了一些了寄存器访问函数体,包括:

VL53L0X_Error VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, 
								uint8_t *pdata, uint32_t count);
VL53L0X_Error VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, 
								uint8_t *pdata, uint32_t count);
VL53L0X_Error VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data);
VL53L0X_Error VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data);
VL53L0X_Error VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data);
VL53L0X_Error VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data);
VL53L0X_Error VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data);
VL53L0X_Error VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data);
VL53L0X_Error VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData);

  这些函数由软件库调用,函数体内部是实现对寄存器访问。这里分别对上述函数体修改,通过以下两个函数进行访问寄存器。
static VL53L0X_Error Vl53l0xWriteRegs(VL53L0X_DEV dev, uint8_t reg, 
									  uint8_t *data, uint8_t data_size)
{
	return dev->RegWrite(dev->I2cDevAddr, reg, data, data_size);
}

static VL53L0X_Error Vl53l0xReadRegs(VL53L0X_DEV dev, uint8_t reg, 
									 uint8_t *data, uint8_t data_size)
{
	return dev->RegRead(dev->I2cDevAddr, reg, data, data_size);
}

3.3.2 实例化


● i2c寄存器访问函数

/* vl53l0x.c */
int32_t vl53l0x_write_regs(uint8_t slave_addr, uint8_t reg, uint8_t *data, uint16_t data_size)
{
  	struct rt_i2c_msg msg[2]={0};
	
    msg[0].addr		= slave_addr;
    msg[0].flags	= RT_I2C_WR;
    msg[0].len   	= 1;
    msg[0].buf   	= &reg;
    msg[1].addr  	= slave_addr;
    msg[1].flags	= RT_I2C_WR | RT_I2C_NO_START;
    msg[1].len   	= data_size;
    msg[1].buf   	= data;
    if(rt_i2c_transfer(i2c_bus_dev, msg, 2) == 2)
	{
        return RT_EOK;
    }
    else
    {
	  	LOG_E("i2c bus write failed!rn");
        return -RT_ERROR;
    }
}

int32_t vl53l0x_read_regs(uint8_t slave_addr, uint8_t reg, uint8_t *data, uint16_t data_size)
{
  	struct rt_i2c_msg msg[2]={0};
	
    msg[0].addr  = slave_addr;
    msg[0].flags = RT_I2C_WR;
    msg[0].len   = 1;
    msg[0].buf   = &reg;
    msg[1].addr  = slave_addr;
    msg[1].flags = RT_I2C_RD;
    msg[1].len   = data_size;
    msg[1].buf   = data;

    if(rt_i2c_transfer(i2c_bus_dev, msg, 2) == 2)
	{
        return RT_EOK;
    }
    else
    {
	  	LOG_E("i2c bus read failed!rn");
        return -RT_ERROR;
    }
}

● 重写delay函数,一般调用系统的sleep;测距是一个阻塞过程,如果是sleep 会挂起当前线程;该函数不能为空,否则函数返回超时错误码

/* vl53l0x_platform.c */
#define VL53L0X_OsDelay(...) rt_thread_delay(1) 

● power控制脚,GPIO驱动;如不需要控制,可以保持高电平
● 中断信号映射,可以不用


  最后,在初始化函数中注册VL53L0X_Dev_t设备。

static VL53L0X_Dev_t vl53l0x_dev = /* vl53l0x device */
{
	.comms_type = 1,
	.comms_speed_khz = 400,
};
vl53l0x_dev.I2cDevAddr = (rt_uint32_t)(cfg->intf.user_data) & 0xff;
vl53l0x_dev.RegRead = vl53l0x_read_regs;
vl53l0x_dev.RegWrite = vl53l0x_write_regs;

3.4 测量功能

3.4.1 测量模式

  vl53l0x提供三种测量模式,分别是单次测量(Single ranging)、连续测量(Continuous ranging)、定时测量(Timed ranging)。

  • 单次测量,只测量一次,测量完毕处于待机状态,需再一次触发才会测量
  • 连续测量,启动测量后会连续测量,除非用户主动停止
  • 定时测量,用户指定测量周期的连续测量

3.4.2 测量精度

  vl53l0x提供四种测距精度选择,默认配置、高速测距、高精度测距、长距离测距。这四种模式的适用于不同场合,优缺点互补。


测距精度测量耗时(ms)测量距离(m)典型应用场景
默认301.2通用
高速201.2±5%速度优先
高精度2001.2±3%精确测量
长距离332黑暗条件(无红外线)

3.4.3 测量方式

  • 轮询,测距线程周期调用API测距,获取距离;该方式消耗一定CPU资源。
  • 中断,VL53L0X测量完毕通过GPIO1发送中断信号,通知测距线程读取数据;该方式效率比较高,消耗CPU资源少。

3.4.4 测量流程

  vl53l0x用户手册提供了一个轮询方式的测距流程图,根据该流程图调用相应的库函数API即可完成一个测量过程。


在这里插入图片描述

vl53l0x 测量流程


4 使用说明

4.1 依赖

  • RT-Thread 4.0.0+

  • sensor 框架组件

  • I2C 驱动,vl53l0x使用 I2C 进行数据通讯,需要系统 I2C 驱动框架支持

  • PIN驱动,用于vl53l0x开关机(复位)引脚控制


4.2 获取软件包

  使用 vl53l0x package 需要在 RT-Thread 的包管理器中选择它,具体路径如下。然后让 RT-Thread 的包管理器自动更新,或者使用 pkgs --update 命令更新包到 BSP 中。如需使用示例程序,则使能Enable vl53l0x sample

RT-Thread online packages --->
    peripheral libraries and drivers --->
        sensors drivers --->
            [*] VL53L0X Time of flight(TOF) sensor.
            		[*] Enable vl53l0x sample
                    Version (latest)  --->

Version:软件包版本选择,默认选择最新版本。


4.3 初始化

  vl53l0x软件包初始化函数如下所示:

int rt_hw_vl53l0x_init(const char *name, struct rt_sensor_config *cfg,
                       rt_base_t xsht_pin);
参数描述
name传感器名称
cfgsensor配置信息
xsht电源控制GPIO
返回
RT_EOK初始化成功
-RT_ERROR初始化失败

  该函数需要由用户调用,函数主要完成的功能有:

  • 根据配置信息配置i2c名称、i2c地址等(可增加其他配置信息),然后初始化设备

  • 选择电源控制GPIO

  • 注册相应的传感器设备,完成 vl53l0x设备的注册


参考示例:

#include "vl53l0x.h"

static int rt_hw_vl53l0x_port(void)
{
    struct rt_sensor_config cfg;
    	
	cfg.intf.dev_name = "i2c1"; 		/* i2c bus */
    cfg.intf.user_data = (void *)0x29;	/* i2c slave addr */
    rt_hw_vl53l0x_init("vl53l0x", &cfg, 57);/* xshutdown ctrl pin */

    return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_vl53l0x_port);

4.4 读取数据

  vl53l0x软件包基于sensor框架,sensor框架继承于RT-Thread标准设备框架,可以使用RT-Thread标准设备接口"open/read"读取传感器数据。


参考伪代码:

temp_dev = rt_device_find("tof_vl53l0x");
rt_device_open(temp_dev, RT_DEVICE_FLAG_RDONLY);
rt_device_read(temp_dev, 0, &sensor_data, 1);

4.5 msh/finsh测试


查看设备注册

msh >list_device
device           type         ref count
-------- -------------------- ----------
tof_vl53 Sensor Device        0       
i2c1     I2C Bus              0       
pin      Miscellaneous Device 0             
uart2    Character Device     0       
uart1    Character Device     2       

注:

RT-Thread设备名称长度为8字节,超出该长度的后面会被截断;如注册“tof_vl53l0x”时,实际设备名称为“tof_vl53 ”。


运行测量线程

  | /
- RT -     Thread Operating System
 / |      4.0.1 build Dec 17 2020
 2006 - 2019 Copyright by rt-thread team
[I/sensor] rt_sensor init success
[I/vl53l0x] vl53l0x info:
      Name[VL53L0X ES1 or later]
      Type[VL53L0X]
      ProductId[VL53L0CBV0DH/1$1]

msh >distance[153mm],timestamp[87]
distance[161mm],timestamp[192]
distance[154mm],timestamp[297]
distance[152mm],timestamp[402]

使用RTT sensor测试命令

  • 探测设备
msh >sensor probe tof_vl53l0x
[I/sensor.cmd] device id: 0xee!
  • 获取传感器信息
msh >sensor info             
vendor    :STMicroelectronics
model     :vl53l0x
unit      :mm
range_max :2000
range_min :0
period_min:100ms
fifo_max  :0

注:

sensor框架暂未提供tof传感器相关描述信息,已在RT-Thread源码上PR。

  • 读取测距数据
msh >sensor read 3
[I/sensor.cmd] num:  0, distance:  212, timestamp:131863
[I/sensor.cmd] num:  1, distance:  213, timestamp:131878
[I/sensor.cmd] num:  2, distance:  213, timestamp:131893

5 代码仓库

【1】https://github.com/Prry/rtt-vl53l0x


6 相关文章

【1】【RT-Thread】基于RT-Thread sensor框架的BMP180气压传感器应用
【2】【RT-Thread】基于Sensor框架TMP1075温度传感器驱动软件包

最后

以上就是粗心诺言为你收集整理的【12月】RT-Thread VL53L0X TOF传感器驱动实现前言1 简介2 传感器介绍3 软件实现4 使用说明5 代码仓库6 相关文章的全部内容,希望文章能够帮你解决【12月】RT-Thread VL53L0X TOF传感器驱动实现前言1 简介2 传感器介绍3 软件实现4 使用说明5 代码仓库6 相关文章所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部