概述
最近在弄ST的课程,需要样片的可以加群申请:615061293 。
本章目的是展示如何充分利用VL53L8CX传感器的高级特性,通过结合运动指示器和阈值检测功能,实现对特定场景的精确监控。首先,程序通过特定的配置,确保了传感器能够在特定的分辨率下工作,同时还可调整用于检测运动的最小和最大距离。其次,一旦在传感器的视野中检测到运动,并且该运动的强度超出了预先设置的阈值,那么这种情况将被认为是一个有效的运动事件。最后,该程序不仅会捕获这些事件,还会详细地显示相关的数据,如运动发生在哪个区域,以及运动的强度如何。这种结合使用多种功能的方法,使得VL53L8CX传感器在各种应用场景中都能提供高效、准确的运动检测结果。
视频教学
https://www.bilibili.com/video/BV11w4m1D7sc/
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
源码下载
硬件准备
首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。
主控为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,所以需要注释掉。
检测流程
初始化变量:
○ 创建相关变量,如状态(status)、运动配置(motion_config)、设备对象(pL5obj)和结果数据(Results)。
配置运动指示器:
○ 使用8x8的分辨率初始化运动指示器。
○ 设置用于检测运动的最小和最大距离(在这里,是设置为1000mm到2000mm)。
○ 如果用户需要改变分辨率,他也需要更新运动指示器的分辨率(代码中此部分被注释掉了)。
设备配置:
○ 设置设备的分辨率为8x8。
○ 将设备设置为自主测距模式。
○ 设置测距频率为2Hz。
○ 设置集成时间为10ms以降低功耗。
配置检测阈值:
○ 对于8x8的分辨率,我们希望每个区域有一个阈值。
○ 初始化阈值数组。
○ 为所有64个区域设置阈值,当运动指示器的值超过44时,将其视为运动。
○ 将阈值数组发送到传感器。
○ 启用检测阈值。
开始测距:
○ 启动传感器的测距功能。
○ 输出消息,等待在1m到2m之间的视野中有运动发生。
无限循环监测:
○ 不断检查数据是否准备好。
○ 如果数据准备好或者某个特定的GPIO引脚被按下,获取测距数据。
○ 因为传感器默认设置为8x8模式,所以有64个区域要打印。但这个例子中,只打印首个区域的数据。
○ 如果某个区域的运动指示器的值大于或等于44,打印该区域有运动发生的消息。
通过上述流程,该程序能够检测并显示在预定距离范围内、运动强度超过预定阈值的运动情况。
TOF代码配置
在main.c中添加对应头文件。
/* USER CODE BEGIN Includes */ #include "stdio.h" #include "custom_ranging_sensor.h" #include "vl53l8cx_plugin_motion_indicator.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 */
添加TOF初始化。
主要为配置运动指示器。
/* USER CODE BEGIN 2 */ uint8_t status, isReady, i; VL53L8CX_Motion_Configuration motion_config; /* 运动配置 */ VL53L8CX_Object_t *pL8obj = CUSTOM_RANGING_CompObj[CUSTOM_VL53L8CX]; VL53L8CX_ResultsData Results; /* 来自VL53L8CX的结果数据 */ /*********************************/ /* 配置运动指示器 */ /*********************************/ /* 使用4x4分辨率初始化运动指示器 */ status = vl53l8cx_motion_indicator_init(&pL8obj- >Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); if(status) { printf("运动指示器初始化失败,状态码 : %un", status); return status; } /* (可选) 设置用于检测运动的最小和最大距离。注意距离的限制 */ status = vl53l8cx_motion_indicator_set_distance_motion(&pL8obj- >Dev, &motion_config, 1000, 2000); if(status) { printf("设置运动检测距离失败,状态码 : %un", status); return status; } /* 如果用户需要更改分辨率,则也需要更新运动指示器的分辨率(此部分已注释) */ //status = vl53l5cx_set_resolution(&Dev, VL53L5CX_RESOLUTION_4X4); //status = vl53l5cx_motion_indicator_set_resolution(&Dev, &motion_config, VL53L5CX_RESOLUTION_4X4); /* 将设备设置为自主模式,并设置较小的集成时间以降低功耗 */ status = vl53l8cx_set_resolution(&pL8obj- >Dev, VL53L8CX_RESOLUTION_8X8); status = vl53l8cx_set_ranging_mode(&pL8obj- >Dev, VL53L8CX_RANGING_MODE_AUTONOMOUS); status = vl53l8cx_set_ranging_frequency_hz(&pL8obj- >Dev, 2); status = vl53l8cx_set_integration_time_ms(&pL8obj- >Dev, 10); /*********************************/ /* 配置检测阈值 */ /*********************************/ /* 对于8x8的分辨率,我们希望为每个区域设置一个阈值 */ VL53L8CX_DetectionThresholds thresholds[VL53L8CX_NB_THRESHOLDS]; /* 将所有阈值设置为0 */ memset(&thresholds, 0, sizeof(thresholds)); /* 为所有64个区域设置阈值 */ for(i = 0; i < 64; i++){ thresholds[i].zone_num = i; thresholds[i].measurement = VL53L8CX_MOTION_INDICATOR; thresholds[i].type = VL53L8CX_GREATER_THAN_MAX_CHECKER; thresholds[i].mathematic_operation = VL53L8CX_OPERATION_NONE; /* 示例值44,超过此值的运动将被认为是移动 */ thresholds[i].param_low_thresh = 44; thresholds[i].param_high_thresh = 44; } /* 明确标记最后一个阈值。因为我们有64个检查器,所以最后一个是第63个 */ thresholds[63].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[63].zone_num; /* 将阈值数组发送到传感器 */ vl53l8cx_set_detection_thresholds(&pL8obj- >Dev, thresholds); /* 启用检测阈值 */ vl53l8cx_set_detection_thresholds_enable(&pL8obj- >Dev, 1); /* 开始测距 */ status = vl53l8cx_start_ranging(&pL8obj- >Dev); printf("等待在1m和2m之间的视场中发生的运动...n"); /* USER CODE END 2 */
主程序
主程序来获取对应的isReady位状态来判定数据是否准备好或者判断INT的IO状态也可。
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_11) ==0) { status = vl53l8cx_check_data_ready(&pL8obj- >Dev, &isReady); if(isReady) { /* 获取测距数据 */ vl53l8cx_get_ranging_data(&pL8obj- >Dev, &Results); /* 默认情况下,传感器设置为8x8模式,因此我们有64个区域的数据。 但在此示例中,只打印了第一个区域的数据 */ for(i = 0; i < 64; i++) { if(Results.motion_indicator.motion[motion_config.map_id[i]] >= 44) { printf(" 在这个区域检测到运动 : %3d !n", i); } } printf("n"); } } /* USER CODE END WHILE */ // MX_TOF_Process(); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
演示结果
检测运动情况下运动强度如下所示。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !