概述
最近在弄ST的課程,需要樣片的可以加群申請(qǐng):615061293 。
本章展示如何使用VL53L8CX近接傳感器的"檢測(cè)閾值"功能。這個(gè)功能允許用戶為傳感器設(shè)置預(yù)定義的條件,當(dāng)這些條件滿足時(shí),傳感器可以觸發(fā)一個(gè)中斷。
VL53L8CX傳感器允許用戶更靈活地定義響應(yīng)行為,特別是當(dāng)檢測(cè)到特定的測(cè)量結(jié)果時(shí)。例如,可以設(shè)置當(dāng)對(duì)象的距離低于或高于特定值時(shí),觸發(fā)中斷。這種功能在各種實(shí)際應(yīng)用中,如智能開(kāi)關(guān)、安全系統(tǒng)或機(jī)器人導(dǎo)航中,都非常有用。
視頻教學(xué)
https://www.bilibili.com/video/BV1Qf421R71U/
樣品申請(qǐng)
https://www.wjx.top/vm/OhcKxJk.aspx#
源碼下載
https://download.csdn.net/download/qq_24312945/89328194
實(shí)現(xiàn)demo
配置VL53L8CX傳感器以實(shí)現(xiàn)特定條件下的目標(biāo)檢測(cè)和距離測(cè)量。通過(guò)設(shè)置信號(hào)強(qiáng)度和距離閾值,可以根據(jù)具體應(yīng)用需求定制傳感器的檢測(cè)行為,使其在各種場(chǎng)景中發(fā)揮作用。
實(shí)現(xiàn)為每個(gè)區(qū)域(在4x4分辨率中有16個(gè)區(qū)域)設(shè)定了兩個(gè)閾值:一個(gè)基于信號(hào)強(qiáng)度,另一個(gè)基于物體的測(cè)量距離。
硬件準(zhǔn)備
首先需要準(zhǔn)備一個(gè)開(kāi)發(fā)板,這里我準(zhǔn)備的是自己繪制的開(kāi)發(fā)板,需要的可以進(jìn)行申請(qǐng)。
主控為STM32G431CB,TOF為VL53L8CX
生成STM32CUBEMX
選擇MCU
測(cè)試版所用的MCU為STM32G431CB。
串口配置
查看原理圖,PA9和PA10設(shè)置為開(kāi)發(fā)板的串口。
配置串口。
IIC配置
在這個(gè)應(yīng)用中,VL53L8CX模塊通過(guò)I2C(IIC)接口與主控器通信。具體來(lái)說(shuō),VL53L8CX模塊的I2C引腳連接到主控器的PA8和PB5兩個(gè)IO口。
配置IIC為快速模式,速度為400k。
LPn 設(shè)置
若進(jìn)行IIC通訊,LPn設(shè)置為高電平狀態(tài)。
這里對(duì)應(yīng)管腳為PA12。
配置為PA12。
INT設(shè)置
自主模式可以通過(guò)獲取INT管腳進(jìn)行判斷數(shù)據(jù)是否準(zhǔn)備好。
配置PA11為輸入模式。
X-CUBE-TOF1
本節(jié)介紹在不需要使用樣例應(yīng)用時(shí)如何使用STM32CubeMX將X-CUBE-TOF1軟件包添加到項(xiàng)目中。有了這樣的設(shè)置,就只配置了驅(qū)動(dòng)層。
串口重定向
打開(kāi)魔術(shù)棒,勾選MicroLIB
在main.c中,添加頭文件,若不添加會(huì)出現(xiàn) identifier “FILE” is undefined報(bào)錯(cuò)。
/* USER CODE BEGIN Includes */ #include "stdio.h" /* USER CODE END Includes */
函數(shù)聲明和串口重定向:
/* 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口驅(qū)動(dòng)VL53L8CX進(jìn)行復(fù)位的代碼,由于沒(méi)有配置對(duì)應(yīng)的IO,所以需要注釋掉。
TOF代碼配置
在main.c中添加對(duì)應(yīng)頭文件。
/* USER CODE BEGIN Includes */ #include "stdio.h" #include "vl53l8cx.h" #include "custom_ranging_sensor.h" /* USER CODE END Includes */
函數(shù)與變量定義:
/* 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閾值檢測(cè)
在激光雷達(dá)和飛行時(shí)間(ToF)傳感器的測(cè)量中,kcps 代表 每秒千計(jì)數(shù)(kilo counts per second)。這是一個(gè)用于表示傳感器每秒鐘探測(cè)到的光子返回計(jì)數(shù)的單位。具體來(lái)說(shuō),它反映了每秒鐘每個(gè)感光單元(SPAD)檢測(cè)到的光子數(shù)量。
較高的kcps值通常表示反射率較高的目標(biāo)或較近的目標(biāo),而較低的kcps值則表示反射率較低的目標(biāo)或較遠(yuǎn)的目標(biāo)。
/*********************************/ /* 程序檢測(cè)閾值 */ /*********************************/ /* 在此示例中,我們希望每個(gè)區(qū)域有2個(gè)閾值,分辨率為4x4 */ /* 創(chuàng)建閾值數(shù)組(大小不能更改) */ 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]; /* 為所有區(qū)域添加閾值(在4x4的分辨率中有16個(gè)區(qū)域,或在8x8中有64個(gè)) */ for (int i = 0; i < 16; i++) { /* 第一個(gè)所需的閾值是GREATER_THAN模式。請(qǐng)注意,第一個(gè)必須始終使用數(shù)學(xué)操作VL53L8CX_OPERATION_NONE設(shè)置。 * 在此示例中,信號(hào)閾值設(shè)置為150 kcps/spads(格式會(huì)在驅(qū)動(dòng)程序內(nèi)自動(dòng)更新) */ 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; } /* 必須明確指出最后的閾值。因?yàn)槲覀冇?6個(gè)檢查器(16個(gè)區(qū)域x 1),所以最后一個(gè)是第15個(gè) */ thresholds[15].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[15].zone_num; /* 向傳感器發(fā)送閾值數(shù)組 */ status |= vl53l8cx_set_detection_thresholds(&pL8obj-?>Dev, thresholds); /* 啟用閾值檢測(cè) */ status |= vl53l8cx_set_detection_thresholds_enable(&pL8obj->Dev, 1U); /* 設(shè)置傳感器的測(cè)量頻率,這決定了傳感器執(zhí)行測(cè)量的速度 */ status |= vl53l8cx_set_ranging_frequency_hz(&(pL8obj->Dev), 10); if (status != VL53L8CX_STATUS_OK) { printf("ERROR : Configuration programming error!nn"); while (1); } status = vl53l8cx_start_ranging(&(pL8obj->Dev)); if (status != VL53L8CX_STATUS_OK) { printf("vl53l5cx_start_ranging failedn"); while (1); } static VL53L8CX_ResultsData data;
檢測(cè)類(lèi)型
這些宏定義用于在配置VL53L8CX傳感器時(shí)指定“檢測(cè)器”的類(lèi)型,它們表示測(cè)量值的窗口或范圍,由低閾值和高閾值定義。每個(gè)宏定義代表不同的檢測(cè)條件類(lèi)型。
/** * @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:如果測(cè)量值在指定的低閾值和高閾值之間,則檢測(cè)為真。
VL53L8CX_OUT_OF_WINDOW:如果測(cè)量值在指定的低閾值和高閾值之外,則檢測(cè)為真。
VL53L8CX_LESS_THAN_EQUAL_MIN_CHECKER: 如果測(cè)量值小于或等于指定的低閾值,則檢測(cè)為真。
VL53L8CX_GREATER_THAN_MAX_CHECKER:如果測(cè)量值大于指定的高閾值,則檢測(cè)為真。
VL53L8CX_EQUAL_MIN_CHECKER:如果測(cè)量值等于指定的低閾值,則檢測(cè)為真。
VL53L8CX_NOT_EQUAL_MIN_CHECKER:如果測(cè)量值不等于指定的低閾值,則檢測(cè)為真。
距離閾值檢測(cè)
配置VL53L8CX傳感器進(jìn)行距離測(cè)量,并設(shè)置每個(gè)區(qū)域的檢測(cè)閾值,使傳感器能夠檢測(cè)特定距離范圍內(nèi)的目標(biāo)。通過(guò)設(shè)置測(cè)量頻率和啟動(dòng)測(cè)量,傳感器將開(kāi)始定期進(jìn)行測(cè)距,并根據(jù)配置的閾值進(jìn)行檢測(cè)。這些步驟確保傳感器按預(yù)期工作,并在指定條件下觸發(fā)相應(yīng)的檢測(cè)結(jié)果。
/*********************************/ /* 程序檢測(cè)閾值 */ /*********************************/ /* 在此示例中,我們希望每個(gè)區(qū)域有2個(gè)閾值,分辨率為4x4 */ /* 創(chuàng)建閾值數(shù)組(大小不能更改) */ 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]; /* 為所有區(qū)域添加閾值(在4x4的分辨率中有16個(gè)區(qū)域,或在8x8中有64個(gè)) */ for (int i = 0; i < 16; i++) { /* 第二個(gè)所需的檢查器是IN_WINDOW模式。我們將設(shè)置一個(gè)數(shù)學(xué)閾值VL53L5CX_OPERATION_OR,以將前一個(gè)檢查器添加到此檢查器。 * 在此示例中,距離閾值設(shè)置在200mm和400mm之間(格式會(huì)在驅(qū)動(dòng)程序內(nèi)自動(dòng)更新)。 */ 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; } /* 必須明確指出最后的閾值。因?yàn)槲覀冇?6個(gè)檢查器(16個(gè)區(qū)域x 1),所以最后一個(gè)是第15個(gè) */ thresholds[15].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[15].zone_num; /* 向傳感器發(fā)送閾值數(shù)組 */ status |= vl53l8cx_set_detection_thresholds(&pL8obj-?>Dev, thresholds); /* 啟用閾值檢測(cè) */ status |= vl53l8cx_set_detection_thresholds_enable(&pL8obj->Dev, 1U); /* 設(shè)置傳感器的測(cè)量頻率,這決定了傳感器執(zhí)行測(cè)量的速度 */ status |= vl53l8cx_set_ranging_frequency_hz(&(pL8obj->Dev), 10); if (status != VL53L8CX_STATUS_OK) { printf("ERROR : Configuration programming error!nn"); while (1); } status = vl53l8cx_start_ranging(&(pL8obj->Dev)); if (status != VL53L8CX_STATUS_OK) { printf("vl53l5cx_start_ranging failedn"); while (1); } static VL53L8CX_ResultsData data;
主程序
主程序來(lái)獲取對(duì)應(yīng)的INT位狀態(tài)來(lái)判定數(shù)據(jù)是否準(zhǔn)備好。
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_11) ==0) { // 獲取傳感器的測(cè)距數(shù)據(jù) status = vl53l8cx_get_ranging_data(&(pL8obj->Dev), &data); printf("n"); // 循環(huán)打印所有16個(gè)區(qū)域的數(shù)據(jù) for (int i = 0; i < 16; i++) { printf("Zone : %3d, Status : %3u, Distance : %4d mm, Signal : %5lu kcps/SPADsrn", 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 */
演示結(jié)果
1500-1700kcps/SPADs檢測(cè)。
200-400mm距離檢測(cè)。
審核編輯 黃宇
-
TOF
+關(guān)注
關(guān)注
9文章
475瀏覽量
36224 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
280瀏覽量
14713
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論