• VL53L5CX驱动开发(3)----检测阈值


    概述

    本章展示如何使用VL53L5CX近接传感器的"检测阈值"功能。这个功能允许用户为传感器设置预定义的条件,当这些条件满足时,传感器可以触发一个中断。

    最近在弄ST的课程,需要样片的可以加群申请:615061293 。

    在这里插入图片描述
    VL53L5CX传感器允许用户更灵活地定义响应行为,特别是当检测到特定的测量结果时。例如,可以设置当对象的距离低于或高于特定值时,触发中断。这种功能在各种实际应用中,如智能开关、安全系统或机器人导航中,都非常有用。

    实现demo

    主要展示了如何使用VL53L5CX传感器来设置和使用检测阈值。
    实现为每个区域(在4x4分辨率中有16个区域)设定了两个阈值:一个基于信号强度,另一个基于物体的测量距离。

    视频教学

    https://www.bilibili.com/video/BV1WC4y1G79n/

    VL53L5CX驱动开发(3)----检测阈值

    样品申请

    https://www.wjx.top/vm/OhcKxJk.aspx#

    在这里插入图片描述

    源码下载

    https://download.csdn.net/download/qq_24312945/88426870

    生成STM32CUBEMX

    选择MCU

    测试版所用的MCU为STM32G431CB。
    在这里插入图片描述

    串口配置

    查看原理图,PA9和PA10设置为开发板的串口。
    在这里插入图片描述

    配置串口。
    在这里插入图片描述

    IIC配置

    在这个应用中,VL53L5CX模块通过I2C(IIC)接口与主控器通信。具体来说,VL53L5CX模块的I2C引脚连接到主控器的PA8和PB5两个IO口。
    在这里插入图片描述

    配置IIC为快速模式,速度为400k。
    在这里插入图片描述

    INT设置

    自主模式可以通过获取INT管脚进行判断数据是否准备好。
    在这里插入图片描述

    配置PB4为输入模式。
    在这里插入图片描述

    配置使能与复位

    驱动中有对模块进行复位的操作。
    在这里插入图片描述

    配置PB15和PB3为输出管脚。
    在这里插入图片描述

    X-CUBE-TOF1

    本节介绍在不需要使用样例应用时如何使用STM32CubeMX将X-CUBE-TOF1软件包添加到项目中。有了这样的设置,就只配置了驱动层。
    在这里插入图片描述

    由于需要自主模式,所以可以不开启主程序TOF执行代码。
    在这里插入图片描述

    串口重定向

    打开魔术棒,勾选MicroLIB
    在这里插入图片描述

    在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。

    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    /* USER CODE END Includes */
    
    • 1
    • 2
    • 3

    函数声明和串口重定向:

    /* 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 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    代码配置

    在custom_ranging_sensor.c代码中,有IO口驱动VL53L5CX进行复位的代码,由于没有配置对应的IO,所以需要注释掉。
    在这里插入图片描述

    由于没加载串口定义,所以注释掉#include “custom.h”
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    TOF代码配置

    在main.c中添加对应头文件。

    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    #include "vl53l5cx.h"
    #include "custom_ranging_sensor.h"
    
    /* USER CODE END Includes */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    函数与变量定义:

    /* 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 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    添加TOF初始化。
    主要为设置检测阈值。

      /* USER CODE BEGIN 2 */
    
    
    	/*********************************/
    	/*  程序检测阈值 */
    	/*********************************/
    
        /* 在此示例中,我们希望每个区域有2个阈值,分辨率为4x4 */
        /* 创建阈值数组(大小不能更改) */
    	VL53L5CX_DetectionThresholds thresholds[VL53L5CX_NB_THRESHOLDS];	
    	
      /* Set all values to 0 */
      memset(&thresholds, 0, sizeof(thresholds));
    
    	
      VL53L5CX_Object_t *pL5obj = CUSTOM_RANGING_CompObj[CUSTOM_VL53L5CX];
    
        /* 为所有区域添加阈值(在4x4的分辨率中有16个区域,或在8x8中有64个) */
      for (int i = 0; i < 16; i++) {
    		/* 第一个所需的阈值是GREATER_THAN模式。请注意,第一个必须始终使用数学操作VL53L5CX_OPERATION_NONE设置。
    		 * 在此示例中,信号阈值设置为150 kcps/spads(格式会在驱动程序内自动更新)
    		 */
        thresholds[2 * i].zone_num = i;
        thresholds[2 * i].measurement = VL53L5CX_SIGNAL_PER_SPAD_KCPS;
        thresholds[2 * i].type = VL53L5CX_GREATER_THAN_MAX_CHECKER;
        thresholds[2 * i].mathematic_operation = VL53L5CX_OPERATION_NONE;
        thresholds[2 * i].param_low_thresh = 150;
        thresholds[2 * i].param_high_thresh = 150;
    
    		/* 第二个所需的检查器是IN_WINDOW模式。我们将设置一个数学阈值VL53L5CX_OPERATION_OR,以将前一个检查器添加到此检查器。
    		 * 在此示例中,距离阈值设置在200mm和400mm之间(格式会在驱动程序内自动更新)。
    		 */
        thresholds[2 * i + 1].zone_num = i;
        thresholds[2 * i + 1].measurement = VL53L5CX_DISTANCE_MM;
        thresholds[2 * i + 1].type = VL53L5CX_IN_WINDOW;
        thresholds[2 * i + 1].mathematic_operation = VL53L5CX_OPERATION_OR;
        thresholds[2 * i + 1].param_low_thresh = 200;
        thresholds[2 * i + 1].param_high_thresh = 400;
      }
    
    	/* 必须明确指出最后的阈值。因为我们有32个检查器(16个区域x 2),所以最后一个是第31个 */
      thresholds[31].zone_num = VL53L5CX_LAST_THRESHOLD | thresholds[31].zone_num;
    
    	/* 向传感器发送阈值数组 */
    	status |= vl53l5cx_set_detection_thresholds(&pL5obj->Dev, thresholds);
    
    	/* 启用阈值检测 */
    	status |= vl53l5cx_set_detection_thresholds_enable(&pL5obj->Dev, 1U);
    
    	/* 设置传感器的测量频率,这决定了传感器执行测量的速度 */
    	status |= vl53l5cx_set_ranging_frequency_hz(&(pL5obj->Dev), 10);
    	
    	
      if (status != VL53L5CX_STATUS_OK)
      {
        printf("ERROR : Configuration programming error!\n\n");
        while (1);
      }
    
      status = vl53l5cx_start_ranging(&(pL5obj->Dev));
      if (status != VL53L5CX_STATUS_OK)
      {
        printf("vl53l5cx_start_ranging failed\n");
        while (1);
      }
    
    
    
      static VL53L5CX_ResultsData data;
    
      /* USER CODE END 2 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    主程序
    主程序来获取对应的INT位状态来判定数据是否准备好。

     /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    	
    	if(HAL_GPIO_ReadPin  ( GPIOB, GPIO_PIN_4) ==0)		
    	{
    		// 获取传感器的测距数据
    		status = vl53l5cx_get_ranging_data(&(pL5obj->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[VL53L5CX_NB_TARGET_PER_ZONE * i],
    							 data.distance_mm[VL53L5CX_NB_TARGET_PER_ZONE * i],
    							 data.signal_per_spad[VL53L5CX_NB_TARGET_PER_ZONE * i]);
    		}
    	}
    	
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Kcps/SPAD定义

    Kcps/SPAD 是一个测量单位,其中 “Kcps” 代表千计数每秒(Kilo Counts Per Second),而 “SPAD” 代表单光子雪崩二极管(Single Photon Avalanche Diode)。
    SPAD是一种高度敏感的光电二极管,当它接收到单个光子时就能产生雪崩击穿,从而输出较大的电流。由于其极高的灵敏度,它经常用于低光强度的测量中,如激光时间飞行距离测量(ToF)中。
    在这里插入图片描述

    状态说明

    正常的数据返回状态为5,为了保持数据一致,用户需要过滤无效的目标器状态。为了给出信心评级,状态为5的目标被认为是100%有效的。6或9的状态可以用50%的置信度来考虑。所有其他状态都低于50%置信度。
    在这里插入图片描述

    演示结果

    当测量距离为200mm-400mm时,会触发中断,进行数据打印。

    在这里插入图片描述

  • 相关阅读:
    ORM基本操作
    【JAVAEE框架】Spring 项目构建流程
    《舌尖上的中国》经典语录
    Android Navigation 过渡动画
    kubernetes的网络代理模式
    贪心算法题
    RabbitMQ之可靠性分析
    RoadBEV:鸟瞰图中的道路表面重建
    kafka rebalance你真的了解吗
    嵌入式开发没有激情了,正常吗?
  • 原文地址:https://blog.csdn.net/qq_24312945/article/details/133828169