VL53L8CX TOF开发----3.检测阈值
概述
最近在弄ST的课程,需要样片的可以加群申请:615061293 。
本章展示如何使用VL53L8CX近接传感器的"检测阈值"功能。这个功能允许用户为传感器设置预定义的条件,当这些条件满足时,传感器可以触发一个中断。
VL53L8CX传感器允许用户更灵活地定义响应行为,特别是当检测到特定的测量结果时。例如,可以设置当对象的距离低于或高于特定值时,触发中断。这种功能在各种实际应用中,如智能开关、安全系统或机器人导航中,都非常有用。
视频教学
https://www.bilibili.com/video/BV1Qf421R71U/
VL53L8CX TOF开发(3)----检测阈值
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
源码下载
https://download.csdn.net/download/qq_24312945/89328194
实现demo
配置VL53L8CX传感器以实现特定条件下的目标检测和距离测量。通过设置信号强度和距离阈值,可以根据具体应用需求定制传感器的检测行为,使其在各种场景中发挥作用。
实现为每个区域(在4x4分辨率中有16个区域)设定了两个阈值:一个基于信号强度,另一个基于物体的测量距离。
硬件准备
首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。
主控为STM32G431CB,TOF为VL53L8CX
生成STM32CUBEMX
选择MCU
测试版所用的MCU为STM32G431CB。
串口配置
查看原理图,PA9和PA10设置为开发板的串口。
配置串口。
IIC配置
在这个应用中,VL53L8CX模块通过I2C(IIC)接口与主控器通信。具体来说,VL53L8CX模块的I2C引脚连接到主控器的PA8和PB5两个IO口。
配置IIC为快速模式,速度为400k。
LPn 设置
若进行IIC通讯,LPn设置为高电平状态。
这里对应管脚为PA12。
配置为PA12。
INT设置
自主模式可以通过获取INT管脚进行判断数据是否准备好。
配置PA11为输入模式。
X-CUBE-TOF1
本节介绍在不需要使用样例应用时如何使用STM32CubeMX将X-CUBE-TOF1软件包添加到项目中。有了这样的设置,就只配置了驱动层。
串口重定向
打开魔术棒,勾选MicroLIB
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
函数声明和串口重定向:
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END PFP */
代码配置
在custom_ranging_sensor.c代码中,有IO口驱动VL53L8CX进行复位的代码,由于没有配置对应的IO,所以需要注释掉。
TOF代码配置
在main.c中添加对应头文件。
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "vl53l8cx.h"
#include "custom_ranging_sensor.h"
/* USER CODE END Includes */
函数与变量定义:
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
static int32_t status = 0;
static RANGING_SENSOR_Result_t Result;
/* USER CODE END PFP */
kcps阈值检测
在激光雷达和飞行时间(ToF)传感器的测量中,kcps 代表 每秒千计数(kilo counts per second)。这是一个用于表示传感器每秒钟探测到的光子返回计数的单位。具体来说,它反映了每秒钟每个感光单元(SPAD)检测到的光子数量。
较高的kcps值通常表示反射率较高的目标或较近的目标,而较低的kcps值则表示反射率较低的目标或较远的目标。
/*********************************/
/* 程序检测阈值 */
/*********************************/
/* 在此示例中,我们希望每个区域有2个阈值,分辨率为4x4 */
/* 创建阈值数组(大小不能更改) */
VL53L8CX_DetectionThresholds thresholds[VL53L8CX_NB_THRESHOLDS];
/* Set all values to 0 */
memset(&thresholds, 0, sizeof(thresholds));
VL53L8CX_Object_t *pL8obj = CUSTOM_RANGING_CompObj[CUSTOM_VL53L8CX];
/* 为所有区域添加阈值(在4x4的分辨率中有16个区域,或在8x8中有64个) */
for (int i = 0; i < 16; i++) {
/* 第一个所需的阈值是GREATER_THAN模式。请注意,第一个必须始终使用数学操作VL53L8CX_OPERATION_NONE设置。
* 在此示例中,信号阈值设置为150 kcps/spads(格式会在驱动程序内自动更新)
*/
thresholds[i].zone_num = i;
thresholds[i].measurement = VL53L8CX_SIGNAL_PER_SPAD_KCPS;
thresholds[i].type = VL53L8CX_IN_WINDOW;
thresholds[i].mathematic_operation = VL53L8CX_OPERATION_NONE;
thresholds[i].param_low_thresh = 1500;
thresholds[i].param_high_thresh = 1700;
}
/* 必须明确指出最后的阈值。因为我们有16个检查器(16个区域x 1),所以最后一个是第15个 */
thresholds[15].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[15].zone_num;
/* 向传感器发送阈值数组 */
status |= vl53l8cx_set_detection_thresholds(&pL8obj->Dev, thresholds);
/* 启用阈值检测 */
status |= vl53l8cx_set_detection_thresholds_enable(&pL8obj->Dev, 1U);
/* 设置传感器的测量频率,这决定了传感器执行测量的速度 */
status |= vl53l8cx_set_ranging_frequency_hz(&(pL8obj->Dev), 10);
if (status != VL53L8CX_STATUS_OK)
{
printf("ERROR : Configuration programming error!\n\n");
while (1);
}
status = vl53l8cx_start_ranging(&(pL8obj->Dev));
if (status != VL53L8CX_STATUS_OK)
{
printf("vl53l5cx_start_ranging failed\n");
while (1);
}
static VL53L8CX_ResultsData data;
检测类型
这些宏定义用于在配置VL53L8CX传感器时指定“检测器”的类型,它们表示测量值的窗口或范围,由低阈值和高阈值定义。每个宏定义代表不同的检测条件类型。
/**
* @brief The following macro are used to define the 'type' of a checker.
* They indicate the window of measurements, defined by low and a high
* thresholds.
*/
#define VL53L8CX_IN_WINDOW ((uint8_t)0U)
#define VL53L8CX_OUT_OF_WINDOW ((uint8_t)1U)
#define VL53L8CX_LESS_THAN_EQUAL_MIN_CHECKER ((uint8_t)2U)
#define VL53L8CX_GREATER_THAN_MAX_CHECKER ((uint8_t)3U)
#define VL53L8CX_EQUAL_MIN_CHECKER ((uint8_t)4U)
#define VL53L8CX_NOT_EQUAL_MIN_CHECKER ((uint8_t)5U)
VL53L8CX_IN_WINDOW:如果测量值在指定的低阈值和高阈值之间,则检测为真。
VL53L8CX_OUT_OF_WINDOW:如果测量值在指定的低阈值和高阈值之外,则检测为真。
VL53L8CX_LESS_THAN_EQUAL_MIN_CHECKER: 如果测量值小于或等于指定的低阈值,则检测为真。
VL53L8CX_GREATER_THAN_MAX_CHECKER:如果测量值大于指定的高阈值,则检测为真。
VL53L8CX_EQUAL_MIN_CHECKER:如果测量值等于指定的低阈值,则检测为真。
VL53L8CX_NOT_EQUAL_MIN_CHECKER:如果测量值不等于指定的低阈值,则检测为真。
距离阈值检测
配置VL53L8CX传感器进行距离测量,并设置每个区域的检测阈值,使传感器能够检测特定距离范围内的目标。通过设置测量频率和启动测量,传感器将开始定期进行测距,并根据配置的阈值进行检测。这些步骤确保传感器按预期工作,并在指定条件下触发相应的检测结果。
/*********************************/
/* 程序检测阈值 */
/*********************************/
/* 在此示例中,我们希望每个区域有2个阈值,分辨率为4x4 */
/* 创建阈值数组(大小不能更改) */
VL53L8CX_DetectionThresholds thresholds[VL53L8CX_NB_THRESHOLDS];
/* Set all values to 0 */
memset(&thresholds, 0, sizeof(thresholds));
VL53L8CX_Object_t *pL8obj = CUSTOM_RANGING_CompObj[CUSTOM_VL53L8CX];
/* 为所有区域添加阈值(在4x4的分辨率中有16个区域,或在8x8中有64个) */
for (int i = 0; i < 16; i++) {
/* 第二个所需的检查器是IN_WINDOW模式。我们将设置一个数学阈值VL53L5CX_OPERATION_OR,以将前一个检查器添加到此检查器。
* 在此示例中,距离阈值设置在200mm和400mm之间(格式会在驱动程序内自动更新)。
*/
thresholds[i].zone_num = i;
thresholds[i].measurement = VL53L8CX_DISTANCE_MM;
thresholds[i].type = VL53L8CX_IN_WINDOW;
thresholds[i].mathematic_operation = VL53L8CX_OPERATION_OR;
thresholds[i].param_low_thresh = 200;
thresholds[i].param_high_thresh = 400;
}
/* 必须明确指出最后的阈值。因为我们有16个检查器(16个区域x 1),所以最后一个是第15个 */
thresholds[15].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[15].zone_num;
/* 向传感器发送阈值数组 */
status |= vl53l8cx_set_detection_thresholds(&pL8obj->Dev, thresholds);
/* 启用阈值检测 */
status |= vl53l8cx_set_detection_thresholds_enable(&pL8obj->Dev, 1U);
/* 设置传感器的测量频率,这决定了传感器执行测量的速度 */
status |= vl53l8cx_set_ranging_frequency_hz(&(pL8obj->Dev), 10);
if (status != VL53L8CX_STATUS_OK)
{
printf("ERROR : Configuration programming error!\n\n");
while (1);
}
status = vl53l8cx_start_ranging(&(pL8obj->Dev));
if (status != VL53L8CX_STATUS_OK)
{
printf("vl53l5cx_start_ranging failed\n");
while (1);
}
static VL53L8CX_ResultsData data;
主程序
主程序来获取对应的INT位状态来判定数据是否准备好。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_11) ==0)
{
// 获取传感器的测距数据
status = vl53l8cx_get_ranging_data(&(pL8obj->Dev), &data);
printf("\n");
// 循环打印所有16个区域的数据
for (int i = 0; i < 16; i++) {
printf("Zone : %3d, Status : %3u, Distance : %4d mm, Signal : %5lu kcps/SPADs\r\n",
i,
data.target_status[VL53L8CX_NB_TARGET_PER_ZONE * i],
data.distance_mm[VL53L8CX_NB_TARGET_PER_ZONE * i],
data.signal_per_spad[VL53L8CX_NB_TARGET_PER_ZONE * i]);
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
演示结果
1500-1700kcps/SPADs检测。
200-400mm距离检测。