文章目录
前言
本文介绍了在 ESP32 DEVKIT V1 开发板上开发 VL53L3CX 距离传感器的过程。
VL53L3CX 是意法半导体的最新飞行时间(ToF)产品,并嵌入了意法半导体的第三代 FlightSense 专利技术。它结合了高性能的接近和测距传感器,具有多目标距离测量和自动污点校正功能。微型可回流封装集成了单光子雪崩二极管(SPAD)阵列和物理红外滤光片,在各种环境照明条件下实现最佳测距性能,并配有各种盖片。
VL53L3CX 结合了高性能接近传感器的优点、出色的近距离线性度以及高达 3m 的测距能力。
凭借获得专利的算法和巧妙的模块构造,VL53L3CX 还能够通过深度检测视野(FoV)内的不同对象。意法半导体的直方图算法允许覆盖玻璃的串扰抗扰度超过 80cm,并具有动态污迹补偿功能。
- 完全集成的小型化模块
- 发射器:940nm 不可见激光(VCSEL)及其模拟驱动器;
- 运行进阶数字固件的低功耗微控制器;
- 尺寸:4.4 x 2.4 x 1 mm。
- 快速,精确测距
- 基于直方图技术;
- 完整视野(FoV)时,高达 300cm+ 的检测范围;
- 使用专利算法(直接 ToF)可以远距离覆盖玻璃串扰和指纹污迹;
- 动态指纹污迹补偿;
- 短距离,高精度线性;
- 多目标检测和距离测量。
- 典型全视野:25°
- 方便集成
- 可回流组件;
- 提供零件间或通用形状串扰校准;
- 单电源;
- 适用于多种类型的覆盖玻璃材料;
- I²C 接口(可达 1MHz);
- Xshutdown 复位并中断 GPIO 以优化测距操作;
- 包含 C 和 Linux 全套软件驱动程序。
1 产品概述
1.1 技术规格
1.2 系统框图
1.3 设备引脚分布
2 工作流程
2.1 系统功能描述
下图显示了系统级功能说明。客户主机应用程序使用应用编程接口 (API) 控制设备。API 的实现以驱动程序(裸 C 代码或 Linux 驱动程序)的形式交付给客户。
驱动程序与客户应用程序共享一套高级功能,可控制设备固件,如初始化、范围启动/停止、设置系统精度等。
用户的应用程序调用 API 中的函数,然后 API 通过 IIC 与 VL53L3CX 中的固件(Firmware)进行通信,固件再操作硬件。
2.2 状态机描述
下图显示了设备状态机。
上电以后,VL53L3CX 会进入 Hw Standby 状态,这是待机状态,功耗很低。然后拉高 XSHUT脚,让 VL53L3CX 进入 Initial Boot 状态,自动进入软件待机状态。主机初始化开始,准备校准。如果不需要待机状态,可以把 XSHUT 接到 AVDD 上。VL53L3CX 处于休眠状态是不能进行 IIC 通信的。
2.3 测距模式说明
VL53L3CX 的专用运行模式(称为 "预设")是 "测距模式"。在该模式下,软件驱动程序提供了统包功能,可在所有客户应用中快速、轻松地进行测距: 测距模式是获得 VL53L3CX 最佳功能的配置。
- 测距模式对 80cm 以外的盖板玻璃串扰和污点具有本机抗扰度。利用获得专利的算法(直接 ToF),可以进行时间滤波,将串扰信号与距离大于 80cm 的物体信号区分开来。现在,与市场上的其他传感器不同,在盖上玻璃的情况下,可以实现 300cm 的同类最佳测距性能,而且无需任何计算;
- 测距模式可同时检测 FoV 内的多个物体。软件驱动程序最多可同时输出四个范围,以显示物体的范围。详情请查阅最新的软件驱动程序手册 了解更多详情;
- 调用驱动函数后,默认以 30Hz 的频率执行测距操作(典型测距操作持续 33ms)。它包括内部内务管理、测距和后处理。
3 控制接口
本节介绍控制接口。I²C 接口使用两个信号:串行数据线 (SDA) 和串行时钟线 (SCL)。连接到总线上的每个设备都使用唯一的地址,存在简单的主/从关系。
SDA 和 SCL 线路均通过主机上的上拉电阻与正电源电压相连。当线路处于浮动状态,上拉电阻器将线路拉高时,线路处于高电平状态。当没有数据传输时,两条线路均为高电平。
时钟信号 (SCL) 由主设备生成。主设备启动数据传输。产品设备上的 I²C 总线最大速度为1Mbits/s,默认设备地址为 0x52。
信息以 8 位数据包(字节)的形式打包,后面总是跟着一个确认位,Ac 表示 VL53L3CX 确认,Am 表示主确认(主机总线主控)。内部数据通过在 SCL 上升沿采样 SDA 产生。外部数据必须在 SCL 的高电平期间保持稳定。但在 SCL 为高电平时,SDA 分别下降或上升时的启动 (S) 或停止 (P) 条件除外。
报文包含一系列字节,前面是启动条件,后面是停止或重复启动(另一个启动条件,但前面没有停止条件),然后是另一条报文。第一个字节包含设备地址(0x52),并指定数据方向。如果最低有效位为低位(即 0x52),则报文是主从写入。如果 LSB 被置位(即 0x53),则信息是主从读取。
3.1 设备地址
VL53L3CX 模块的 I²C 通讯地址是 0x52。
3.2 I²C写1个字节数据
与飞行时间传感器的所有串行接口通信必须以启动条件开始。VL53L3CX 模块通过将 SDA 线变为低电平来确认收到有效地址。读/写位(地址字节的 LSB)的状态将被存储,并可解释从 SDA 采样的下一个数据字节。在写入序列中,接收到的第二个字节提供一个 16 位索引,该索引指向一个内部 8 位寄存器。
从站接收到数据后,逐位写入串行/并行寄存器。从站接收到每个数据字节后,都会产生一个确认。然后,数据将被存储到由当前索引寻址的内部寄存器中。
在读取信息期间,当前索引所寻址寄存器的内容将在设备地址字节之后的字节中读出。该寄存器的内容被并行加载到串行/并行寄存器中,并通过 SCL 的下降沿从设备中时钟输出。
3.3 I²C读1个字节数据
在读取和写入信息序列中,每个字节结束时,接收设备都会发出确认(即 VL53L3CX 设备为写入,主机为读取)。
3.4 I²C写多个字节数据
总线主站只能通过发出停止条件或在读取操作过程中读取完整字节后发出负确认(即不将 SDA 线路拉低)来终止报文。接口还支持自动递增索引。因此,主站可以连续向从站发送数据字节,直到从站无法提供确认,或者主站通过停止条件终止写入通信。如果使用自动递增功能,主站就不必在发送数据字节时同时发送地址索引。
3.5 I²C读多个字节数据
3.6 I²C 接口 - 参考寄存器
下表所示寄存器可用于验证用户 I²C 接口。
4 代码说明
4.1 下载编译
1. 下载代码
git clone https://github.com/EmotionFly/ESP32_VL53L3CX.git
cd ESP32_VL53L3CX
2. 获取 esp-idf 库的环境
. $HOME/esp/esp-idf/export.sh
3. 编译—>下载—>监控
idf.py flash monitor
4.2 代码结构
1. 先确定测量数据是否已准备就绪。
VL53L1_GetMeasurementDataReady(&dev, &dataReady);
VL53L1_Error VL53L1_GetMeasurementDataReady(VL53L1_DEV Dev,
uint8_t *pMeasurementDataReady)
{
VL53L1_Error Status = VL53L1_ERROR_NONE;
LOG_FUNCTION_START("");
Status = VL53L1_is_new_data_ready(Dev, pMeasurementDataReady);
LOG_FUNCTION_END(Status);
return Status;
}
本质是访问 GPIO__TIO_HV_STATUS(0x0031) 寄存器的数据。
2. 获取测量数据。
VL53L1_GetRangingMeasurementData(&dev, &rangingData);
VL53L1_Error VL53L1_GetRangingMeasurementData(VL53L1_DEV Dev,
VL53L1_RangingMeasurementData_t *pRangingMeasurementData)
{
VL53L1_Error Status = VL53L1_ERROR_NONE;
VL53L1_range_results_t results;
VL53L1_range_results_t *presults = &results;
VL53L1_range_data_t *presults_data;
LOG_FUNCTION_START("");
/* Clear Ranging Data */
memset(pRangingMeasurementData, 0xFF,
sizeof(VL53L1_RangingMeasurementData_t));
/* Get Ranging Data */
Status = VL53L1_get_device_results(
Dev,
VL53L1_DEVICERESULTSLEVEL_FULL,
presults);
if (Status == VL53L1_ERROR_NONE) {
pRangingMeasurementData->StreamCount = presults->stream_count;
/* in case of lite ranging or autonomous the following function
* returns index = 0
*/
presults_data = &(presults->data[0]);
Status = SetSimpleData(Dev, 1,
presults->device_status,
presults_data,
pRangingMeasurementData);
}
LOG_FUNCTION_END(Status);
return Status;
}
本质是访问 RESULT__RANGE_STATUS(0x0089)和 RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0(0x0096)寄存器的数据。
3. 系统中断清零
本质是将 SYSTEM__INTERRUPT_CLEAR(0x0086) 寄存器置 1。
5 波形分析
1. GPIO__TIO_HV_STATUS(0x0031)
从 0x0031 寄存器读取数据,当返回值为 0x02 时,表示测量数据准备就绪。
2. RESULT__RANGE_STATUS(0x0089)和 RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0(0x0096)
从 0x0089 寄存器读取数据,返回值为 0x09。
从 0x0096 寄存器读取数据,返回值为 0x0069,为测量值。
3. SYSTEM__INTERRUPT_CLEAR(0x0086)
向 0x0086 寄存器写入 1。