概述
文章目录
- 前言
- 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的基本原理是通过灯光发射器发射光脉冲,遇到障碍物后反射;接收器接收反射回来的光脉冲,并根据光脉冲的往返时间计算与物体之间的距离。
1 简介
vl53l0x软件包是基于RT-Thread sensor框架实现的一个驱动包。基于该软件包,RT-Thread应用程序可以使用标准的sensor接口访问vl53l0x,获取传感器数据。源码地址,点击下载。
1.1 目录结构
名称 | 说明 |
---|---|
docs | 文档目录 |
vl53l0x | 官方库函数以及i2c platform对接 |
examples | 例子目录 |
inc | 头文件目录 |
src | 源代码目录 |
LICENSE | 许可证文件 |
SConscript | RT-Thread默认构建脚本 |
1.2 许可证
vl53l0x软件包遵循 Apache license v2.0 许可,详见 LICENSE
文件。
2 传感器介绍
vl53l0x是 STMicroelectronics(意法半导体)公司推出的新一代单点TOF(Time of Flight)传感器,具备体积小、测量精度高、测量距离远、无需增加外部光学器件、使用简单等优点;此外,vl53l0x采用940nm肉眼不可见光源,集成物理红外过滤器,提高对环境光的抗干扰特性,具备良好的鲁棒性和防光学串扰特性。
测量参数:
功能 | 量程 | 分辨率 | 精度 |
---|---|---|---|
距离 | 0—2000mm | 1mm | — |
2.1 应用场合
vl53l0x 是一个单分辨率的TOF传感器,适用于一些功能比较单一的场合。
- 相机对焦
- 1D手势识别
- 白色家电检测(额温枪、水龙头、皂液分配器)
- 数码电子(笔记本、平板、手机)用户检测
- 机器人避障
2.2 电路原理图
vl53l0x 硬件原理图比较简单,只需单电源供电,与CPU通过i2c总线进行交互数据;XSHUT控制芯片睡眠/正常工作;GPIO1为芯片中断信号输出,开漏状态,可产生一个中断信号通知CPU读取数据。
3 软件实现
3.1 支持情况
包含设备 | TOF |
---|---|
通信接口 | |
IIC | √ |
SPI | |
工作模式 | |
轮询 | √ |
中断 | |
FIFO | |
电源模式 | |
掉电 | √ |
低功耗 | |
普通 | √ |
注:
目前暂时只支持单次测量模式;后续增加:
- 连续测量模式
- 定时测量模式
- 测距校准功能
3.2 vl53l0x 软件库
ST并未给出vl53l0x 的详细寄存器描述手册,而是以开源库的方式提供给用户使用,即是vl53l0x 软件库。vl53l0x 软件库将芯片的功能封装成一个API接口,我们使用时无需关心其内部原理、实现及寄存器访问过程,直接调用其相关API即可实现具体功能。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,
RegRead
、
RegWrite
是新增的寄存器访问函数指针,最终会调用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.c
,vl53l0x_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 = ®
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 = ®
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) | 典型应用场景 |
---|---|---|---|
默认 | 30 | 1.2 | 通用 |
高速 | 20 | 1.2±5% | 速度优先 |
高精度 | 200 | 1.2±3% | 精确测量 |
长距离 | 33 | 2 | 黑暗条件(无红外线) |
3.4.3 测量方式
- 轮询,测距线程周期调用API测距,获取距离;该方式消耗一定CPU资源。
- 中断,VL53L0X测量完毕通过GPIO1发送中断信号,通知测距线程读取数据;该方式效率比较高,消耗CPU资源少。
3.4.4 测量流程
vl53l0x用户手册提供了一个轮询方式的测距流程图,根据该流程图调用相应的库函数API即可完成一个测量过程。
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 | 传感器名称 |
cfg | sensor配置信息 |
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 相关文章所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复